aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt4
-rw-r--r--src/Makefile.am10
-rw-r--r--src/bindings/Makefile.am12
-rw-r--r--src/bindings/interface/Makefile.am4
-rw-r--r--src/bindings/interface/ScriptMgr.cpp4
-rw-r--r--src/bindings/interface/ScriptMgr.h4
-rw-r--r--src/bindings/interface/Scripts/sc_default.cpp4
-rw-r--r--src/bindings/interface/Scripts/sc_defines.cpp4
-rw-r--r--src/bindings/interface/Scripts/sc_defines.h4
-rw-r--r--src/bindings/interface/config.h4
-rw-r--r--src/bindings/interface/system.cpp4
-rw-r--r--src/bindings/scripts/CMakeLists.txt3
-rw-r--r--src/bindings/scripts/Makefile.am7
-rw-r--r--src/bindings/scripts/ScriptMgr.cpp24
-rw-r--r--src/bindings/scripts/ScriptMgr.h2
-rw-r--r--src/bindings/scripts/VC71/71ScriptDev2.vcproj105
-rw-r--r--src/bindings/scripts/VC80/80ScriptDev2.vcproj104
-rw-r--r--src/bindings/scripts/VC90/90ScriptDev2.vcproj132
-rw-r--r--src/bindings/scripts/include/sc_creature.cpp30
-rw-r--r--src/bindings/scripts/include/sc_creature.h2
-rw-r--r--src/bindings/scripts/include/sc_gossip.h2
-rw-r--r--src/bindings/scripts/scripts/npc/npcs_special.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/azuremyst_isle/azuremyst_isle.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp53
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/boss_shade_of_akama.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blades_edge_mountains/blades_edge_mountains.cpp59
-rw-r--r--src/bindings/scripts/scripts/zone/bloodmyst_isle/bloodmyst_isle.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/borean_tundra/borean_tundra.cpp105
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp20
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp16
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/boss_warlord_kalithresh.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/deadmines/deadmines.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/eastern_plaguelands/eastern_plaguelands.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/eversong_woods/eversong_woods.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/gruuls_lair/boss_high_king_maulgar.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/boss_nightbane.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp20
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/bosses_opera.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/nagrand/nagrand.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/netherstorm/netherstorm.cpp12
-rw-r--r--src/bindings/scripts/scripts/zone/scarlet_monastery/boss_headless_horseman.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/scarlet_monastery/instance_scarlet_monastery.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp29
-rw-r--r--src/bindings/scripts/scripts/zone/sunwell_plateau/boss_felmyst.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kalecgos.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp14
-rw-r--r--src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/terokkar_forest/terokkar_forest.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/tirisfal_glades/tirisfal_glades.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/uldaman/instance_uldaman.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/boss_keleseth.cpp223
-rw-r--r--src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/def_keep.h26
-rw-r--r--src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp231
-rw-r--r--src/bindings/scripts/scripts/zone/zulaman/boss_akilzon.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp3
-rw-r--r--src/bindings/scripts/scripts/zone/zulaman/boss_janalai.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/zulaman/boss_zuljin.cpp12
-rw-r--r--src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp12
-rw-r--r--src/bindings/scripts/system.cpp4
-rw-r--r--src/framework/Dynamic/FactoryHolder.h4
-rw-r--r--src/framework/Dynamic/ObjectRegistry.h4
-rw-r--r--src/framework/GameSystem/Grid.h4
-rw-r--r--src/framework/GameSystem/GridLoader.h4
-rw-r--r--src/framework/GameSystem/GridRefManager.h4
-rw-r--r--src/framework/GameSystem/GridReference.h4
-rw-r--r--src/framework/GameSystem/NGrid.h16
-rw-r--r--src/framework/GameSystem/TypeContainer.h4
-rw-r--r--src/framework/GameSystem/TypeContainerFunctions.h4
-rw-r--r--src/framework/GameSystem/TypeContainerFunctionsPtr.h4
-rw-r--r--src/framework/GameSystem/TypeContainerVisitor.h4
-rw-r--r--src/framework/Makefile.am4
-rw-r--r--src/framework/Network/SocketDefines.h4
-rw-r--r--src/framework/Platform/CompilerDefs.h4
-rw-r--r--src/framework/Platform/Define.h4
-rw-r--r--src/framework/Policies/CreationPolicy.h4
-rw-r--r--src/framework/Policies/ObjectLifeTime.cpp4
-rw-r--r--src/framework/Policies/ObjectLifeTime.h8
-rw-r--r--src/framework/Policies/Singleton.h4
-rw-r--r--src/framework/Policies/SingletonImp.h4
-rw-r--r--src/framework/Policies/ThreadingModel.h4
-rw-r--r--src/framework/Utilities/ByteConverter.h4
-rw-r--r--src/framework/Utilities/Callback.h4
-rw-r--r--src/framework/Utilities/CountedReference/Reference.h4
-rw-r--r--src/framework/Utilities/CountedReference/ReferenceHolder.h4
-rw-r--r--src/framework/Utilities/CountedReference/ReferenceImpl.h4
-rw-r--r--src/framework/Utilities/EventProcessor.cpp4
-rw-r--r--src/framework/Utilities/EventProcessor.h4
-rw-r--r--src/framework/Utilities/LinkedList.h4
-rw-r--r--src/framework/Utilities/LinkedReference/RefManager.h4
-rw-r--r--src/framework/Utilities/LinkedReference/Reference.h18
-rw-r--r--src/framework/Utilities/TypeList.h4
-rw-r--r--src/framework/Utilities/UnorderedMap.h4
-rw-r--r--src/game/AccountMgr.cpp10
-rw-r--r--src/game/AccountMgr.h4
-rw-r--r--src/game/AchievementMgr.cpp1177
-rw-r--r--src/game/AchievementMgr.h176
-rw-r--r--src/game/AddonHandler.cpp69
-rw-r--r--src/game/AddonHandler.h4
-rw-r--r--src/game/AggressorAI.cpp4
-rw-r--r--src/game/AggressorAI.h4
-rw-r--r--src/game/AnimalRandomMovementGenerator.h4
-rw-r--r--src/game/ArenaTeam.cpp44
-rw-r--r--src/game/ArenaTeam.h17
-rw-r--r--src/game/ArenaTeamHandler.cpp6
-rw-r--r--src/game/AuctionHouse.cpp83
-rw-r--r--src/game/AuctionHouseBot.cpp16
-rw-r--r--src/game/AuctionHouseBot.h9
-rw-r--r--src/game/AuctionHouseObject.h27
-rw-r--r--src/game/Bag.cpp6
-rw-r--r--src/game/Bag.h4
-rw-r--r--src/game/BattleGround.cpp87
-rw-r--r--src/game/BattleGround.h56
-rw-r--r--src/game/BattleGroundAA.cpp6
-rw-r--r--src/game/BattleGroundAA.h6
-rw-r--r--src/game/BattleGroundAB.cpp11
-rw-r--r--src/game/BattleGroundAB.h6
-rw-r--r--src/game/BattleGroundAV.cpp7
-rw-r--r--src/game/BattleGroundAV.h6
-rw-r--r--src/game/BattleGroundBE.cpp7
-rw-r--r--src/game/BattleGroundBE.h6
-rw-r--r--src/game/BattleGroundDS.cpp63
-rw-r--r--src/game/BattleGroundDS.h47
-rw-r--r--src/game/BattleGroundEY.cpp9
-rw-r--r--src/game/BattleGroundEY.h6
-rw-r--r--src/game/BattleGroundHandler.cpp68
-rw-r--r--src/game/BattleGroundMgr.cpp532
-rw-r--r--src/game/BattleGroundMgr.h108
-rw-r--r--src/game/BattleGroundNA.cpp7
-rw-r--r--src/game/BattleGroundNA.h6
-rw-r--r--src/game/BattleGroundRL.cpp7
-rw-r--r--src/game/BattleGroundRL.h6
-rw-r--r--src/game/BattleGroundRV.cpp63
-rw-r--r--src/game/BattleGroundRV.h47
-rw-r--r--src/game/BattleGroundSA.cpp68
-rw-r--r--src/game/BattleGroundSA.h52
-rw-r--r--src/game/BattleGroundWS.cpp8
-rw-r--r--src/game/BattleGroundWS.h6
-rw-r--r--src/game/CMakeLists.txt17
-rw-r--r--src/game/Calendar.cpp17
-rw-r--r--src/game/Calendar.h26
-rw-r--r--src/game/CalendarHandler.cpp159
-rw-r--r--src/game/Cell.h8
-rw-r--r--src/game/CellImpl.h4
-rw-r--r--src/game/Channel.cpp4
-rw-r--r--src/game/Channel.h4
-rw-r--r--src/game/ChannelHandler.cpp4
-rw-r--r--src/game/ChannelMgr.h4
-rw-r--r--src/game/CharacterHandler.cpp361
-rw-r--r--src/game/Chat.cpp257
-rw-r--r--src/game/Chat.h31
-rw-r--r--src/game/ChatHandler.cpp6
-rw-r--r--src/game/CombatHandler.cpp4
-rw-r--r--src/game/ConfusedMovementGenerator.cpp4
-rw-r--r--src/game/ConfusedMovementGenerator.h4
-rw-r--r--src/game/Corpse.cpp39
-rw-r--r--src/game/Corpse.h6
-rw-r--r--src/game/Creature.cpp91
-rw-r--r--src/game/Creature.h42
-rw-r--r--src/game/CreatureAI.cpp4
-rw-r--r--src/game/CreatureAI.h4
-rw-r--r--src/game/CreatureAIImpl.h4
-rw-r--r--src/game/CreatureAIRegistry.cpp4
-rw-r--r--src/game/CreatureAIRegistry.h4
-rw-r--r--src/game/CreatureAISelector.cpp4
-rw-r--r--src/game/CreatureAISelector.h4
-rw-r--r--src/game/CreatureGroups.cpp4
-rw-r--r--src/game/CreatureGroups.h4
-rw-r--r--src/game/Debugcmds.cpp87
-rw-r--r--src/game/DestinationHolder.cpp4
-rw-r--r--src/game/DestinationHolder.h4
-rw-r--r--src/game/DestinationHolderImp.h4
-rw-r--r--src/game/DuelHandler.cpp4
-rw-r--r--src/game/DynamicObject.cpp8
-rw-r--r--src/game/DynamicObject.h4
-rw-r--r--src/game/FleeingMovementGenerator.cpp25
-rw-r--r--src/game/FleeingMovementGenerator.h4
-rw-r--r--src/game/FollowerRefManager.h4
-rw-r--r--src/game/FollowerReference.cpp4
-rw-r--r--src/game/FollowerReference.h4
-rw-r--r--src/game/Formulas.h77
-rw-r--r--src/game/GameEvent.cpp117
-rw-r--r--src/game/GameEvent.h4
-rw-r--r--src/game/GameObject.cpp136
-rw-r--r--src/game/GameObject.h44
-rw-r--r--src/game/GlobalEvents.cpp6
-rw-r--r--src/game/GlobalEvents.h4
-rw-r--r--src/game/GossipDef.cpp30
-rw-r--r--src/game/GossipDef.h4
-rw-r--r--src/game/GridDefines.h4
-rw-r--r--src/game/GridNotifiers.cpp23
-rw-r--r--src/game/GridNotifiers.h82
-rw-r--r--src/game/GridNotifiersImpl.h97
-rw-r--r--src/game/GridStates.cpp4
-rw-r--r--src/game/GridStates.h4
-rw-r--r--src/game/Group.cpp54
-rw-r--r--src/game/Group.h19
-rw-r--r--src/game/GroupHandler.cpp66
-rw-r--r--src/game/GroupRefManager.h4
-rw-r--r--src/game/GroupReference.cpp4
-rw-r--r--src/game/GroupReference.h4
-rw-r--r--src/game/GuardAI.cpp4
-rw-r--r--src/game/GuardAI.h4
-rw-r--r--src/game/Guild.cpp57
-rw-r--r--src/game/Guild.h13
-rw-r--r--src/game/GuildHandler.cpp6
-rw-r--r--src/game/HomeMovementGenerator.cpp4
-rw-r--r--src/game/HomeMovementGenerator.h4
-rw-r--r--src/game/HostilRefManager.cpp4
-rw-r--r--src/game/HostilRefManager.h4
-rw-r--r--src/game/IdleMovementGenerator.cpp4
-rw-r--r--src/game/IdleMovementGenerator.h4
-rw-r--r--src/game/InstanceData.cpp4
-rw-r--r--src/game/InstanceData.h4
-rw-r--r--src/game/InstanceSaveMgr.cpp18
-rw-r--r--src/game/InstanceSaveMgr.h4
-rw-r--r--src/game/Item.cpp28
-rw-r--r--src/game/Item.h48
-rw-r--r--src/game/ItemEnchantmentMgr.cpp4
-rw-r--r--src/game/ItemEnchantmentMgr.h4
-rw-r--r--src/game/ItemHandler.cpp110
-rw-r--r--src/game/ItemPrototype.h126
-rw-r--r--src/game/LFGHandler.cpp4
-rw-r--r--src/game/Language.h90
-rw-r--r--src/game/Level0.cpp6
-rw-r--r--src/game/Level1.cpp448
-rw-r--r--src/game/Level2.cpp684
-rw-r--r--src/game/Level3.cpp650
-rw-r--r--src/game/LootHandler.cpp24
-rw-r--r--src/game/LootMgr.cpp234
-rw-r--r--src/game/LootMgr.h52
-rw-r--r--src/game/Mail.cpp12
-rw-r--r--src/game/Mail.h4
-rw-r--r--src/game/Makefile.am561
-rw-r--r--src/game/Map.cpp63
-rw-r--r--src/game/Map.h39
-rw-r--r--src/game/MapInstanced.cpp4
-rw-r--r--src/game/MapInstanced.h4
-rw-r--r--src/game/MapManager.cpp12
-rw-r--r--src/game/MapManager.h25
-rw-r--r--src/game/MapRefManager.h2
-rw-r--r--src/game/MapReference.h2
-rw-r--r--src/game/MiscHandler.cpp159
-rw-r--r--src/game/MovementGenerator.cpp4
-rw-r--r--src/game/MovementGenerator.h4
-rw-r--r--src/game/MovementGeneratorImpl.h4
-rw-r--r--src/game/MovementHandler.cpp329
-rw-r--r--src/game/NPCHandler.cpp52
-rw-r--r--src/game/NPCHandler.h4
-rw-r--r--src/game/NullCreatureAI.cpp4
-rw-r--r--src/game/NullCreatureAI.h4
-rw-r--r--src/game/Object.cpp127
-rw-r--r--src/game/Object.h34
-rw-r--r--src/game/ObjectAccessor.cpp107
-rw-r--r--src/game/ObjectAccessor.h36
-rw-r--r--src/game/ObjectDefines.h8
-rw-r--r--src/game/ObjectGridLoader.cpp6
-rw-r--r--src/game/ObjectGridLoader.h4
-rw-r--r--src/game/ObjectMgr.cpp636
-rw-r--r--src/game/ObjectMgr.h39
-rw-r--r--src/game/ObjectPosSelector.cpp157
-rw-r--r--src/game/ObjectPosSelector.h155
-rw-r--r--src/game/Opcodes.cpp2257
-rw-r--r--src/game/Opcodes.h407
-rw-r--r--src/game/OutdoorPvP.cpp10
-rw-r--r--src/game/OutdoorPvP.h2
-rw-r--r--src/game/OutdoorPvPEP.cpp2
-rw-r--r--src/game/OutdoorPvPEP.h2
-rw-r--r--src/game/OutdoorPvPHP.cpp2
-rw-r--r--src/game/OutdoorPvPHP.h2
-rw-r--r--src/game/OutdoorPvPMgr.cpp2
-rw-r--r--src/game/OutdoorPvPMgr.h2
-rw-r--r--src/game/OutdoorPvPNA.cpp2
-rw-r--r--src/game/OutdoorPvPNA.h2
-rw-r--r--src/game/OutdoorPvPObjectiveAI.cpp2
-rw-r--r--src/game/OutdoorPvPObjectiveAI.h2
-rw-r--r--src/game/OutdoorPvPSI.cpp6
-rw-r--r--src/game/OutdoorPvPSI.h2
-rw-r--r--src/game/OutdoorPvPTF.cpp2
-rw-r--r--src/game/OutdoorPvPZM.cpp2
-rw-r--r--src/game/OutdoorPvPZM.h2
-rw-r--r--src/game/Path.h4
-rw-r--r--src/game/Pet.cpp651
-rw-r--r--src/game/Pet.h70
-rw-r--r--src/game/PetAI.cpp8
-rw-r--r--src/game/PetAI.h4
-rw-r--r--src/game/PetHandler.cpp266
-rw-r--r--src/game/PetitionsHandler.cpp12
-rw-r--r--src/game/Player.cpp3317
-rw-r--r--src/game/Player.h407
-rw-r--r--src/game/PlayerDump.cpp4
-rw-r--r--src/game/PlayerDump.h4
-rw-r--r--src/game/PointMovementGenerator.cpp4
-rw-r--r--src/game/PointMovementGenerator.h4
-rw-r--r--src/game/PossessedAI.cpp4
-rw-r--r--src/game/PossessedAI.h4
-rw-r--r--src/game/QueryHandler.cpp49
-rw-r--r--src/game/QuestDef.cpp114
-rw-r--r--src/game/QuestDef.h53
-rw-r--r--src/game/QuestHandler.cpp12
-rw-r--r--src/game/RandomMovementGenerator.cpp4
-rw-r--r--src/game/RandomMovementGenerator.h4
-rw-r--r--src/game/ReactorAI.cpp4
-rw-r--r--src/game/ReactorAI.h4
-rw-r--r--src/game/ScriptCalls.cpp7
-rw-r--r--src/game/ScriptCalls.h4
-rw-r--r--src/game/SharedDefines.h416
-rw-r--r--src/game/SkillDiscovery.cpp82
-rw-r--r--src/game/SkillDiscovery.h5
-rw-r--r--src/game/SkillExtraItems.cpp4
-rw-r--r--src/game/SkillExtraItems.h4
-rw-r--r--src/game/SkillHandler.cpp10
-rw-r--r--src/game/SocialMgr.cpp11
-rw-r--r--src/game/SocialMgr.h7
-rw-r--r--src/game/Spell.cpp1081
-rw-r--r--src/game/Spell.h79
-rw-r--r--src/game/SpellAuraDefines.h92
-rw-r--r--src/game/SpellAuras.cpp2446
-rw-r--r--src/game/SpellAuras.h113
-rw-r--r--src/game/SpellEffects.cpp1857
-rw-r--r--src/game/SpellHandler.cpp104
-rw-r--r--src/game/SpellMgr.cpp919
-rw-r--r--src/game/SpellMgr.h527
-rw-r--r--src/game/StatSystem.cpp180
-rw-r--r--src/game/TargetedMovementGenerator.cpp4
-rw-r--r--src/game/TargetedMovementGenerator.h4
-rw-r--r--src/game/TaxiHandler.cpp12
-rw-r--r--src/game/TemporarySummon.cpp4
-rw-r--r--src/game/TemporarySummon.h4
-rw-r--r--src/game/ThreatManager.cpp33
-rw-r--r--src/game/ThreatManager.h12
-rw-r--r--src/game/TicketHandler.cpp4
-rw-r--r--src/game/TicketMgr.cpp4
-rw-r--r--src/game/TicketMgr.h4
-rw-r--r--src/game/Tools.cpp4
-rw-r--r--src/game/Tools.h4
-rw-r--r--src/game/Totem.cpp28
-rw-r--r--src/game/Totem.h6
-rw-r--r--src/game/TotemAI.cpp19
-rw-r--r--src/game/TotemAI.h4
-rw-r--r--src/game/TradeHandler.cpp4
-rw-r--r--src/game/Transports.cpp23
-rw-r--r--src/game/Transports.h16
-rw-r--r--src/game/Traveller.h12
-rw-r--r--src/game/Unit.cpp6353
-rw-r--r--src/game/Unit.h295
-rw-r--r--src/game/UnitEvents.h4
-rw-r--r--src/game/UpdateData.cpp6
-rw-r--r--src/game/UpdateData.h9
-rw-r--r--src/game/UpdateFields.h535
-rw-r--r--src/game/UpdateMask.h32
-rw-r--r--src/game/Vehicle.cpp102
-rw-r--r--src/game/Vehicle.h58
-rw-r--r--src/game/VoiceChatHandler.cpp4
-rw-r--r--src/game/WaypointManager.cpp4
-rw-r--r--src/game/WaypointManager.h4
-rw-r--r--src/game/WaypointMovementGenerator.cpp2
-rw-r--r--src/game/WaypointMovementGenerator.h8
-rw-r--r--src/game/Weather.cpp6
-rw-r--r--src/game/Weather.h6
-rw-r--r--src/game/World.cpp174
-rw-r--r--src/game/World.h26
-rw-r--r--src/game/WorldLog.cpp4
-rw-r--r--src/game/WorldLog.h8
-rw-r--r--src/game/WorldSession.cpp100
-rw-r--r--src/game/WorldSession.h61
-rw-r--r--src/game/WorldSocket.cpp202
-rw-r--r--src/game/WorldSocket.h24
-rw-r--r--src/game/WorldSocketMgr.cpp2
-rw-r--r--src/game/WorldSocketMgr.h4
-rw-r--r--src/mangosd/CMakeLists.txt53
-rw-r--r--src/mangosd/CliRunnable.cpp366
-rw-r--r--src/mangosd/CliRunnable.h35
-rw-r--r--src/mangosd/Main.cpp165
-rw-r--r--src/mangosd/Makefile.am62
-rw-r--r--src/mangosd/Master.cpp519
-rw-r--r--src/mangosd/Master.h52
-rw-r--r--src/mangosd/RASocket.cpp259
-rw-r--r--src/mangosd/RASocket.h (renamed from src/trinitycore/RASocket.h)4
-rw-r--r--src/mangosd/TrinityCore.ico (renamed from src/trinitycore/TrinityCore.ico)bin136606 -> 136606 bytes
-rw-r--r--src/mangosd/WorldRunnable.cpp90
-rw-r--r--src/mangosd/WorldRunnable.h35
-rw-r--r--src/mangosd/mangosd.conf.dist.in1448
-rw-r--r--src/mangosd/mangosd.rc (renamed from src/trinitycore/TrinityCore.rc)2
-rw-r--r--src/mangosd/monitor-mangosd (renamed from src/trinitycore/monitor-mangosd)0
-rw-r--r--src/mangosd/resource.h15
-rw-r--r--src/mangosd/run-mangosd (renamed from src/trinitycore/run-mangosd)0
-rw-r--r--src/realmd/AuthCodes.h75
-rw-r--r--src/realmd/AuthSocket.cpp1094
-rw-r--r--src/realmd/AuthSocket.h (renamed from src/trinityrealm/AuthSocket.h)4
-rw-r--r--src/realmd/CMakeLists.txt45
-rw-r--r--src/realmd/Main.cpp345
-rw-r--r--src/realmd/Makefile.am59
-rw-r--r--src/realmd/RealmList.cpp101
-rw-r--r--src/realmd/RealmList.h67
-rw-r--r--src/realmd/TrinityRealm.ico (renamed from src/trinityrealm/TrinityRealm.ico)bin136606 -> 136606 bytes
-rw-r--r--src/realmd/realmd.conf.dist.in (renamed from src/trinityrealm/trinityrealm.conf.dist)0
-rw-r--r--src/realmd/realmd.rc (renamed from src/trinityrealm/TrinityRealm.rc)2
-rw-r--r--src/realmd/resource.h15
-rw-r--r--src/shared/Auth/AuthCrypt.cpp9
-rw-r--r--src/shared/Auth/AuthCrypt.h5
-rw-r--r--src/shared/Auth/BigNumber.cpp4
-rw-r--r--src/shared/Auth/BigNumber.h4
-rw-r--r--src/shared/Auth/Hmac.cpp4
-rw-r--r--src/shared/Auth/Hmac.h4
-rw-r--r--src/shared/Auth/Makefile.am30
-rw-r--r--src/shared/Auth/Sha1.cpp4
-rw-r--r--src/shared/Auth/Sha1.h4
-rw-r--r--src/shared/ByteBuffer.h30
-rw-r--r--src/shared/Common.cpp4
-rw-r--r--src/shared/Common.h6
-rw-r--r--src/shared/Config/Config.cpp4
-rw-r--r--src/shared/Config/Config.h4
-rw-r--r--src/shared/Config/ConfigEnv.h4
-rw-r--r--src/shared/Config/Makefile.am10
-rw-r--r--src/shared/Config/dotconfpp/dotconfpp.cpp4
-rw-r--r--src/shared/Database/DBCEnums.h247
-rw-r--r--src/shared/Database/DBCStores.cpp128
-rw-r--r--src/shared/Database/DBCStores.h19
-rw-r--r--src/shared/Database/DBCStructure.h1383
-rw-r--r--src/shared/Database/DBCfmt.cpp67
-rw-r--r--src/shared/Database/Database.cpp4
-rw-r--r--src/shared/Database/Database.h6
-rw-r--r--src/shared/Database/DatabaseEnv.h4
-rw-r--r--src/shared/Database/DatabaseImpl.h4
-rw-r--r--src/shared/Database/DatabaseMysql.cpp4
-rw-r--r--src/shared/Database/DatabaseMysql.h4
-rw-r--r--src/shared/Database/DatabasePostgre.cpp4
-rw-r--r--src/shared/Database/DatabasePostgre.h4
-rw-r--r--src/shared/Database/DatabaseSqlite.cpp4
-rw-r--r--src/shared/Database/DatabaseSqlite.h4
-rw-r--r--src/shared/Database/Field.cpp4
-rw-r--r--src/shared/Database/Field.h4
-rw-r--r--src/shared/Database/Makefile.am78
-rw-r--r--src/shared/Database/MySQLDelayThread.h4
-rw-r--r--src/shared/Database/PGSQLDelayThread.h4
-rw-r--r--src/shared/Database/QueryResult.h4
-rw-r--r--src/shared/Database/QueryResultMysql.cpp4
-rw-r--r--src/shared/Database/QueryResultMysql.h4
-rw-r--r--src/shared/Database/QueryResultPostgre.cpp4
-rw-r--r--src/shared/Database/QueryResultPostgre.h4
-rw-r--r--src/shared/Database/QueryResultSqlite.cpp4
-rw-r--r--src/shared/Database/QueryResultSqlite.h4
-rw-r--r--src/shared/Database/SQLStorage.cpp18
-rw-r--r--src/shared/Database/SQLStorage.h4
-rw-r--r--src/shared/Database/SQLStorageImpl.h2
-rw-r--r--src/shared/Database/SqlDelayThread.cpp4
-rw-r--r--src/shared/Database/SqlDelayThread.h6
-rw-r--r--src/shared/Database/SqlOperations.cpp4
-rw-r--r--src/shared/Database/SqlOperations.h4
-rw-r--r--src/shared/Database/dbcfile.cpp4
-rw-r--r--src/shared/Database/dbcfile.h4
-rw-r--r--src/shared/Errors.h4
-rw-r--r--src/shared/Log.cpp4
-rw-r--r--src/shared/Log.h4
-rw-r--r--src/shared/Makefile.am112
-rw-r--r--src/shared/MemoryLeaks.cpp32
-rw-r--r--src/shared/MemoryLeaks.h48
-rw-r--r--src/shared/PacketLog.cpp4
-rw-r--r--src/shared/PacketLog.h4
-rw-r--r--src/shared/ProgressBar.cpp4
-rw-r--r--src/shared/ProgressBar.h4
-rw-r--r--src/shared/ServiceWin32.cpp4
-rw-r--r--src/shared/ServiceWin32.h4
-rw-r--r--src/shared/SystemConfig.h6
-rw-r--r--src/shared/SystemConfig.h.in79
-rw-r--r--src/shared/Timer.h4
-rw-r--r--src/shared/Util.cpp14
-rw-r--r--src/shared/Util.h257
-rw-r--r--src/shared/WorldPacket.h4
-rw-r--r--src/shared/revision_nr.h4
-rw-r--r--src/shared/vmap/BaseModel.cpp4
-rw-r--r--src/shared/vmap/BaseModel.h4
-rw-r--r--src/shared/vmap/CoordModelMapping.cpp4
-rw-r--r--src/shared/vmap/CoordModelMapping.h4
-rw-r--r--src/shared/vmap/DebugCmdLogger.cpp4
-rw-r--r--src/shared/vmap/DebugCmdLogger.h4
-rw-r--r--src/shared/vmap/IVMapManager.h4
-rw-r--r--src/shared/vmap/Makefile.am78
-rw-r--r--src/shared/vmap/ManagedModelContainer.cpp4
-rw-r--r--src/shared/vmap/ManagedModelContainer.h4
-rw-r--r--src/shared/vmap/ModelContainer.cpp4
-rw-r--r--src/shared/vmap/ModelContainer.h4
-rw-r--r--src/shared/vmap/NodeValueAccess.h4
-rw-r--r--src/shared/vmap/ShortBox.h4
-rw-r--r--src/shared/vmap/ShortVector.h4
-rw-r--r--src/shared/vmap/SubModel.cpp4
-rw-r--r--src/shared/vmap/SubModel.h4
-rw-r--r--src/shared/vmap/TileAssembler.cpp7
-rw-r--r--src/shared/vmap/TileAssembler.h4
-rw-r--r--src/shared/vmap/TreeNode.cpp4
-rw-r--r--src/shared/vmap/TreeNode.h4
-rw-r--r--src/shared/vmap/VMapDefinitions.h4
-rw-r--r--src/shared/vmap/VMapFactory.cpp4
-rw-r--r--src/shared/vmap/VMapFactory.h4
-rw-r--r--src/shared/vmap/VMapManager.cpp4
-rw-r--r--src/shared/vmap/VMapManager.h4
-rw-r--r--src/shared/vmap/VMapTools.h4
-rw-r--r--src/tools/Makefile.am21
-rw-r--r--src/tools/genrevision/Makefile.am24
-rw-r--r--src/tools/genrevision/genrevision.cpp2
-rw-r--r--src/trinitycore/CliRunnable.cpp4
-rw-r--r--src/trinitycore/Main.cpp4
-rw-r--r--src/trinitycore/Makefile.am85
-rw-r--r--src/trinitycore/Master.cpp4
-rw-r--r--src/trinitycore/RASocket.cpp4
-rw-r--r--src/trinitycore/WorldRunnable.cpp4
-rw-r--r--src/trinityrealm/AuthSocket.cpp4
-rw-r--r--src/trinityrealm/Main.cpp4
-rw-r--r--src/trinityrealm/Makefile.am72
-rw-r--r--src/trinityrealm/RealmList.cpp4
516 files changed, 29651 insertions, 14226 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 8c8b9e0126f..fe367ba22d0 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,6 +1,6 @@
add_subdirectory(framework)
add_subdirectory(shared)
-add_subdirectory(trinityrealm)
+add_subdirectory(realmd)
add_subdirectory(game)
add_subdirectory(bindings)
-add_subdirectory(trinitycore)
+add_subdirectory(mangosd)
diff --git a/src/Makefile.am b/src/Makefile.am
index 40787fa17d0..7309b10db83 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,6 +1,6 @@
-# Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+# Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
#
-# Thanks to the original authors: MaNGOS <http://www.mangosproject.org/>
+# Thanks to the original authors: 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
@@ -9,17 +9,17 @@
#
# 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
+# 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, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
## Process this file with automake to produce Makefile.in
## Sub-directories to parse
-SUBDIRS = framework shared trinityrealm game bindings trinitycore
+SUBDIRS = tools framework shared realmd game bindings mangosd
## Additional files to include when running 'make dist'
# Nothing yet.
diff --git a/src/bindings/Makefile.am b/src/bindings/Makefile.am
index 5e85dfe15bc..26914e8fde1 100644
--- a/src/bindings/Makefile.am
+++ b/src/bindings/Makefile.am
@@ -1,6 +1,6 @@
-# Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+# Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
#
-# Thanks to the original authors: MaNGOS <http://www.mangosproject.org/>
+# Thanks to the original authors: 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
@@ -18,8 +18,8 @@
# interface folder is disabled for now
-if USE_TSCRIPTS
+#if USE_TSCRIPTS
SUBDIRS = scripts
-else
-SUBDIRS = interface
-endif
+#else
+#SUBDIRS = interface
+#endif
diff --git a/src/bindings/interface/Makefile.am b/src/bindings/interface/Makefile.am
index bcca2128203..9bb53f98454 100644
--- a/src/bindings/interface/Makefile.am
+++ b/src/bindings/interface/Makefile.am
@@ -1,6 +1,6 @@
-# Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+# Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
#
-# Thanks to the original authors: MaNGOS <http://www.mangosproject.org/>
+# Thanks to the original authors: 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
diff --git a/src/bindings/interface/ScriptMgr.cpp b/src/bindings/interface/ScriptMgr.cpp
index 276b5fa3a54..abbde65c51a 100644
--- a/src/bindings/interface/ScriptMgr.cpp
+++ b/src/bindings/interface/ScriptMgr.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
- * Thanks to the original authors: MaNGOS <http://www.mangosproject.org/>
+ * Thanks to the original authors: 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
diff --git a/src/bindings/interface/ScriptMgr.h b/src/bindings/interface/ScriptMgr.h
index 30d94ac01e1..2296d2247de 100644
--- a/src/bindings/interface/ScriptMgr.h
+++ b/src/bindings/interface/ScriptMgr.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
- * Thanks to the original authors: MaNGOS <http://www.mangosproject.org/>
+ * Thanks to the original authors: 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
diff --git a/src/bindings/interface/Scripts/sc_default.cpp b/src/bindings/interface/Scripts/sc_default.cpp
index 79796eba8f6..f6c8386579f 100644
--- a/src/bindings/interface/Scripts/sc_default.cpp
+++ b/src/bindings/interface/Scripts/sc_default.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
- * Thanks to the original authors: MaNGOS <http://www.mangosproject.org/>
+ * Thanks to the original authors: 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
diff --git a/src/bindings/interface/Scripts/sc_defines.cpp b/src/bindings/interface/Scripts/sc_defines.cpp
index 2c7c4ec743f..45456a1d5e2 100644
--- a/src/bindings/interface/Scripts/sc_defines.cpp
+++ b/src/bindings/interface/Scripts/sc_defines.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
- * Thanks to the original authors: MaNGOS <http://www.mangosproject.org/>
+ * Thanks to the original authors: 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
diff --git a/src/bindings/interface/Scripts/sc_defines.h b/src/bindings/interface/Scripts/sc_defines.h
index 1f8b468dc05..ecd55aa7282 100644
--- a/src/bindings/interface/Scripts/sc_defines.h
+++ b/src/bindings/interface/Scripts/sc_defines.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
- * Thanks to the original authors: MaNGOS <http://www.mangosproject.org/>
+ * Thanks to the original authors: 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
diff --git a/src/bindings/interface/config.h b/src/bindings/interface/config.h
index f074f0a3351..ab312d7d3f4 100644
--- a/src/bindings/interface/config.h
+++ b/src/bindings/interface/config.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
- * Thanks to the original authors: MaNGOS <http://www.mangosproject.org/>
+ * Thanks to the original authors: 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
diff --git a/src/bindings/interface/system.cpp b/src/bindings/interface/system.cpp
index 3c76284b5af..20eaf9ce64c 100644
--- a/src/bindings/interface/system.cpp
+++ b/src/bindings/interface/system.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
- * Thanks to the original authors: MaNGOS <http://www.mangosproject.org/>
+ * Thanks to the original authors: 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
diff --git a/src/bindings/scripts/CMakeLists.txt b/src/bindings/scripts/CMakeLists.txt
index d908064ca9b..e482940a280 100644
--- a/src/bindings/scripts/CMakeLists.txt
+++ b/src/bindings/scripts/CMakeLists.txt
@@ -106,6 +106,7 @@ SET(trinityscript_LIB_SRCS
scripts/zone/blasted_lands/blasted_lands.cpp
scripts/zone/blasted_lands/boss_kruul.cpp
scripts/zone/bloodmyst_isle/bloodmyst_isle.cpp
+ scripts/zone/borean_tundra/borean_tundra.cpp
scripts/zone/burning_steppes/burning_steppes.cpp
scripts/zone/caverns_of_time/dark_portal/def_dark_portal.h
scripts/zone/caverns_of_time/dark_portal/instance_dark_portal.cpp
@@ -346,6 +347,8 @@ SET(trinityscript_LIB_SRCS
scripts/zone/uldaman/uldaman.cpp
scripts/zone/undercity/undercity.cpp
scripts/zone/ungoro_crater/ungoro_crater.cpp
+ scripts/zone/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp
+ scripts/zone/utgarde_keep/utgarde_keep/boss_keleseth.cpp
scripts/zone/wailing_caverns/instance_wailing_caverns.cpp
scripts/zone/western_plaguelands/western_plaguelands.cpp
scripts/zone/westfall/westfall.cpp
diff --git a/src/bindings/scripts/Makefile.am b/src/bindings/scripts/Makefile.am
index ac5965336a6..0e1890ac869 100644
--- a/src/bindings/scripts/Makefile.am
+++ b/src/bindings/scripts/Makefile.am
@@ -1,6 +1,6 @@
-# Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+# Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
#
-# Thanks to the original authors: MaNGOS <http://www.mangosproject.org/>
+# Thanks to the original authors: 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
@@ -140,6 +140,7 @@ scripts/zone/blades_edge_mountains/blades_edge_mountains.cpp \
scripts/zone/blasted_lands/blasted_lands.cpp \
scripts/zone/blasted_lands/boss_kruul.cpp \
scripts/zone/bloodmyst_isle/bloodmyst_isle.cpp \
+scripts/zone/borean_tundra/borean_tundra.cpp \
scripts/zone/burning_steppes/burning_steppes.cpp \
scripts/zone/caverns_of_time/dark_portal/boss_aeonus.cpp \
scripts/zone/caverns_of_time/dark_portal/boss_chrono_lord_deja.cpp \
@@ -379,6 +380,8 @@ scripts/zone/uldaman/boss_ironaya.cpp \
scripts/zone/uldaman/uldaman.cpp \
scripts/zone/undercity/undercity.cpp \
scripts/zone/ungoro_crater/ungoro_crater.cpp \
+scripts/zone/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp \
+scripts/zone/utgarde_keep/utgarde_keep/boss_keleseth.cpp \
scripts/zone/wailing_caverns/instance_wailing_caverns.cpp \
scripts/zone/western_plaguelands/western_plaguelands.cpp \
scripts/zone/westfall/westfall.cpp \
diff --git a/src/bindings/scripts/ScriptMgr.cpp b/src/bindings/scripts/ScriptMgr.cpp
index c41a461e4d1..5dc16953860 100644
--- a/src/bindings/scripts/ScriptMgr.cpp
+++ b/src/bindings/scripts/ScriptMgr.cpp
@@ -211,6 +211,9 @@ extern void AddSC_blasted_lands();
//Bloodmyst Isle
extern void AddSC_bloodmyst_isle();
+//Borean Tundra
+extern void AddSC_borean_tundra();
+
//Burning steppes
extern void AddSC_burning_steppes();
@@ -392,12 +395,12 @@ extern void AddSC_boss_patchwerk();
extern void AddSC_boss_razuvious();
extern void AddSC_boss_highlord_mograine();
extern void AddSC_boss_kelthuzad();
-extern void AddSC_boss_faerlina();
extern void AddSC_boss_loatheb();
extern void AddSC_boss_noth();
extern void AddSC_boss_gluth();
extern void AddSC_boss_sapphiron();
extern void AddSC_boss_four_horsemen();
+extern void AddSC_boss_faerlina();
//Netherstorm
extern void AddSC_netherstorm();
@@ -566,6 +569,11 @@ extern void AddSC_undercity();
extern void AddSC_ungoro_crater();
//Upper blackrock spire
+
+//Utgarde Keep
+extern void AddSC_boss_keleseth();
+extern void AddSC_instance_utgarde_keep();
+
//Wailing caverns
//Western plaguelands
@@ -1418,6 +1426,9 @@ void ScriptsInit()
//Bloodmyst Isle
AddSC_bloodmyst_isle();
+
+ //Borean Tundra
+ AddSC_borean_tundra();
//Burning steppes
AddSC_burning_steppes();
@@ -1594,12 +1605,12 @@ void ScriptsInit()
//Naxxramas
AddSC_boss_anubrekhan();
+ AddSC_boss_faerlina();
AddSC_boss_maexxna();
AddSC_boss_patchwerk();
AddSC_boss_razuvious();
- AddSC_boss_highlord_mograine();
- AddSC_boss_kelthuzad();
- AddSC_boss_faerlina();
+ AddSC_boss_highlord_mograine();
+ AddSC_boss_kelthuzad();
AddSC_boss_loatheb();
AddSC_boss_noth();
AddSC_boss_gluth();
@@ -1773,6 +1784,11 @@ void ScriptsInit()
AddSC_ungoro_crater();
//Upper blackrock spire
+
+ //Utgarde Keep
+ AddSC_boss_keleseth();
+ AddSC_instance_utgarde_keep();
+
//Wailing caverns
//Western plaguelands
diff --git a/src/bindings/scripts/ScriptMgr.h b/src/bindings/scripts/ScriptMgr.h
index ef7bdfd3cce..ebc102f32d9 100644
--- a/src/bindings/scripts/ScriptMgr.h
+++ b/src/bindings/scripts/ScriptMgr.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+/* Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
* Thanks to the original authors: ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
diff --git a/src/bindings/scripts/VC71/71ScriptDev2.vcproj b/src/bindings/scripts/VC71/71ScriptDev2.vcproj
index a309f585589..302d97c9736 100644
--- a/src/bindings/scripts/VC71/71ScriptDev2.vcproj
+++ b/src/bindings/scripts/VC71/71ScriptDev2.vcproj
@@ -1879,6 +1879,7 @@
RelativePath="..\scripts\zone\caverns_of_time\dark_portal\instance_dark_portal.cpp"
>
</File>
+
</Filter>
<Filter
Name="Battle for Mt. Hyjal"
@@ -1936,6 +1937,9 @@
>
</File>
</Filter>
+ <Filter
+ Name="Culling of Stratholme">
+ </Filter>
</Filter>
<Filter
Name="Silvermoon City"
@@ -1969,6 +1973,107 @@
>
</File>
</Filter>
+ <Filter
+ Name="Borean Tundra">
+ <File
+ RelativePath="..\scripts\zone\borean_tundra\borean_tundra.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Howling Fjord">
+ </Filter>
+ <Filter
+ Name="Crystalsong Forest">
+ </Filter>
+ <Filter
+ Name="Dalaran">
+ </Filter>
+ <Filter
+ Name="Dragonblight">
+ </Filter>
+ <Filter
+ Name="Grizzly Hills">
+ </Filter>
+ <Filter
+ Name="Icecrown">
+ </Filter>
+ <Filter
+ Name="Sholazar Basin">
+ </Filter>
+ <Filter
+ Name="The Storm Peaks">
+ </Filter>
+ <Filter
+ Name="Zul&apos;Drak">
+ </Filter>
+ <Filter
+ Name="Azjol-Nerub">
+ <Filter
+ Name="Ahn&apos;kahet">
+ </Filter>
+ <Filter
+ Name="Azjol-Nerub">
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Drak&apos;Tharon Keep">
+ </Filter>
+ <Filter
+ Name="Gundrak">
+ </Filter>
+ <Filter
+ Name="Nexus">
+ <Filter
+ Name="Nexus">
+ </Filter>
+ <Filter
+ Name="Oculus">
+ </Filter>
+ <Filter
+ Name="Eye of Eternity">
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Violet Hold">
+ </Filter>
+ <Filter
+ Name="Ulduar"
+ >
+ <Filter
+ Name="Halls of Stone">
+ </Filter>
+ <Filter
+ Name="Halls of Lightning">
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Utgarde Keep">
+ <Filter
+ Name="Utgarde Keep">
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_keep\boss_keleseth.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_keep\def_keep.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_keep\instance_utgarde_keep.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Utgarde Pinnacle">
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Obsidian Sanctum">
+ </Filter>
+ <Filter
+ Name="Vault of Archavon">
+ </Filter>
<Filter
Name="Shattrath City"
>
diff --git a/src/bindings/scripts/VC80/80ScriptDev2.vcproj b/src/bindings/scripts/VC80/80ScriptDev2.vcproj
index e4e20bbb129..62fa4d240e6 100644
--- a/src/bindings/scripts/VC80/80ScriptDev2.vcproj
+++ b/src/bindings/scripts/VC80/80ScriptDev2.vcproj
@@ -1078,6 +1078,107 @@
Name="Ragefire Chasm"
>
</Filter>
+ <Filter
+ Name="Borean Tundra">
+ <File
+ RelativePath="..\scripts\zone\borean_tundra\borean_tundra.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Howling Fjord">
+ </Filter>
+ <Filter
+ Name="Crystalsong Forest">
+ </Filter>
+ <Filter
+ Name="Dalaran">
+ </Filter>
+ <Filter
+ Name="Dragonblight">
+ </Filter>
+ <Filter
+ Name="Grizzly Hills">
+ </Filter>
+ <Filter
+ Name="Icecrown">
+ </Filter>
+ <Filter
+ Name="Sholazar Basin">
+ </Filter>
+ <Filter
+ Name="The Storm Peaks">
+ </Filter>
+ <Filter
+ Name="Zul&apos;Drak">
+ </Filter>
+ <Filter
+ Name="Azjol-Nerub">
+ <Filter
+ Name="Ahn&apos;kahet">
+ </Filter>
+ <Filter
+ Name="Azjol-Nerub">
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Drak&apos;Tharon Keep">
+ </Filter>
+ <Filter
+ Name="Gundrak">
+ </Filter>
+ <Filter
+ Name="Nexus">
+ <Filter
+ Name="Nexus">
+ </Filter>
+ <Filter
+ Name="Oculus">
+ </Filter>
+ <Filter
+ Name="Eye of Eternity">
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Violet Hold">
+ </Filter>
+ <Filter
+ Name="Ulduar"
+ >
+ <Filter
+ Name="Halls of Stone">
+ </Filter>
+ <Filter
+ Name="Halls of Lightning">
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Utgarde Keep">
+ <Filter
+ Name="Utgarde Keep">
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_keep\boss_keleseth.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_keep\def_keep.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_keep\instance_utgarde_keep.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Utgarde Pinnacle">
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Obsidian Sanctum">
+ </Filter>
+ <Filter
+ Name="Vault of Archavon">
+ </Filter>
<Filter
Name="Razorfen Downs"
>
@@ -2086,6 +2187,9 @@
</File>
</Filter>
<Filter
+ Name="Culling of Stratholme">
+ </Filter>
+ <Filter
Name="Old Hillsbrad"
>
<File
diff --git a/src/bindings/scripts/VC90/90ScriptDev2.vcproj b/src/bindings/scripts/VC90/90ScriptDev2.vcproj
index e6d36179274..dfb4b147848 100644
--- a/src/bindings/scripts/VC90/90ScriptDev2.vcproj
+++ b/src/bindings/scripts/VC90/90ScriptDev2.vcproj
@@ -748,6 +748,134 @@
>
</Filter>
<Filter
+ Name="Borean Tundra"
+ >
+ <File
+ RelativePath="..\scripts\zone\borean_tundra\borean_tundra.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Howling Fjord"
+ >
+ </Filter>
+ <Filter
+ Name="Crystalsong Forest"
+ >
+ </Filter>
+ <Filter
+ Name="Dalaran"
+ >
+ </Filter>
+ <Filter
+ Name="Dragonblight"
+ >
+ </Filter>
+ <Filter
+ Name="Grizzly Hills"
+ >
+ </Filter>
+ <Filter
+ Name="Icecrown"
+ >
+ </Filter>
+ <Filter
+ Name="Sholazar Basin"
+ >
+ </Filter>
+ <Filter
+ Name="The Storm Peaks"
+ >
+ </Filter>
+ <Filter
+ Name="Zul&apos;Drak"
+ >
+ </Filter>
+ <Filter
+ Name="Azjol-Nerub"
+ >
+ <Filter
+ Name="Ahn&apos;kahet"
+ >
+ </Filter>
+ <Filter
+ Name="Azjol-Nerub"
+ >
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Drak&apos;Tharon Keep"
+ >
+ </Filter>
+ <Filter
+ Name="Gundrak"
+ >
+ </Filter>
+ <Filter
+ Name="Nexus"
+ >
+ <Filter
+ Name="Nexus"
+ >
+ </Filter>
+ <Filter
+ Name="Oculus"
+ >
+ </Filter>
+ <Filter
+ Name="Eye of Eternity"
+ >
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Violet Hold"
+ >
+ </Filter>
+ <Filter
+ Name="Ulduar"
+ >
+ <Filter
+ Name="Halls of Stone"
+ >
+ </Filter>
+ <Filter
+ Name="Halls of Lightning"
+ >
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Utgarde Keep"
+ >
+ <Filter
+ Name="Utgarde Keep"
+ >
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_keep\boss_keleseth.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_keep\def_keep.h"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\utgarde_keep\utgarde_keep\instance_utgarde_keep.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Utgarde Pinnacle"
+ >
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Obsidian Sanctum"
+ >
+ </Filter>
+ <Filter
+ Name="Vault of Archavon"
+ >
+ </Filter>
+ <Filter
Name="Scarlet Monastery"
>
<File
@@ -2079,6 +2207,10 @@
</File>
</Filter>
<Filter
+ Name="Culling of Stratholme"
+ >
+ </Filter>
+ <Filter
Name="Old Hillsbrad"
>
<File
diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp
index 6c9a0059b11..8764f612557 100644
--- a/src/bindings/scripts/include/sc_creature.cpp
+++ b/src/bindings/scripts/include/sc_creature.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+/* Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
* Thanks to the original authors: ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
@@ -454,11 +454,9 @@ SpellEntry const* ScriptedAI::SelectSpell(Unit* Target, int32 School, int32 Mech
return false;
//Using the extended script system we first create a list of viable spells
- SpellEntry const* Spell[4];
- Spell[0] = 0;
- Spell[1] = 0;
- Spell[2] = 0;
- Spell[3] = 0;
+ SpellEntry const* Spell[CREATURE_MAX_SPELLS];
+ for (uint8 i=0;i<CREATURE_MAX_SPELLS;i++)
+ Spell[i] = 0;
uint32 SpellCount = 0;
@@ -466,7 +464,7 @@ SpellEntry const* ScriptedAI::SelectSpell(Unit* Target, int32 School, int32 Mech
SpellRangeEntry const* TempRange;
//Check if each spell is viable(set it to null if not)
- for (uint32 i = 0; i < 4; i++)
+ for (uint32 i = 0; i < CREATURE_MAX_SPELLS; i++)
{
TempSpell = GetSpellStore()->LookupEntry(m_creature->m_spells[i]);
@@ -600,7 +598,7 @@ void FillSpellSummary()
//Spell targets AoE at enemy
if ( TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA ||
TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_INSTANT ||
- TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_AROUND_CASTER ||
+ TempSpell->EffectImplicitTargetA[j] == TARGET_DEST_CASTER ||
TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED )
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_AOE_ENEMY-1);
@@ -609,7 +607,7 @@ void FillSpellSummary()
TempSpell->EffectImplicitTargetA[j] == TARGET_CURRENT_ENEMY_COORDINATES ||
TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA ||
TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_INSTANT ||
- TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_AROUND_CASTER ||
+ TempSpell->EffectImplicitTargetA[j] == TARGET_DEST_CASTER ||
TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED )
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_ANY_ENEMY-1);
@@ -622,7 +620,7 @@ void FillSpellSummary()
//Spell targets aoe friends
if ( TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_PARTY_AROUND_CASTER ||
TempSpell->EffectImplicitTargetA[j] == TARGET_AREAEFFECT_PARTY ||
- TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_AROUND_CASTER)
+ TempSpell->EffectImplicitTargetA[j] == TARGET_DEST_CASTER)
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_AOE_FRIEND-1);
//Spell targets any friend(or self)
@@ -631,7 +629,7 @@ void FillSpellSummary()
TempSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_PARTY ||
TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_PARTY_AROUND_CASTER ||
TempSpell->EffectImplicitTargetA[j] == TARGET_AREAEFFECT_PARTY ||
- TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_AROUND_CASTER)
+ TempSpell->EffectImplicitTargetA[j] == TARGET_DEST_CASTER)
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_ANY_FRIEND-1);
//Make sure that this spell includes a damage effect
@@ -752,7 +750,7 @@ Unit* FindCreature(uint32 entry, float range, Unit* Finder)
return NULL;
Creature* target = NULL;
Trinity::AllCreaturesOfEntryInRange check(Finder, entry, range);
- Trinity::CreatureSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(target, check);
+ Trinity::CreatureSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(Finder, target, check);
Finder->VisitNearbyObject(range, searcher);
return target;
}
@@ -763,7 +761,7 @@ GameObject* FindGameObject(uint32 entry, float range, Unit* Finder)
return NULL;
GameObject* target = NULL;
Trinity::AllGameObjectsWithEntryInGrid go_check(entry);
- Trinity::GameObjectSearcher<Trinity::AllGameObjectsWithEntryInGrid> searcher(target, go_check);
+ Trinity::GameObjectSearcher<Trinity::AllGameObjectsWithEntryInGrid> searcher(Finder, target, go_check);
Finder->VisitNearbyGridObject(range, searcher);
return target;
}
@@ -772,7 +770,7 @@ Unit* ScriptedAI::DoSelectLowestHpFriendly(float range, uint32 MinHPDiff)
{
Unit* pUnit = NULL;
Trinity::MostHPMissingInRange u_check(m_creature, range, MinHPDiff);
- Trinity::UnitLastSearcher<Trinity::MostHPMissingInRange> searcher(pUnit, u_check);
+ Trinity::UnitLastSearcher<Trinity::MostHPMissingInRange> searcher(m_creature, pUnit, u_check);
m_creature->VisitNearbyObject(range, searcher);
return pUnit;
}
@@ -781,7 +779,7 @@ std::list<Creature*> ScriptedAI::DoFindFriendlyCC(float range)
{
std::list<Creature*> pList;
Trinity::FriendlyCCedInRange u_check(m_creature, range);
- Trinity::CreatureListSearcher<Trinity::FriendlyCCedInRange> searcher(pList, u_check);
+ Trinity::CreatureListSearcher<Trinity::FriendlyCCedInRange> searcher(m_creature, pList, u_check);
m_creature->VisitNearbyObject(range, searcher);
return pList;
}
@@ -790,7 +788,7 @@ std::list<Creature*> ScriptedAI::DoFindFriendlyMissingBuff(float range, uint32 s
{
std::list<Creature*> pList;
Trinity::FriendlyMissingBuffInRange u_check(m_creature, range, spellid);
- Trinity::CreatureListSearcher<Trinity::FriendlyMissingBuffInRange> searcher(pList, u_check);
+ Trinity::CreatureListSearcher<Trinity::FriendlyMissingBuffInRange> searcher(m_creature, pList, u_check);
m_creature->VisitNearbyObject(range, searcher);
return pList;
}
diff --git a/src/bindings/scripts/include/sc_creature.h b/src/bindings/scripts/include/sc_creature.h
index aadfdd3d19f..866007cc52a 100644
--- a/src/bindings/scripts/include/sc_creature.h
+++ b/src/bindings/scripts/include/sc_creature.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+/* Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
* Thanks to the original authors: ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
diff --git a/src/bindings/scripts/include/sc_gossip.h b/src/bindings/scripts/include/sc_gossip.h
index ec4ba0ae3f9..ead61740cdf 100644
--- a/src/bindings/scripts/include/sc_gossip.h
+++ b/src/bindings/scripts/include/sc_gossip.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+/* Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
* Thanks to the original authors: ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
diff --git a/src/bindings/scripts/scripts/npc/npcs_special.cpp b/src/bindings/scripts/scripts/npc/npcs_special.cpp
index d0131bf4067..ba315b6f866 100644
--- a/src/bindings/scripts/scripts/npc/npcs_special.cpp
+++ b/src/bindings/scripts/scripts/npc/npcs_special.cpp
@@ -351,7 +351,7 @@ struct TRINITY_DLL_DECL npc_injured_patientAI : public ScriptedAI
//no regen health
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
//to make them lay with face down
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_DEAD);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_DEAD);
uint32 mobId = m_creature->GetEntry();
@@ -392,7 +392,7 @@ struct TRINITY_DLL_DECL npc_injured_patientAI : public ScriptedAI
//regen health
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
//stand up
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_NONE);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_STAND);
DoSay(SAY_DOC1,LANG_UNIVERSAL,NULL);
uint32 mobId = m_creature->GetEntry();
diff --git a/src/bindings/scripts/scripts/zone/azuremyst_isle/azuremyst_isle.cpp b/src/bindings/scripts/scripts/zone/azuremyst_isle/azuremyst_isle.cpp
index d1acc9373c4..90bbaac9705 100644
--- a/src/bindings/scripts/scripts/zone/azuremyst_isle/azuremyst_isle.cpp
+++ b/src/bindings/scripts/scripts/zone/azuremyst_isle/azuremyst_isle.cpp
@@ -562,7 +562,7 @@ struct TRINITY_DLL_DECL npc_geezleAI : public ScriptedAI
cell.SetNoCreate();
Trinity::AllGameObjectsWithEntryInGrid go_check(GO_NAGA_FLAG);
- Trinity::GameObjectListSearcher<Trinity::AllGameObjectsWithEntryInGrid> go_search(FlagList, go_check);
+ Trinity::GameObjectListSearcher<Trinity::AllGameObjectsWithEntryInGrid> go_search(m_creature, FlagList, go_check);
TypeContainerVisitor
<Trinity::GameObjectListSearcher<Trinity::AllGameObjectsWithEntryInGrid>, GridTypeMapContainer> go_visit(go_search);
CellLock<GridReadGuard> cell_lock(cell, pair);
diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp
index 813705739a5..4c796293aa3 100644
--- a/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp
+++ b/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp
@@ -137,6 +137,9 @@ EndScriptData */
#define FLAME_ENRAGE_DISTANCE 30
#define FLAME_CHARGE_DISTANCE 50
+#define ITEM_ID_MAIN_HAND 32837
+#define ITEM_ID_OFF_HAND 32838
+
/**** Creature Summon and Recognition IDs ****/
enum CreatureEntry
{
@@ -454,7 +457,7 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI
{
GameObject* Door = GameObject::GetGameObject((*m_creature), pInstance->GetData64(i));
if(Door)
- Door->SetUInt32Value(GAMEOBJECT_STATE, 0); // Open Doors
+ Door->SetGoState(0); // Open Doors
}
}
@@ -487,10 +490,10 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI
{
if(spell->Id == SPELL_GLAIVE_RETURNS) // Re-equip our warblades!
{
- if(!m_creature->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY))
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479);
+ if(!m_creature->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID))
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 45479);
else
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 45481);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 45481);
m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE );
}
}
@@ -567,8 +570,8 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI
Timer[EVENT_FLIGHT_SEQUENCE] = 700;
break;
case 4://throw another
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);
{
uint8 i=0;
Creature* Glaive = m_creature->SummonCreature(BLADE_OF_AZZINOTH, GlaivePosition[i].x, GlaivePosition[i].y, GlaivePosition[i].z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
@@ -653,14 +656,14 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI
if(DemonTransformation[TransformCount].equip)
{
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479); // Requip warglaives if needed
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 45481);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 45479); // Requip warglaives if needed
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 45481);
m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE );
}
else
{
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0); // Unequip warglaives if needed
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+0, 0); // Unequip warglaives if needed
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);
}
switch(TransformCount)
@@ -999,10 +1002,10 @@ struct TRINITY_DLL_DECL npc_akama_illidanAI : public ScriptedAI
DoorGUID[1] = pInstance->GetData64(DATA_GAMEOBJECT_ILLIDAN_DOOR_L);
if(GETGO(Gate, GateGUID))
- Gate->SetUInt32Value(GAMEOBJECT_STATE, 1);
+ Gate->SetGoState(1);
for(uint8 i = 0; i < 2; i++)
if(GETGO(Door, DoorGUID[i]))
- Door->SetUInt32Value(GAMEOBJECT_STATE, 1);
+ Door->SetGoState(1);
}
else
{
@@ -1072,7 +1075,7 @@ struct TRINITY_DLL_DECL npc_akama_illidanAI : public ScriptedAI
for(uint8 i = 0; i < 2; i++)
if(GETGO(Door, DoorGUID[i]))
- Door->SetUInt32Value(GAMEOBJECT_STATE, 1);
+ Door->SetGoState(1);
if(GETCRE(Illidan, IllidanGUID))
{
@@ -1238,7 +1241,7 @@ struct TRINITY_DLL_DECL npc_akama_illidanAI : public ScriptedAI
Spirit[0]->InterruptNonMeleeSpells(true);
Spirit[1]->InterruptNonMeleeSpells(true);
if(GETGO(Gate, GateGUID))
- Gate->SetUInt32Value(GAMEOBJECT_STATE, 0);
+ Gate->SetGoState(0);
Timer = 2000;
break;
case 4:
@@ -1269,7 +1272,7 @@ struct TRINITY_DLL_DECL npc_akama_illidanAI : public ScriptedAI
case 6:
for(uint8 i = 0; i < 2; i++)
if(GETGO(Door, DoorGUID[i]))
- Door->SetUInt32Value(GAMEOBJECT_STATE, 0);
+ Door->SetGoState(0);
break;
case 8:
if(Phase == PHASE_WALK)
@@ -1379,9 +1382,9 @@ struct TRINITY_DLL_DECL boss_maievAI : public ScriptedAI
Timer[EVENT_MAIEV_STEALTH] = 0;
Timer[EVENT_MAIEV_TAUNT] = 22000 + rand()%21 * 1000;
Timer[EVENT_MAIEV_SHADOW_STRIKE] = 30000;
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 44850);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 1, 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 2, 45738);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 44850);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, 45738);
}
void Aggro(Unit *who) {}
@@ -1659,7 +1662,7 @@ bool GOHello_cage_trap(Player* plr, GameObject* go)
// Grid search for nearest live creature of entry 23304 within 10 yards
Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck check(*plr, 23304, true, 10);
- Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(trigger, check);
+ Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(plr, trigger, check);
TypeContainerVisitor<Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck>, GridTypeMapContainer> cSearcher(searcher);
@@ -1667,7 +1670,7 @@ bool GOHello_cage_trap(Player* plr, GameObject* go)
cell_lock->Visit(cell_lock, cSearcher, *(plr->GetMap()));
((cage_trap_triggerAI*)trigger->AI())->Active = true;
- go->SetUInt32Value(GAMEOBJECT_STATE, 0);
+ go->SetGoState(0);
return true;
}
@@ -1831,8 +1834,8 @@ void boss_illidan_stormrageAI::Reset()
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);
m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING + MOVEMENTFLAG_ONTRANSPORT);
m_creature->setActive(false);
Summons.DespawnAll();
@@ -1889,8 +1892,8 @@ void boss_illidan_stormrageAI::HandleTalkSequence()
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
break;
case 8:
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479); // Equip our warglaives!
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 45481);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 45479); // Equip our warglaives!
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 45481);
m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE );
m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
break;
@@ -1950,7 +1953,7 @@ void boss_illidan_stormrageAI::HandleTalkSequence()
{
Maiev->CastSpell(Maiev, SPELL_TELEPORT_VISUAL, true);
Maiev->setDeathState(JUST_DIED);
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,PLAYER_STATE_DEAD);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,UNIT_STAND_STATE_DEAD);
}
break;
case 21: // Kill ourself.
diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_shade_of_akama.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_shade_of_akama.cpp
index d2b2da6d866..7315c7b3490 100644
--- a/src/bindings/scripts/scripts/zone/black_temple/boss_shade_of_akama.cpp
+++ b/src/bindings/scripts/scripts/zone/black_temple/boss_shade_of_akama.cpp
@@ -346,7 +346,7 @@ struct TRINITY_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI
std::list<Creature*> ChannelerList;
Trinity::AllCreaturesOfEntryInRange check(m_creature, CREATURE_CHANNELER, 50);
- Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(ChannelerList, check);
+ Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(m_creature, ChannelerList, check);
TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange>, GridTypeMapContainer> visitor(searcher);
CellLock<GridReadGuard> cell_lock(cell, pair);
diff --git a/src/bindings/scripts/scripts/zone/blades_edge_mountains/blades_edge_mountains.cpp b/src/bindings/scripts/scripts/zone/blades_edge_mountains/blades_edge_mountains.cpp
index 8b08011bc8a..f56bd53e8fa 100644
--- a/src/bindings/scripts/scripts/zone/blades_edge_mountains/blades_edge_mountains.cpp
+++ b/src/bindings/scripts/scripts/zone/blades_edge_mountains/blades_edge_mountains.cpp
@@ -17,7 +17,7 @@
/* ScriptData
SDName: Blades_Edge_Mountains
SD%Complete: 90
-SDComment: Quest support: 10503, 10504, 10556, 10609, 10682, 10980. Ogri'la->Skettis Flight. (npc_daranelle needs bit more work before consider complete)
+SDComment: Quest support: 10503, 10504, 10556, 10609, 10682, 10821, 10980. Ogri'la->Skettis Flight. (npc_daranelle needs bit more work before consider complete)
SDCategory: Blade's Edge Mountains
EndScriptData */
@@ -28,10 +28,20 @@ npc_daranelle
npc_overseer_nuaar
npc_saikkal_the_elder
npc_skyguard_handler_irena
+go_legion_obelisk
EndContentData */
#include "precompiled.h"
+//Support for quest: You're Fired! (10821)
+bool obelisk_one, obelisk_two, obelisk_three, obelisk_four, obelisk_five;
+
+#define LEGION_OBELISK_ONE 185193
+#define LEGION_OBELISK_TWO 185195
+#define LEGION_OBELISK_THREE 185196
+#define LEGION_OBELISK_FOUR 185197
+#define LEGION_OBELISK_FIVE 185198
+
/*######
## mobs_bladespire_ogre
######*/
@@ -392,6 +402,48 @@ bool GossipSelect_npc_skyguard_handler_irena(Player *player, Creature *_Creature
}
/*######
+## go_legion_obelisk
+######*/
+
+bool GOHello_go_legion_obelisk(Player *player, GameObject* _GO)
+{
+ if ( player->GetQuestStatus(10821) == QUEST_STATUS_INCOMPLETE )
+ {
+ switch( _GO->GetEntry() )
+ {
+ case LEGION_OBELISK_ONE:
+ obelisk_one = true;
+ break;
+ case LEGION_OBELISK_TWO:
+ obelisk_two = true;
+ break;
+ case LEGION_OBELISK_THREE:
+ obelisk_three = true;
+ break;
+ case LEGION_OBELISK_FOUR:
+ obelisk_four = true;
+ break;
+ case LEGION_OBELISK_FIVE:
+ obelisk_five = true;
+ break;
+ }
+
+ if ( obelisk_one == true && obelisk_two == true && obelisk_three == true && obelisk_four == true && obelisk_five == true )
+ {
+ _GO->SummonCreature(19963,2943.40f,4778.20f,284.49f,0.94f,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,120000);
+ //reset global var
+ obelisk_one = false;
+ obelisk_two = false;
+ obelisk_three = false;
+ obelisk_four = false;
+ obelisk_five = false;
+ }
+ }
+
+ return true;
+}
+
+/*######
## AddSC
######*/
@@ -425,6 +477,11 @@ void AddSC_blades_edge_mountains()
newscript->pGossipHello = &GossipHello_npc_saikkal_the_elder;
newscript->pGossipSelect = &GossipSelect_npc_saikkal_the_elder;
newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="go_legion_obelisk";
+ newscript->pGOHello = &GOHello_go_legion_obelisk;
+ newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_skyguard_handler_irena";
diff --git a/src/bindings/scripts/scripts/zone/bloodmyst_isle/bloodmyst_isle.cpp b/src/bindings/scripts/scripts/zone/bloodmyst_isle/bloodmyst_isle.cpp
index f298f3fa22a..3c3a622b49d 100644
--- a/src/bindings/scripts/scripts/zone/bloodmyst_isle/bloodmyst_isle.cpp
+++ b/src/bindings/scripts/scripts/zone/bloodmyst_isle/bloodmyst_isle.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* 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
diff --git a/src/bindings/scripts/scripts/zone/borean_tundra/borean_tundra.cpp b/src/bindings/scripts/scripts/zone/borean_tundra/borean_tundra.cpp
new file mode 100644
index 00000000000..c776c1f9271
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/borean_tundra/borean_tundra.cpp
@@ -0,0 +1,105 @@
+/* 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Borean_Tundra
+SD%Complete: 100
+SDComment:
+SDCategory: Borean Tundra
+EndScriptData */
+
+/* ContentData
+npc_tiare
+npc_surristrasz
+EndContentData */
+
+#include "precompiled.h"
+
+/*######
+## npc_tiare
+######*/
+
+#define GOSSIP_ITEM_TELEPORT "Teleport me to Amber Ledge, please."
+
+bool GossipHello_npc_tiare(Player *player, Creature *_Creature)
+{
+ player->ADD_GOSSIP_ITEM(0, GOSSIP_ITEM_TELEPORT, GOSSIP_SENDER_MAIN, GOSSIP_OPTION_GOSSIP);
+ player->SEND_GOSSIP_MENU(_Creature->GetNpcTextId(), _Creature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_tiare(Player *player, Creature *_Creature, uint32 sender, uint32 action)
+{
+ if (action == GOSSIP_OPTION_GOSSIP)
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->CastSpell(player,50135,true);
+ }
+ return true;
+}
+
+/*######
+## npc_surristrasz
+######*/
+
+#define GOSSIP_ITEM_FREE_FLIGHT "I'd like passage to the Transitus Shield."
+#define GOSSIP_ITEM_FLIGHT "May I use a drake to fly elsewhere?"
+
+bool GossipHello_npc_surristrasz(Player *player, Creature *_Creature)
+{
+ if (_Creature->isQuestGiver())
+ player->PrepareQuestMenu(_Creature->GetGUID());
+
+ if (_Creature->isTaxi())
+ {
+ player->ADD_GOSSIP_ITEM(0, GOSSIP_ITEM_FREE_FLIGHT, GOSSIP_SENDER_MAIN, GOSSIP_OPTION_GOSSIP);
+ player->ADD_GOSSIP_ITEM(2, GOSSIP_ITEM_FLIGHT, GOSSIP_SENDER_MAIN, GOSSIP_OPTION_TAXIVENDOR);
+ }
+
+ player->SEND_GOSSIP_MENU(_Creature->GetNpcTextId(), _Creature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_surristrasz(Player *player, Creature *_Creature, uint32 sender, uint32 action)
+{
+ if (action == GOSSIP_OPTION_GOSSIP)
+ {
+ player->CLOSE_GOSSIP_MENU();
+ player->CastSpell(player,46064,true); //TaxiPath 795 (amber to coldarra)
+ }
+ if (action == GOSSIP_OPTION_TAXIVENDOR)
+ {
+ player->GetSession()->SendTaxiMenu(_Creature);
+ }
+ return true;
+}
+
+void AddSC_borean_tundra()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_tiare";
+ newscript->pGossipHello = &GossipHello_npc_tiare;
+ newscript->pGossipSelect = &GossipSelect_npc_tiare;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_surristrasz";
+ newscript->pGossipHello = &GossipHello_npc_surristrasz;
+ newscript->pGossipSelect = &GossipSelect_npc_surristrasz;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp
index 8b3eb0525dc..6e1e028cc70 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp
@@ -324,7 +324,7 @@ void hyjalAI::Retreat()
// First get all creatures.
std::list<Creature*> creatures;
Trinity::AllFriendlyCreaturesInGrid creature_check(m_creature);
- Trinity::CreatureListSearcher<Trinity::AllFriendlyCreaturesInGrid> creature_searcher(creatures, creature_check);
+ Trinity::CreatureListSearcher<Trinity::AllFriendlyCreaturesInGrid> creature_searcher(m_creature, creatures, creature_check);
TypeContainerVisitor
<Trinity::CreatureListSearcher<Trinity::AllFriendlyCreaturesInGrid>,
GridTypeMapContainer> creature_visitor(creature_searcher);
@@ -332,7 +332,7 @@ void hyjalAI::Retreat()
// Then get all Ancient Gem Veins. NOTE: Grid Search will only be able to find those in the grid.
std::list<GameObject*> goList;
Trinity::AllGameObjectsWithEntryInGrid go_check(185557);
- Trinity::GameObjectListSearcher<Trinity::AllGameObjectsWithEntryInGrid> go_search(goList, go_check);
+ Trinity::GameObjectListSearcher<Trinity::AllGameObjectsWithEntryInGrid> go_search(m_creature, goList, go_check);
TypeContainerVisitor
<Trinity::GameObjectListSearcher<Trinity::AllGameObjectsWithEntryInGrid>, GridTypeMapContainer> go_visit(go_search);
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp
index e3aeaf55605..11462385674 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp
@@ -235,12 +235,12 @@ struct TRINITY_DLL_DECL npc_thrall_old_hillsbradAI : public npc_escortAI
case 9:
DoScriptText(SAY_TH_ARMORY, m_creature);
m_creature->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, THRALL_WEAPON_MODEL);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, THRALL_WEAPON_INFO);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+1, 781);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, THRALL_SHIELD_MODEL);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, THRALL_SHIELD_INFO);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+3, 1038);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, THRALL_WEAPON_MODEL);
+ //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, THRALL_WEAPON_INFO);
+ //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+1, 781);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, THRALL_SHIELD_MODEL);
+ //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, THRALL_SHIELD_INFO);
+ //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+3, 1038);
break;
case 10:
m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, THRALL_MODEL_EQUIPPED);
@@ -399,12 +399,8 @@ struct TRINITY_DLL_DECL npc_thrall_old_hillsbradAI : public npc_escortAI
{
DoUnmount();
HadMount = false;
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+1, 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+3, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);
m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, THRALL_MODEL_UNEQUIPPED);
}
if( IsBeingEscorted )
diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp
index 1643f1068cf..4827de39a7a 100644
--- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp
+++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp
@@ -198,8 +198,8 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI
m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true);
m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_NIGHTELF);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY , 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID , 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);
m_creature->CastSpell(m_creature, SPELL_DUAL_WIELD, true);
m_creature->SetCorpseDelay(1000*60*60);
if(pInstance)
@@ -277,7 +277,7 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI
m_creature->RemoveAurasDueToSpell(AURA_BANISH);
// Leotheras is getting immune again
- m_creature->ApplySpellImmune(AURA_BANISH, IMMUNITY_MECHANIC, MECHANIC_BANISH, true);
+ m_creature->ApplySpellImmune(AURA_BANISH, IMMUNITY_MECHANIC, 1<<MECHANIC_BANISH, true);
// changing model to bloodelf
m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_NIGHTELF);
@@ -298,15 +298,15 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI
{
// channelers != 0 apply banish aura
// removing Leotheras banish immune to apply AURA_BANISH
- m_creature->ApplySpellImmune(AURA_BANISH, IMMUNITY_MECHANIC, MECHANIC_BANISH, false);
+ m_creature->ApplySpellImmune(AURA_BANISH, IMMUNITY_MECHANIC, 1<<MECHANIC_BANISH, false);
DoCast(m_creature, AURA_BANISH);
// changing model
m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_DEMON);
// and removing weapons
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY , 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID , 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);
}
}
@@ -469,8 +469,8 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI
m_creature->RemoveAurasDueToSpell(SPELL_WHIRLWIND,0);
m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_DEMON);
DoScriptText(SAY_SWITCH_TO_DEMON, m_creature);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY , 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID , 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);
DemonForm = true;
NeedThreatReset = true;
SwitchToDemon_Timer = 45000;
diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp
index 919a455bb79..5b4085335c3 100644
--- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp
+++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp
@@ -137,7 +137,7 @@ struct TRINITY_DLL_DECL instance_serpentshrine_cavern : public ScriptedInstance
void OpenDoor(uint64 DoorGUID, bool open)
{
if(GameObject *Door = instance->GetGameObjectInMap(DoorGUID))
- Door->SetUInt32Value(GAMEOBJECT_STATE, open ? 0 : 1);
+ Door->SetGoState(open ? 0 : 1);
}
void OnCreatureCreate(Creature *creature, uint32 creature_entry)
diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/boss_warlord_kalithresh.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/boss_warlord_kalithresh.cpp
index efa5cf72eaa..23985bdbdff 100644
--- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/boss_warlord_kalithresh.cpp
+++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/boss_warlord_kalithresh.cpp
@@ -145,7 +145,7 @@ struct TRINITY_DLL_DECL boss_warlord_kalithreshAI : public ScriptedAI
cell.SetNoCreate();
Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck creature_check(*m_creature, entry, true, range);
- Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(pCreature, creature_check);
+ Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(m_creature, pCreature, creature_check);
TypeContainerVisitor<Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck>, GridTypeMapContainer> creature_searcher(searcher);
diff --git a/src/bindings/scripts/scripts/zone/deadmines/deadmines.cpp b/src/bindings/scripts/scripts/zone/deadmines/deadmines.cpp
index 4bd33af98df..dfa3540857e 100644
--- a/src/bindings/scripts/scripts/zone/deadmines/deadmines.cpp
+++ b/src/bindings/scripts/scripts/zone/deadmines/deadmines.cpp
@@ -120,13 +120,13 @@ struct TRINITY_DLL_DECL instance_deadmines : public ScriptedInstance
void ShootCannon()
{
- DefiasCannon->SetUInt32Value(GAMEOBJECT_STATE, 0);
+ DefiasCannon->SetGoState(0);
DoPlaySound(DefiasCannon, SOUND_CANNONFIRE);
}
void BlastOutDoor()
{
- IronCladDoor->SetUInt32Value(GAMEOBJECT_STATE, 2);
+ IronCladDoor->SetGoState(2);
DoPlaySound(IronCladDoor, SOUND_DESTROYDOOR);
}
diff --git a/src/bindings/scripts/scripts/zone/eastern_plaguelands/eastern_plaguelands.cpp b/src/bindings/scripts/scripts/zone/eastern_plaguelands/eastern_plaguelands.cpp
index 44abf0da806..f0b073f5aa0 100644
--- a/src/bindings/scripts/scripts/zone/eastern_plaguelands/eastern_plaguelands.cpp
+++ b/src/bindings/scripts/scripts/zone/eastern_plaguelands/eastern_plaguelands.cpp
@@ -118,7 +118,7 @@ bool GossipHello_npc_tirion_fordring(Player *player, Creature *_Creature)
if (_Creature->isQuestGiver())
player->PrepareQuestMenu( _Creature->GetGUID() );
- if (player->GetQuestStatus(5742) == QUEST_STATUS_INCOMPLETE && player->getStandState() == PLAYER_STATE_SIT )
+ if (player->GetQuestStatus(5742) == QUEST_STATUS_INCOMPLETE && player->getStandState() == UNIT_STAND_STATE_SIT )
player->ADD_GOSSIP_ITEM( 0, "I am ready to hear your tale, Tirion.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
player->SEND_GOSSIP_MENU(_Creature->GetNpcTextId(), _Creature->GetGUID());
diff --git a/src/bindings/scripts/scripts/zone/eversong_woods/eversong_woods.cpp b/src/bindings/scripts/scripts/zone/eversong_woods/eversong_woods.cpp
index 1aa7a6259d9..a0f0c57fdf9 100644
--- a/src/bindings/scripts/scripts/zone/eversong_woods/eversong_woods.cpp
+++ b/src/bindings/scripts/scripts/zone/eversong_woods/eversong_woods.cpp
@@ -229,7 +229,7 @@ struct TRINITY_DLL_DECL npc_secondTrialAI : public ScriptedAI
questPhase = 0;
summonerGuid = 0;
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_KNEEL);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_KNEEL);
m_creature->setFaction(FACTION_FRIENDLY);
spellFlashLight = false;
@@ -268,7 +268,7 @@ struct TRINITY_DLL_DECL npc_secondTrialAI : public ScriptedAI
if ( questPhase == 1 ) {
if ( timer < diff ) {
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_NONE);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_STAND);
m_creature->setFaction(FACTION_HOSTILE);
questPhase = 0;
@@ -539,7 +539,7 @@ bool GOHello_go_second_trial(Player *player, GameObject* _GO)
Creature* event_controller = NULL;
Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*_GO, MASTER_KELERUN_BLOODMOURN, true, 30);
- Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(event_controller, u_check);
+ Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(player, event_controller, u_check);
TypeContainerVisitor<Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck>, GridTypeMapContainer > grid_unit_searcher(searcher);
//cell_lock->Visit(cell_lock, grid_unit_searcher, *MapManager::Instance().GetMap(_GO->GetMap(), _GO));
cell_lock->Visit(cell_lock, grid_unit_searcher, *(_GO->GetMap()));
diff --git a/src/bindings/scripts/scripts/zone/gruuls_lair/boss_high_king_maulgar.cpp b/src/bindings/scripts/scripts/zone/gruuls_lair/boss_high_king_maulgar.cpp
index e0d3aea7d06..63f9becac3f 100644
--- a/src/bindings/scripts/scripts/zone/gruuls_lair/boss_high_king_maulgar.cpp
+++ b/src/bindings/scripts/scripts/zone/gruuls_lair/boss_high_king_maulgar.cpp
@@ -238,8 +238,8 @@ struct TRINITY_DLL_DECL boss_high_king_maulgarAI : public ScriptedAI
DoScriptText(SAY_ENRAGE, m_creature);
m_creature->CastSpell(m_creature, SPELL_DUAL_WIELD, true);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);
}
if(Phase2)
diff --git a/src/bindings/scripts/scripts/zone/karazhan/boss_nightbane.cpp b/src/bindings/scripts/scripts/zone/karazhan/boss_nightbane.cpp
index 1a3c6684bbd..cc0645ce47d 100644
--- a/src/bindings/scripts/scripts/zone/karazhan/boss_nightbane.cpp
+++ b/src/bindings/scripts/scripts/zone/karazhan/boss_nightbane.cpp
@@ -136,9 +136,9 @@ struct TRINITY_DLL_DECL boss_nightbaneAI : public ScriptedAI
void HandleTerraceDoors(bool open)
{
if(GameObject *Door = GameObject::GetGameObject((*m_creature),pInstance->GetData64(DATA_MASTERS_TERRACE_DOOR_1)))
- Door->SetUInt32Value(GAMEOBJECT_STATE, open ? 0 : 1);
+ Door->SetGoState(open ? 0 : 1);
if(GameObject *Door = GameObject::GetGameObject((*m_creature),pInstance->GetData64(DATA_MASTERS_TERRACE_DOOR_2)))
- Door->SetUInt32Value(GAMEOBJECT_STATE, open ? 0 : 1);
+ Door->SetGoState(open ? 0 : 1);
}
void Aggro(Unit *who)
diff --git a/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp b/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp
index 34a1114a12d..84dc686b73d 100644
--- a/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp
+++ b/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp
@@ -289,11 +289,11 @@ struct TRINITY_DLL_DECL boss_malchezaarAI : public ScriptedAI
void ClearWeapons()
{
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0);
+ //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);
+ //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, 0);
//damage
const CreatureInfo *cinfo = m_creature->GetCreatureInfo();
@@ -433,11 +433,11 @@ struct TRINITY_DLL_DECL boss_malchezaarAI : public ScriptedAI
m_creature->CastSpell(m_creature, SPELL_THRASH_AURA, true);
//models
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, AXE_EQUIP_MODEL);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, AXE_EQUIP_INFO);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, AXE_EQUIP_MODEL);
+ //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, AXE_EQUIP_INFO);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, AXE_EQUIP_MODEL);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, AXE_EQUIP_INFO);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, AXE_EQUIP_MODEL);
+ //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, AXE_EQUIP_INFO);
//damage
const CreatureInfo *cinfo = m_creature->GetCreatureInfo();
@@ -475,8 +475,8 @@ struct TRINITY_DLL_DECL boss_malchezaarAI : public ScriptedAI
Creature *axe = m_creature->SummonCreature(MALCHEZARS_AXE, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1000);
if(axe)
{
- axe->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, AXE_EQUIP_MODEL);
- axe->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, AXE_EQUIP_INFO);
+ axe->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, AXE_EQUIP_MODEL);
+ //axe->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, AXE_EQUIP_INFO);
axe->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
axe->setFaction(m_creature->getFaction());
diff --git a/src/bindings/scripts/scripts/zone/karazhan/bosses_opera.cpp b/src/bindings/scripts/scripts/zone/karazhan/bosses_opera.cpp
index 10828248927..b5dfc875984 100644
--- a/src/bindings/scripts/scripts/zone/karazhan/bosses_opera.cpp
+++ b/src/bindings/scripts/scripts/zone/karazhan/bosses_opera.cpp
@@ -905,7 +905,7 @@ void PretendToDie(Creature* _Creature)
_Creature->SetUInt64Value(UNIT_FIELD_TARGET,0);
_Creature->GetMotionMaster()->Clear();
_Creature->GetMotionMaster()->MoveIdle();
- _Creature->SetUInt32Value(UNIT_FIELD_BYTES_1,PLAYER_STATE_DEAD);
+ _Creature->SetUInt32Value(UNIT_FIELD_BYTES_1,UNIT_STAND_STATE_DEAD);
};
void Resurrect(Creature* target)
diff --git a/src/bindings/scripts/scripts/zone/nagrand/nagrand.cpp b/src/bindings/scripts/scripts/zone/nagrand/nagrand.cpp
index 3ee4f06d629..92b179eefec 100644
--- a/src/bindings/scripts/scripts/zone/nagrand/nagrand.cpp
+++ b/src/bindings/scripts/scripts/zone/nagrand/nagrand.cpp
@@ -125,7 +125,7 @@ struct TRINITY_DLL_DECL mob_lumpAI : public ScriptedAI
m_creature->DeleteThreatList();
m_creature->CombatStop();
m_creature->setFaction(1080); //friendly
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_SIT);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_SIT);
DoScriptText(LUMP_DEFEAT, m_creature);
bReset = true;
@@ -139,7 +139,7 @@ struct TRINITY_DLL_DECL mob_lumpAI : public ScriptedAI
m_creature->RemoveAura(SPELL_VISUAL_SLEEP,0);
if (!m_creature->IsStandState())
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_NONE);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_STAND);
switch(rand()%2)
{
diff --git a/src/bindings/scripts/scripts/zone/netherstorm/netherstorm.cpp b/src/bindings/scripts/scripts/zone/netherstorm/netherstorm.cpp
index fc27da1b649..20eb88a538b 100644
--- a/src/bindings/scripts/scripts/zone/netherstorm/netherstorm.cpp
+++ b/src/bindings/scripts/scripts/zone/netherstorm/netherstorm.cpp
@@ -404,7 +404,7 @@ struct TRINITY_DLL_DECL npc_commander_dawnforgeAI : public ScriptedAI
cell.SetNoCreate();
Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck creature_check(*m_creature, entry, true, range);
- Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(pCreature, creature_check);
+ Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(m_creature, pCreature, creature_check);
TypeContainerVisitor<Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck>, GridTypeMapContainer> creature_searcher(searcher);
@@ -441,8 +441,8 @@ struct TRINITY_DLL_DECL npc_commander_dawnforgeAI : public ScriptedAI
ardonis->SendUpdateToPlayer(player);
//Set them to kneel
- m_creature->SetStandState(PLAYER_STATE_KNEEL);
- ardonis->SetStandState(PLAYER_STATE_KNEEL);
+ m_creature->SetStandState(UNIT_STAND_STATE_KNEEL);
+ ardonis->SetStandState(UNIT_STAND_STATE_KNEEL);
}
//Set them back to each other
@@ -466,8 +466,8 @@ struct TRINITY_DLL_DECL npc_commander_dawnforgeAI : public ScriptedAI
ardonis->SendUpdateToPlayer(player);
//Set state
- m_creature->SetStandState(PLAYER_STATE_NONE);
- ardonis->SetStandState(PLAYER_STATE_NONE);
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
+ ardonis->SetStandState(UNIT_STAND_STATE_STAND);
}
}
@@ -639,7 +639,7 @@ Creature* SearchDawnforge(Player *source, uint32 entry, float range)
cell.SetNoCreate();
Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck creature_check(*source, entry, true, range);
- Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(pCreature, creature_check);
+ Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(source, pCreature, creature_check);
TypeContainerVisitor<Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck>, GridTypeMapContainer> creature_searcher(searcher);
diff --git a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_headless_horseman.cpp b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_headless_horseman.cpp
index 66270e79539..ac8d941fa07 100644
--- a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_headless_horseman.cpp
+++ b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_headless_horseman.cpp
@@ -573,7 +573,7 @@ struct TRINITY_DLL_DECL boss_headless_horsemanAI : public ScriptedAI
DoCast(m_creature,SPELL_BODY_REGEN,true);
m_creature->CastSpell(Head, SPELL_FLYING_HEAD,true);
DoCast(m_creature,SPELL_CONFUSE,false); //test
- done_by->ProcDamageAndSpell(m_creature,PROC_FLAG_KILL_AND_GET_XP,PROC_FLAG_KILLED,PROC_EX_NONE,0);
+ done_by->ProcDamageAndSpell(m_creature,PROC_FLAG_KILL,PROC_FLAG_KILLED,PROC_EX_NONE,0);
whirlwind = 4000 + (rand()%5)*1000;
regen = 0;
}
@@ -736,7 +736,7 @@ struct TRINITY_DLL_DECL mob_pulsing_pumpkinAI : public ScriptedAI
sprouted = false;
DoCast(m_creature,SPELL_PUMPKIN_AURA,true);
DoCast(m_creature,SPELL_SPROUTING);
- m_creature->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISABLE_ROTATE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_STUNNED);
}
void Aggro(Unit *who){}
@@ -747,7 +747,7 @@ struct TRINITY_DLL_DECL mob_pulsing_pumpkinAI : public ScriptedAI
{
sprouted = true;
m_creature->RemoveAllAuras();
- m_creature->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISABLE_ROTATE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_STUNNED);
DoCast(m_creature,SPELL_SPROUT_BODY,true);
m_creature->UpdateEntry(PUMPKIN_FIEND);
DoStartMovement(m_creature->getVictim());
diff --git a/src/bindings/scripts/scripts/zone/scarlet_monastery/instance_scarlet_monastery.cpp b/src/bindings/scripts/scripts/zone/scarlet_monastery/instance_scarlet_monastery.cpp
index 953ae804e39..1a94123f383 100644
--- a/src/bindings/scripts/scripts/zone/scarlet_monastery/instance_scarlet_monastery.cpp
+++ b/src/bindings/scripts/scripts/zone/scarlet_monastery/instance_scarlet_monastery.cpp
@@ -92,7 +92,7 @@ struct TRINITY_DLL_DECL instance_scarlet_monastery : public ScriptedInstance
{
GameObject *Shrine = instance->GetGameObjectInMap(PumpkinShrineGUID);
if(Shrine)
- Shrine->SetUInt32Value(GAMEOBJECT_STATE,1);
+ Shrine->SetGoState(1);
}break;
case DATA_HORSEMAN_EVENT:
if (data == DONE)
@@ -106,7 +106,7 @@ struct TRINITY_DLL_DECL instance_scarlet_monastery : public ScriptedInstance
HorsemanAdds.clear();
GameObject *Shrine = instance->GetGameObjectInMap(PumpkinShrineGUID);
if(Shrine)
- Shrine->SetUInt32Value(GAMEOBJECT_STATE,1);
+ Shrine->SetGoState(1);
}
break;
}
diff --git a/src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp b/src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp
index 6a11c455f67..b09cdce5c20 100644
--- a/src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp
+++ b/src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp
@@ -27,6 +27,7 @@ npc_bartleby
npc_dashel_stonefist
npc_general_marcus_jonathan
npc_lady_katrana_prestor
+npc_harbor_taxi
EndContentData */
#include "precompiled.h"
@@ -236,6 +237,28 @@ bool GossipSelect_npc_lady_katrana_prestor(Player *player, Creature *_Creature,
return true;
}
+/*######
+## npc_harbor_taxi
+######*/
+
+#define GOSSIP_STORMWIND "I'd like to take a flight around Stormwind Harbor."
+
+bool GossipHello_npc_stormwind_harbor_taxi(Player *player, Creature *_Creature)
+{
+ player->ADD_GOSSIP_ITEM(0, GOSSIP_STORMWIND, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 10);
+ player->SEND_GOSSIP_MENU(13454,_Creature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_stormwind_harbor_taxi(Player *player, Creature *_Creature, uint32 sender, uint32 action )
+{
+ if (action == GOSSIP_ACTION_INFO_DEF + 10)
+ {
+ player->GetSession()->SendDoFlight(1149, 1041);
+ }
+ return true;
+}
+
void AddSC_stormwind_city()
{
Script *newscript;
@@ -268,4 +291,10 @@ void AddSC_stormwind_city()
newscript->pGossipHello = &GossipHello_npc_lady_katrana_prestor;
newscript->pGossipSelect = &GossipSelect_npc_lady_katrana_prestor;
newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="npc_stormwind_harbor_taxi";
+ newscript->pGossipHello = &GossipHello_npc_stormwind_harbor_taxi;
+ newscript->pGossipSelect = &GossipSelect_npc_stormwind_harbor_taxi;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_felmyst.cpp b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_felmyst.cpp
index 4dea21dd771..8afba94fa44 100644
--- a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_felmyst.cpp
+++ b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_felmyst.cpp
@@ -493,7 +493,7 @@ struct TRINITY_DLL_DECL boss_felmystAI : public ScriptedAI
cell.SetNoCreate();
Trinity::AllCreaturesOfEntryInRange check(m_creature, entry, 100);
- Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(templist, check);
+ Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(m_creature, templist, check);
TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange>, GridTypeMapContainer> cSearcher(searcher);
diff --git a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kalecgos.cpp b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kalecgos.cpp
index 3c358c1f3b6..cab99d321f8 100644
--- a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kalecgos.cpp
+++ b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kalecgos.cpp
@@ -133,7 +133,7 @@ struct TRINITY_DLL_DECL boss_kalecgosAI : public ScriptedAI
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE);
m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
m_creature->SetVisibility(VISIBILITY_ON);
- m_creature->SetStandState(PLAYER_STATE_SLEEP);
+ m_creature->SetStandState(UNIT_STAND_STATE_SLEEP);
ArcaneBuffetTimer = 8000;
FrostBreathTimer = 15000;
@@ -158,7 +158,7 @@ struct TRINITY_DLL_DECL boss_kalecgosAI : public ScriptedAI
void Aggro(Unit* who)
{
- m_creature->SetStandState(PLAYER_STATE_NONE);
+ m_creature->SetStandState(UNIT_STAND_STATE_STAND);
DoScriptText(SAY_EVIL_AGGRO, m_creature);
GameObject *Door = GameObject::GetGameObject(*m_creature, DoorGUID);
if(Door) Door->SetLootState(GO_ACTIVATED);
diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp
index ec7036e4666..fed536832bf 100644
--- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp
@@ -228,12 +228,12 @@ struct TRINITY_DLL_DECL boss_alarAI : public ScriptedAI
WaitEvent = WE_DUMMY;
return;
case WE_DIE:
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_DEAD);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_DEAD);
WaitTimer = 5000;
WaitEvent = WE_REVIVE;
return;
case WE_REVIVE:
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_NONE);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_STAND);
m_creature->SetHealth(m_creature->GetMaxHealth());
m_creature->SetSpeed(MOVE_RUN, DefaultMoveSpeedRate);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp
index 2c9df9cb219..342363eb9b2 100644
--- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp
@@ -238,7 +238,7 @@ struct TRINITY_DLL_DECL advisorbase_ai : public ScriptedAI
m_creature->SetUInt64Value(UNIT_FIELD_TARGET,0);
m_creature->GetMotionMaster()->Clear();
m_creature->GetMotionMaster()->MoveIdle();
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,PLAYER_STATE_DEAD);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,UNIT_STAND_STATE_DEAD);
if (pInstance->GetData(DATA_KAELTHASEVENT) == 3)
JustDied(pKiller);
@@ -344,7 +344,7 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI
std::list<Creature*> PhoenixList;
Trinity::AllCreaturesOfEntryInRange check(m_creature, PHOENIX, 50);
- Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(PhoenixList, check);
+ Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(m_creature, PhoenixList, check);
TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange>, GridTypeMapContainer> visitor(searcher);
CellLock<GridReadGuard> cell_lock(cell, pair);
@@ -575,7 +575,7 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI
//Subphase 2 - Start
case 2:
Advisor = (Creature*)(Unit::GetUnit((*m_creature), AdvisorGuid[0]));
- if(Advisor && (Advisor->GetUInt32Value(UNIT_FIELD_BYTES_1) == PLAYER_STATE_DEAD))
+ if(Advisor && (Advisor->GetUInt32Value(UNIT_FIELD_BYTES_1) == UNIT_STAND_STATE_DEAD))
{
DoScriptText(SAY_INTRO_SANGUINAR, m_creature);
@@ -609,7 +609,7 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI
//Subphase 3 - Start
case 4:
Advisor = (Creature*)(Unit::GetUnit((*m_creature), AdvisorGuid[1]));
- if(Advisor && (Advisor->GetUInt32Value(UNIT_FIELD_BYTES_1) == PLAYER_STATE_DEAD))
+ if(Advisor && (Advisor->GetUInt32Value(UNIT_FIELD_BYTES_1) == UNIT_STAND_STATE_DEAD))
{
DoScriptText(SAY_INTRO_CAPERNIAN, m_creature);
@@ -643,7 +643,7 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI
//Subphase 4 - Start
case 6:
Advisor = (Creature*)(Unit::GetUnit((*m_creature), AdvisorGuid[2]));
- if(Advisor && (Advisor->GetUInt32Value(UNIT_FIELD_BYTES_1) == PLAYER_STATE_DEAD))
+ if(Advisor && (Advisor->GetUInt32Value(UNIT_FIELD_BYTES_1) == UNIT_STAND_STATE_DEAD))
{
DoScriptText(SAY_INTRO_TELONICUS, m_creature);
@@ -679,7 +679,7 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI
//End of phase 1
case 8:
Advisor = (Creature*)(Unit::GetUnit((*m_creature), AdvisorGuid[3]));
- if(Advisor && (Advisor->GetUInt32Value(UNIT_FIELD_BYTES_1) == PLAYER_STATE_DEAD))
+ if(Advisor && (Advisor->GetUInt32Value(UNIT_FIELD_BYTES_1) == UNIT_STAND_STATE_DEAD))
{
Phase = 2;
pInstance->SetData(DATA_KAELTHASEVENT, 2);
@@ -1467,7 +1467,7 @@ struct TRINITY_DLL_DECL mob_phoenix_tkAI : public ScriptedAI
if(SummonEgg == 1){ //hack die animation
m_creature->RemoveAllAuras();
DoStartNoMovement(m_creature->getVictim());
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_DEAD);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_DEAD);
SummonEgg = 2;
Cycle_Timer = 1000;
}
diff --git a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp
index 97a4e26536c..4223261f23e 100644
--- a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp
+++ b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp
@@ -336,7 +336,7 @@ struct TRINITY_DLL_DECL boss_twinemperorsAI : public ScriptedAI
std::list<Creature*> unitList;
AnyBugCheck u_check(m_creature, 150);
- Trinity::CreatureListSearcher<AnyBugCheck> searcher(unitList, u_check);
+ Trinity::CreatureListSearcher<AnyBugCheck> searcher(m_creature, unitList, u_check);
TypeContainerVisitor<Trinity::CreatureListSearcher<AnyBugCheck>, GridTypeMapContainer > grid_creature_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, grid_creature_searcher, *(m_creature->GetMap()));
diff --git a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp
index 913bf6d9c68..56a94c27272 100644
--- a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp
+++ b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp
@@ -175,7 +175,7 @@ struct TRINITY_DLL_DECL aqsentinelAI : public ScriptedAI
std::list<Creature*> assistList;
NearbyAQSentinel u_check(nears);
- Trinity::CreatureListSearcher<NearbyAQSentinel> searcher(assistList, u_check);
+ Trinity::CreatureListSearcher<NearbyAQSentinel> searcher(m_creature, assistList, u_check);
TypeContainerVisitor<Trinity::CreatureListSearcher<NearbyAQSentinel>, GridTypeMapContainer > grid_creature_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, grid_creature_searcher, *(nears->GetMap()));
diff --git a/src/bindings/scripts/scripts/zone/terokkar_forest/terokkar_forest.cpp b/src/bindings/scripts/scripts/zone/terokkar_forest/terokkar_forest.cpp
index 444e8b0a528..9bc5b231b7d 100644
--- a/src/bindings/scripts/scripts/zone/terokkar_forest/terokkar_forest.cpp
+++ b/src/bindings/scripts/scripts/zone/terokkar_forest/terokkar_forest.cpp
@@ -60,7 +60,7 @@ struct TRINITY_DLL_DECL mob_unkor_the_ruthlessAI : public ScriptedAI
CanDoQuest = false;
UnkorUnfriendly_Timer = 0;
Pulverize_Timer = 3000;
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_NONE);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_STAND);
m_creature->setFaction(FACTION_HOSTILE);
}
@@ -70,7 +70,7 @@ struct TRINITY_DLL_DECL mob_unkor_the_ruthlessAI : public ScriptedAI
{
DoScriptText(SAY_SUBMIT, m_creature);
m_creature->setFaction(FACTION_FRIENDLY);
- m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_SIT);
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_SIT);
m_creature->RemoveAllAuras();
m_creature->DeleteThreatList();
m_creature->CombatStop();
diff --git a/src/bindings/scripts/scripts/zone/tirisfal_glades/tirisfal_glades.cpp b/src/bindings/scripts/scripts/zone/tirisfal_glades/tirisfal_glades.cpp
index 779466f2863..3f42f65b7e7 100644
--- a/src/bindings/scripts/scripts/zone/tirisfal_glades/tirisfal_glades.cpp
+++ b/src/bindings/scripts/scripts/zone/tirisfal_glades/tirisfal_glades.cpp
@@ -100,7 +100,7 @@ GameObject* SearchMausoleumGo(Unit *source, uint32 entry, float range)
cell.SetNoCreate();
Trinity::NearestGameObjectEntryInObjectRangeCheck go_check(*source, entry, range);
- Trinity::GameObjectLastSearcher<Trinity::NearestGameObjectEntryInObjectRangeCheck> searcher(pGo, go_check);
+ Trinity::GameObjectLastSearcher<Trinity::NearestGameObjectEntryInObjectRangeCheck> searcher(source, pGo, go_check);
TypeContainerVisitor<Trinity::GameObjectLastSearcher<Trinity::NearestGameObjectEntryInObjectRangeCheck>, GridTypeMapContainer> go_searcher(searcher);
diff --git a/src/bindings/scripts/scripts/zone/uldaman/instance_uldaman.cpp b/src/bindings/scripts/scripts/zone/uldaman/instance_uldaman.cpp
index 08e1eeee423..bca17fcd031 100644
--- a/src/bindings/scripts/scripts/zone/uldaman/instance_uldaman.cpp
+++ b/src/bindings/scripts/scripts/zone/uldaman/instance_uldaman.cpp
@@ -70,7 +70,7 @@ struct TRINITY_DLL_DECL instance_uldaman : public ScriptedInstance
break;
case ANCIENT_VAULT_DOOR:
- go->SetUInt32Value(GAMEOBJECT_STATE,1);
+ go->SetGoState(1);
go->SetUInt32Value(GAMEOBJECT_FLAGS, 33);
ancientVaultDoor = go->GetGUID();
break;
@@ -93,7 +93,7 @@ struct TRINITY_DLL_DECL instance_uldaman : public ScriptedInstance
return;
go->SetUInt32Value(GAMEOBJECT_FLAGS, 33);
- go->SetUInt32Value(GAMEOBJECT_STATE, 0);
+ go->SetGoState(0);
}
void ActivateStoneKeepers()
diff --git a/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/boss_keleseth.cpp b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/boss_keleseth.cpp
new file mode 100644
index 00000000000..c9d40cc1b77
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/boss_keleseth.cpp
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2009 Trinity <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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Boss_Prince_Keleseth
+SD%Complete: 80
+SDComment: Normal and Heroic Support. Needs Prince Movements, Needs skeletons resurrection, Needs adjustments to blizzlike timers, Needs adjustments to use spell though. Needs Shadowbolt castbar
+SDCategory: Utgarde Keep
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_keep.h"
+
+#define SPELL_SHADOWBOLT 43667
+#define SPELL_SHADOWBOLT_HEROIC 59389
+#define SPELL_FROST_TOMB 48400
+#define SPELL_FROST_TOMB_SUMMON 42714
+#define CREATURE_FROSTTOMB 23965
+#define CREATURE_SKELETON 23970
+
+#define SAY_AGGRO -1574000
+#define SAY_KILL -1574001
+#define SAY_DEATH -1574002
+#define SAY_FROST_TOMB -1574003
+#define SAY_SKELETONS -1574004
+
+#define SKELETONSPAWN_Z 42.8668
+
+float SkeletonSpawnPoint[5][5]=
+{
+ {156.2559, 259.2093},
+ {156.2559, 259.2093},
+ {156.2559, 259.2093},
+ {156.2559, 259.2093},
+ {156.2559, 259.2093},
+};
+
+float AttackLoc[3]={197.636, 194.046, 40.8164};
+
+struct TRINITY_DLL_DECL mob_frost_tombAI : public ScriptedAI
+{
+ mob_frost_tombAI(Creature *c) : ScriptedAI(c)
+ {
+ Reset();
+ }
+
+ uint64 FrostTombGUID;
+
+ void Reset()
+ {
+ FrostTombGUID = 0;
+ }
+
+ void Aggro(Unit* who) {}
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+
+ void JustDied(Unit *killer)
+ {
+ if(FrostTombGUID)
+ {
+ Unit* FrostTomb = Unit::GetUnit((*m_creature),FrostTombGUID);
+ if(FrostTomb)
+ FrostTomb->RemoveAurasDueToSpell(SPELL_FROST_TOMB);
+ }
+ }
+};
+
+struct TRINITY_DLL_DECL boss_kelesethAI : public ScriptedAI
+{
+ boss_kelesethAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = ((ScriptedInstance*)c->GetInstanceData());
+ Reset();
+ Heroic = c->GetMap()->IsHeroic();
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 FrostTombTimer;
+ uint32 SummonSkeletonsTimer;
+ uint32 RespawnSkeletonsTimer;
+ uint32 ShadowboltTimer;
+ uint64 SkeletonGUID[5];
+ bool Skeletons;
+ bool Heroic;
+ bool RespawnSkeletons;
+
+ void Reset()
+ {
+ ShadowboltTimer = 0;
+ Skeletons = false;
+
+ ResetTimer();
+
+ if(pInstance)
+ pInstance->SetData(DATA_PRINCEKELESETH, NOT_STARTED);
+ }
+
+ void KilledUnit(Unit *victim)
+ {
+ if(victim == m_creature)
+ return;
+
+ DoScriptText(SAY_KILL, m_creature);
+ }
+
+ void JustDied(Unit* killer)
+ {
+ if(pInstance)
+ pInstance->SetData(DATA_PRINCEKELESETH, DONE);
+
+ DoScriptText(SAY_DEATH, m_creature);
+ }
+
+ void Aggro(Unit* who)
+ {
+ if(pInstance)
+ pInstance->SetData(DATA_PRINCEKELESETH, IN_PROGRESS);
+
+ DoScriptText(SAY_AGGRO, m_creature);
+ DoZoneInCombat();
+ }
+
+ void ResetTimer(uint32 inc = 0)
+ {
+ SummonSkeletonsTimer = 5000 + inc;
+ FrostTombTimer = 28000 + inc;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if(ShadowboltTimer < diff)
+ {
+ Unit* target = SelectUnit(SELECT_TARGET_TOPAGGRO, 0);
+ if(target && target->isAlive() && target->GetTypeId() == TYPEID_PLAYER)
+ m_creature->CastSpell(target, Heroic ? SPELL_SHADOWBOLT:SPELL_SHADOWBOLT_HEROIC, true);
+ ShadowboltTimer = 2000;
+ }else ShadowboltTimer -= diff;
+
+ if((SummonSkeletonsTimer < diff) && !Skeletons)
+ {
+ Creature* Skeleton;
+ DoScriptText(SAY_SKELETONS, m_creature);
+ for(uint8 i = 0; i < 5; ++i)
+ {
+ Skeleton = m_creature->SummonCreature(CREATURE_SKELETON, SkeletonSpawnPoint[i][0], SkeletonSpawnPoint[i][1] , SKELETONSPAWN_Z, 0, TEMPSUMMON_MANUAL_DESPAWN,0);
+ if(Skeleton)
+ {
+ Skeleton->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ Skeleton->GetMotionMaster()->MovePoint(0, m_creature->GetPositionX(), m_creature->GetPositionY() , m_creature->GetPositionZ());
+ Skeleton->AddThreat(m_creature, 0.0f);
+ DoZoneInCombat(Skeleton);
+ }
+ }
+ Skeletons = true;
+ }else SummonSkeletonsTimer -= diff;
+
+ if(FrostTombTimer < diff)
+ {
+ Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1);
+ if(target && target->isAlive() && target->GetTypeId() == TYPEID_PLAYER)
+ {
+ DoCast(target, SAY_FROST_TOMB, true);
+ Creature* Chains = m_creature->SummonCreature(CREATURE_FROSTTOMB, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 20000);
+ if(Chains)
+ {
+ ((mob_frost_tombAI*)Chains->AI())->FrostTombGUID = target->GetGUID();
+ Chains->CastSpell(target, SPELL_FROST_TOMB, true);
+
+ DoScriptText(SAY_FROST_TOMB, m_creature);
+
+ FrostTombTimer = 15000;
+ }
+ }
+ }else FrostTombTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_frost_tomb(Creature *_Creature)
+{
+ return new mob_frost_tombAI(_Creature);
+}
+
+CreatureAI* GetAI_boss_keleseth(Creature *_Creature)
+{
+ return new boss_kelesethAI (_Creature);
+}
+
+void AddSC_boss_keleseth()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_keleseth";
+ newscript->GetAI = &GetAI_boss_keleseth;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_frost_tomb";
+ newscript->GetAI = &GetAI_mob_frost_tomb;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/def_keep.h b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/def_keep.h
new file mode 100644
index 00000000000..4161c725fb2
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/def_keep.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2009 Trinity <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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef DEF_KEEP_H
+#define DEF_KEEP_H
+
+#define DATA_PRINCEKELESETH 1
+#define DATA_DALRON 2
+#define DATA_SKARVALD 3
+#define DATA_INGVAR 4
+#endif
diff --git a/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp
new file mode 100644
index 00000000000..77672143f24
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2009 Trinity <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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Instance_Utgarde_Keep
+SD%Complete: 0
+SDComment: Instance Data Scripts and functions to acquire mobs and set encounter status for use in various Utgarde Keep Scripts
+SDCategory: Utgarde Keep
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_keep.h"
+
+#define ENCOUNTERS 4
+
+/* Utgarde Keep encounters:
+0 - Prince Keleseth
+1 - Skarvald
+2 - Dalronn
+3 - Ingvar the Plunderer
+*/
+
+struct TRINITY_DLL_DECL instance_utgarde_keep : public ScriptedInstance
+{
+ instance_utgarde_keep(Map *Map) : ScriptedInstance(Map) {Initialize();};
+
+ uint64 Keleseth;
+ uint64 Skarvald;
+ uint64 Dalronn;
+ uint64 Ingvar;
+
+ bool IsBossDied[2];
+
+ uint32 Encounters[ENCOUNTERS];
+ std::string str_data;
+
+ void Initialize()
+ {
+ Keleseth = 0;
+ Skarvald = 0;
+ Dalronn =0;
+ Ingvar =0;
+
+ for(uint8 i = 0; i < ENCOUNTERS; ++i)
+ Encounters[i] = NOT_STARTED;
+ }
+
+ bool IsEncounterInProgress() const
+ {
+ for(uint8 i = 0; i < ENCOUNTERS; ++i)
+ if(Encounters[i] == IN_PROGRESS) return true;
+
+ return false;
+ }
+
+ Player* GetPlayerInMap()
+ {
+ Map::PlayerList const& players = instance->GetPlayers();
+
+ if (!players.isEmpty())
+ {
+ for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
+ {
+ if (Player* plr = itr->getSource())
+ return plr;
+ }
+ }
+
+ debug_log("TSCR: Instance Utgarde Keep: GetPlayerInMap, but PlayerList is empty!");
+ return NULL;
+ }
+
+ void HandleGameObject(uint64 guid, uint32 state)
+ {
+ Player *player = GetPlayerInMap();
+
+ if (!player || !guid)
+ {
+ debug_log("TSCR: Utgarde Keep: HandleGameObject fail");
+ return;
+ }
+
+ if (GameObject *go = GameObject::GetGameObject(*player,guid))
+ go->SetGoState(state);
+ }
+
+ void OnCreatureCreate(Creature *creature, uint32 creature_entry)
+ {
+ switch(creature->GetEntry())
+ {
+ case 23953: Keleseth = creature->GetGUID(); break;
+ case 24200: Dalronn = creature->GetGUID(); break;
+ case 24201: Skarvald = creature->GetGUID(); break;
+ case 23954: Ingvar = creature->GetGUID(); break;
+ }
+ }
+
+ void OnObjectCreate(GameObject* go)
+ {
+ switch(go->GetEntry())
+ {
+ //door and object id
+ }
+ }
+
+ uint64 GetData64(uint32 identifier)
+ {
+ switch(identifier)
+ {
+ case DATA_PRINCEKELESETH: return Keleseth;
+ case DATA_DALRON: return Dalronn;
+ case DATA_SKARVALD: return Skarvald;
+ case DATA_INGVAR: return Ingvar;
+ }
+
+ return 0;
+ }
+
+ void SetData(uint32 type, uint32 data)
+ {
+ switch(type)
+ {
+ case DATA_PRINCEKELESETH:
+ if(data == DONE)
+ {
+ //HandleGameObject(doorname, 0);
+ }
+ Encounters[0] = data;break;
+ case DATA_DALRON:
+ if(data == DONE)
+ {
+ //HandleGameObject(doorname, 0);
+ }
+ Encounters[1] = data; break;
+ case DATA_SKARVALD:
+ if(data == DONE)
+ {
+ //HandleGameObject(doorname, 0);
+ }
+ Encounters[2] = data; break;
+ case DATA_INGVAR:
+ if(data == DONE)
+ {
+ //HandleGameObject(doorname, 0);
+ }
+ Encounters[3] = data; break;
+ }
+
+ if (data == DONE)
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+ saveStream << Encounters[0] << " " << Encounters[1] << " "
+ << Encounters[2] << " " << Encounters[3];
+
+ str_data = saveStream.str();
+
+ SaveToDB();
+ OUT_SAVE_INST_DATA_COMPLETE;
+ }
+ }
+
+ uint32 GetData(uint32 type)
+ {
+ switch(type)
+ {
+ case DATA_PRINCEKELESETH: return Encounters[0];
+ case DATA_DALRON: return Encounters[1];
+ case DATA_SKARVALD: return Encounters[2];
+ case DATA_INGVAR: return Encounters[3];
+ }
+
+ return 0;
+ }
+
+ const char* Save()
+ {
+ return str_data.c_str();
+ }
+
+ void Load(const char* in)
+ {
+ if (!in)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(in);
+
+ std::istringstream loadStream(in);
+ loadStream >> Encounters[0] >> Encounters[1] >> Encounters[2]
+ >> Encounters[3];
+
+ for(uint8 i = 0; i < ENCOUNTERS; ++i)
+ if (Encounters[i] == IN_PROGRESS)
+ Encounters[i] = NOT_STARTED;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+};
+
+InstanceData* GetInstanceData_instance_utgarde_keep(Map* map)
+{
+ return new instance_utgarde_keep(map);
+}
+
+void AddSC_instance_utgarde_keep()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_utgarde_keep";
+ newscript->GetInstanceData = &GetInstanceData_instance_utgarde_keep;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_akilzon.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_akilzon.cpp
index 7eb9fb81426..4daff002f38 100644
--- a/src/bindings/scripts/scripts/zone/zulaman/boss_akilzon.cpp
+++ b/src/bindings/scripts/scripts/zone/zulaman/boss_akilzon.cpp
@@ -188,7 +188,7 @@ struct TRINITY_DLL_DECL boss_akilzonAI : public ScriptedAI
{
Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(m_creature, m_creature, 999);
- Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(tempUnitMap, u_check);
+ Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(m_creature, tempUnitMap, u_check);
TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher);
TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck>, GridTypeMapContainer > grid_unit_searcher(searcher);
diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp
index fe31c5fbfc1..c2827ce6701 100644
--- a/src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp
+++ b/src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp
@@ -237,8 +237,7 @@ struct TRINITY_DLL_DECL boss_hex_lord_malacrassAI : public ScriptedAI
SpawnAdds();
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 46916);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, 50268674);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 46916);
m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE );
}
diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_janalai.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_janalai.cpp
index d7ce85055d3..b6792278127 100644
--- a/src/bindings/scripts/scripts/zone/zulaman/boss_janalai.cpp
+++ b/src/bindings/scripts/scripts/zone/zulaman/boss_janalai.cpp
@@ -239,7 +239,7 @@ struct TRINITY_DLL_DECL boss_janalaiAI : public ScriptedAI
cell.SetNoCreate();
Trinity::AllCreaturesOfEntryInRange check(m_creature, MOB_EGG, 100);
- Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(templist, check);
+ Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(m_creature, templist, check);
TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange>, GridTypeMapContainer> cSearcher(searcher);
@@ -274,7 +274,7 @@ struct TRINITY_DLL_DECL boss_janalaiAI : public ScriptedAI
cell.SetNoCreate();
Trinity::AllCreaturesOfEntryInRange check(m_creature, MOB_FIRE_BOMB, 100);
- Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(templist, check);
+ Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(m_creature, templist, check);
TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange>, GridTypeMapContainer> cSearcher(searcher);
@@ -518,7 +518,7 @@ struct TRINITY_DLL_DECL mob_amanishi_hatcherAI : public ScriptedAI
cell.SetNoCreate();
Trinity::AllCreaturesOfEntryInRange check(m_creature, 23817, 50);
- Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(templist, check);
+ Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(m_creature, templist, check);
TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange>, GridTypeMapContainer> cSearcher(searcher);
diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp
index c1ef845d1f8..0220523a1e2 100644
--- a/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp
+++ b/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp
@@ -143,7 +143,7 @@ struct TRINITY_DLL_DECL boss_nalorakkAI : public ScriptedAI
Berserk_Timer = 600000;
inBearForm = false;
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 1, 5122);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 5122);
}
void SendAttacker(Unit* target)
@@ -159,7 +159,7 @@ struct TRINITY_DLL_DECL boss_nalorakkAI : public ScriptedAI
cell.SetNoCreate();
Trinity::AllFriendlyCreaturesInGrid check(m_creature);
- Trinity::CreatureListSearcher<Trinity::AllFriendlyCreaturesInGrid> searcher(templist, check);
+ Trinity::CreatureListSearcher<Trinity::AllFriendlyCreaturesInGrid> searcher(m_creature, templist, check);
TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllFriendlyCreaturesInGrid>, GridTypeMapContainer> cSearcher(searcher);
@@ -361,7 +361,7 @@ struct TRINITY_DLL_DECL boss_nalorakkAI : public ScriptedAI
{
if(inBearForm)
{
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 1, 5122);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 5122);
DoYell(YELL_SHIFTEDTOTROLL, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_YELL_TOTROLL);
m_creature->RemoveAurasDueToSpell(SPELL_BEARFORM);
@@ -373,7 +373,7 @@ struct TRINITY_DLL_DECL boss_nalorakkAI : public ScriptedAI
}
else
{
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 1, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 0);
DoYell(YELL_SHIFTEDTOBEAR, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_YELL_TOBEAR);
DoCast(m_creature, SPELL_BEARFORM, true);
diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_zuljin.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_zuljin.cpp
index 685cfa57a0b..d4be29c3557 100644
--- a/src/bindings/scripts/scripts/zone/zulaman/boss_zuljin.cpp
+++ b/src/bindings/scripts/scripts/zone/zulaman/boss_zuljin.cpp
@@ -207,9 +207,9 @@ struct TRINITY_DLL_DECL boss_zuljinAI : public ScriptedAI
Summons.DespawnAll();
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 47174);
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, 218172674);
- m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 47174);
+ //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, 218172674);
+ //m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE);
}
void Aggro(Unit *who)
@@ -253,7 +253,7 @@ struct TRINITY_DLL_DECL boss_zuljinAI : public ScriptedAI
Summons.DespawnEntry(CREATURE_COLUMN_OF_FIRE);
if(Unit *Temp = Unit::GetUnit(*m_creature, SpiritGUID[3]))
- Temp->SetUInt32Value(UNIT_FIELD_BYTES_1,PLAYER_STATE_DEAD);
+ Temp->SetUInt32Value(UNIT_FIELD_BYTES_1,UNIT_STAND_STATE_DEAD);
}
void AttackStart(Unit *who)
@@ -341,7 +341,7 @@ struct TRINITY_DLL_DECL boss_zuljinAI : public ScriptedAI
m_creature->Relocate(CENTER_X, CENTER_Y, CENTER_Z,0);
m_creature->SendMonsterMove(CENTER_X, CENTER_Y, CENTER_Z,0,0,100);
DoResetThreat();
- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0);
+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0);
m_creature->RemoveAurasDueToSpell(Transform[Phase].unaura);
DoCast(m_creature, Transform[Phase].spell);
DoYell(Transform[Phase].text, LANG_UNIVERSAL, NULL);
@@ -349,7 +349,7 @@ struct TRINITY_DLL_DECL boss_zuljinAI : public ScriptedAI
if(Phase > 0)
{
if(Unit *Temp = Unit::GetUnit(*m_creature, SpiritGUID[Phase - 1]))
- Temp->SetUInt32Value(UNIT_FIELD_BYTES_1,PLAYER_STATE_DEAD);
+ Temp->SetUInt32Value(UNIT_FIELD_BYTES_1,UNIT_STAND_STATE_DEAD);
}
if(Unit *Temp = Unit::GetUnit(*m_creature, SpiritGUID[NextPhase - 1]))
Temp->CastSpell(m_creature, SPELL_SIPHON_SOUL, false); // should m cast on temp
diff --git a/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp b/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp
index dff3148aa57..47e9c4395ba 100644
--- a/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp
+++ b/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp
@@ -140,7 +140,7 @@ struct TRINITY_DLL_DECL instance_zulaman : public ScriptedInstance
void OpenDoor(uint64 DoorGUID, bool open)
{
if(GameObject *Door = instance->GetGameObjectInMap(DoorGUID))
- Door->SetUInt32Value(GAMEOBJECT_STATE, open ? 0 : 1);
+ Door->SetGoState(open ? 0 : 1);
}
void SummonHostage(uint8 num)
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp
index 0dccc26ff14..10679d13812 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp
@@ -65,9 +65,9 @@ struct TRINITY_DLL_DECL boss_renatakiAI : public ScriptedAI
if (Invisible_Timer < diff)
{
m_creature->InterruptSpell(CURRENT_GENERIC_SPELL);
- m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0);
- m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO , 218171138);
- m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + 1, 3);
+ m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_ID, 0);
+ //m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO , 218171138);
+ //m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + 1, 3);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID,11686);
Invisible = true;
@@ -100,9 +100,9 @@ struct TRINITY_DLL_DECL boss_renatakiAI : public ScriptedAI
m_creature->InterruptSpell(CURRENT_GENERIC_SPELL);
m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID,15268);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 31818);
- m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO , 218171138);
- m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + 1, 3);
+ m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_ID, 31818);
+ //m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO , 218171138);
+ //m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + 1, 3);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
Invisible = false;
diff --git a/src/bindings/scripts/system.cpp b/src/bindings/scripts/system.cpp
index e1e103f58e1..703fa139bee 100644
--- a/src/bindings/scripts/system.cpp
+++ b/src/bindings/scripts/system.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
- * Thanks to the original authors: MaNGOS <http://www.mangosproject.org/>
+ * Thanks to the original authors: 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
diff --git a/src/framework/Dynamic/FactoryHolder.h b/src/framework/Dynamic/FactoryHolder.h
index a9c7a718541..cf41be4953f 100644
--- a/src/framework/Dynamic/FactoryHolder.h
+++ b/src/framework/Dynamic/FactoryHolder.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/Dynamic/ObjectRegistry.h b/src/framework/Dynamic/ObjectRegistry.h
index 25dfa9f5092..ef61ef38cde 100644
--- a/src/framework/Dynamic/ObjectRegistry.h
+++ b/src/framework/Dynamic/ObjectRegistry.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/GameSystem/Grid.h b/src/framework/GameSystem/Grid.h
index a239795f3c3..0210f62faf7 100644
--- a/src/framework/GameSystem/Grid.h
+++ b/src/framework/GameSystem/Grid.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/GameSystem/GridLoader.h b/src/framework/GameSystem/GridLoader.h
index 882974b81b0..df46585c225 100644
--- a/src/framework/GameSystem/GridLoader.h
+++ b/src/framework/GameSystem/GridLoader.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/GameSystem/GridRefManager.h b/src/framework/GameSystem/GridRefManager.h
index d233b844572..63e5065dc12 100644
--- a/src/framework/GameSystem/GridRefManager.h
+++ b/src/framework/GameSystem/GridRefManager.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/GameSystem/GridReference.h b/src/framework/GameSystem/GridReference.h
index 65592e780b1..529278ea036 100644
--- a/src/framework/GameSystem/GridReference.h
+++ b/src/framework/GameSystem/GridReference.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/GameSystem/NGrid.h b/src/framework/GameSystem/NGrid.h
index ecb20ff5069..6ed87624662 100644
--- a/src/framework/GameSystem/NGrid.h
+++ b/src/framework/GameSystem/NGrid.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -76,12 +76,12 @@ class TRINITY_DLL_DECL NGrid
const GridType& operator()(unsigned short x, unsigned short y) const { return i_cells[x][y]; }
GridType& operator()(unsigned short x, unsigned short y) { return i_cells[x][y]; }
- inline const uint32& GetGridId(void) const { return i_gridId; }
- inline void SetGridId(const uint32 id) const { i_gridId = id; }
- inline grid_state_t GetGridState(void) const { return i_cellstate; }
- inline void SetGridState(grid_state_t s) { i_cellstate = s; }
- inline int32 getX() const { return i_x; }
- inline int32 getY() const { return i_y; }
+ const uint32& GetGridId(void) const { return i_gridId; }
+ void SetGridId(const uint32 id) const { i_gridId = id; }
+ grid_state_t GetGridState(void) const { return i_cellstate; }
+ void SetGridState(grid_state_t s) { i_cellstate = s; }
+ int32 getX() const { return i_x; }
+ int32 getY() const { return i_y; }
void link(GridRefManager<NGrid<N, ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES, ThreadModel> >* pTo)
{
diff --git a/src/framework/GameSystem/TypeContainer.h b/src/framework/GameSystem/TypeContainer.h
index b7949b8b461..e4a30103d2d 100644
--- a/src/framework/GameSystem/TypeContainer.h
+++ b/src/framework/GameSystem/TypeContainer.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/GameSystem/TypeContainerFunctions.h b/src/framework/GameSystem/TypeContainerFunctions.h
index 4dc1bcf79ba..ec005e2218c 100644
--- a/src/framework/GameSystem/TypeContainerFunctions.h
+++ b/src/framework/GameSystem/TypeContainerFunctions.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/GameSystem/TypeContainerFunctionsPtr.h b/src/framework/GameSystem/TypeContainerFunctionsPtr.h
index 33df2b1461c..5f15f6c65a7 100644
--- a/src/framework/GameSystem/TypeContainerFunctionsPtr.h
+++ b/src/framework/GameSystem/TypeContainerFunctionsPtr.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/GameSystem/TypeContainerVisitor.h b/src/framework/GameSystem/TypeContainerVisitor.h
index c6999a88384..c544afa0f5e 100644
--- a/src/framework/GameSystem/TypeContainerVisitor.h
+++ b/src/framework/GameSystem/TypeContainerVisitor.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/Makefile.am b/src/framework/Makefile.am
index 081b1cc9b44..e76e12ee76a 100644
--- a/src/framework/Makefile.am
+++ b/src/framework/Makefile.am
@@ -1,6 +1,6 @@
-# Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+# Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
#
-# Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+# Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/Network/SocketDefines.h b/src/framework/Network/SocketDefines.h
index b5c0434c1d3..e18be535e91 100644
--- a/src/framework/Network/SocketDefines.h
+++ b/src/framework/Network/SocketDefines.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/Platform/CompilerDefs.h b/src/framework/Platform/CompilerDefs.h
index cd7b6ff55bb..2bf7f7872f9 100644
--- a/src/framework/Platform/CompilerDefs.h
+++ b/src/framework/Platform/CompilerDefs.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/Platform/Define.h b/src/framework/Platform/Define.h
index 5228359589b..574793a285d 100644
--- a/src/framework/Platform/Define.h
+++ b/src/framework/Platform/Define.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 Mangos <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/Policies/CreationPolicy.h b/src/framework/Policies/CreationPolicy.h
index 72a7e265d62..10ed0109583 100644
--- a/src/framework/Policies/CreationPolicy.h
+++ b/src/framework/Policies/CreationPolicy.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/Policies/ObjectLifeTime.cpp b/src/framework/Policies/ObjectLifeTime.cpp
index 15bcaa54686..55d452f801d 100644
--- a/src/framework/Policies/ObjectLifeTime.cpp
+++ b/src/framework/Policies/ObjectLifeTime.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/Policies/ObjectLifeTime.h b/src/framework/Policies/ObjectLifeTime.h
index acd8516fc56..0666d7e19a8 100644
--- a/src/framework/Policies/ObjectLifeTime.h
+++ b/src/framework/Policies/ObjectLifeTime.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -34,7 +34,7 @@ namespace Trinity
class TRINITY_DLL_DECL ObjectLifeTime
{
public:
- inline static void ScheduleCall(void (*destroyer)() )
+ static void ScheduleCall(void (*destroyer)() )
{
at_exit( destroyer );
}
@@ -44,7 +44,7 @@ namespace Trinity
};
template <class T>
- inline void ObjectLifeTime<T>::OnDeadReference(void)// We don't handle Dead Reference for now
+ void ObjectLifeTime<T>::OnDeadReference(void) // We don't handle Dead Reference for now
{
throw std::runtime_error("Dead Reference");
}
diff --git a/src/framework/Policies/Singleton.h b/src/framework/Policies/Singleton.h
index 0f382197f1f..e33a52b2462 100644
--- a/src/framework/Policies/Singleton.h
+++ b/src/framework/Policies/Singleton.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/Policies/SingletonImp.h b/src/framework/Policies/SingletonImp.h
index 16bfa2c4b05..386b321c1f1 100644
--- a/src/framework/Policies/SingletonImp.h
+++ b/src/framework/Policies/SingletonImp.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/Policies/ThreadingModel.h b/src/framework/Policies/ThreadingModel.h
index 08d72854781..c482b2f10ad 100644
--- a/src/framework/Policies/ThreadingModel.h
+++ b/src/framework/Policies/ThreadingModel.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/Utilities/ByteConverter.h b/src/framework/Utilities/ByteConverter.h
index 59081ef8ccd..c770be449cb 100644
--- a/src/framework/Utilities/ByteConverter.h
+++ b/src/framework/Utilities/ByteConverter.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/Utilities/Callback.h b/src/framework/Utilities/Callback.h
index 29de60d998d..3b8c3e450f3 100644
--- a/src/framework/Utilities/Callback.h
+++ b/src/framework/Utilities/Callback.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/Utilities/CountedReference/Reference.h b/src/framework/Utilities/CountedReference/Reference.h
index 693df05dddc..7954c437966 100644
--- a/src/framework/Utilities/CountedReference/Reference.h
+++ b/src/framework/Utilities/CountedReference/Reference.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/Utilities/CountedReference/ReferenceHolder.h b/src/framework/Utilities/CountedReference/ReferenceHolder.h
index 0c2294fc8c5..03edff4c7cd 100644
--- a/src/framework/Utilities/CountedReference/ReferenceHolder.h
+++ b/src/framework/Utilities/CountedReference/ReferenceHolder.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/Utilities/CountedReference/ReferenceImpl.h b/src/framework/Utilities/CountedReference/ReferenceImpl.h
index ef217a72dd9..43a01e2bc85 100644
--- a/src/framework/Utilities/CountedReference/ReferenceImpl.h
+++ b/src/framework/Utilities/CountedReference/ReferenceImpl.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/Utilities/EventProcessor.cpp b/src/framework/Utilities/EventProcessor.cpp
index cd80a9effcc..d6e74ced42c 100644
--- a/src/framework/Utilities/EventProcessor.cpp
+++ b/src/framework/Utilities/EventProcessor.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/Utilities/EventProcessor.h b/src/framework/Utilities/EventProcessor.h
index 508da2cc0fd..ecc7ec608be 100644
--- a/src/framework/Utilities/EventProcessor.h
+++ b/src/framework/Utilities/EventProcessor.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/Utilities/LinkedList.h b/src/framework/Utilities/LinkedList.h
index 347fe7fa849..22a80f0b9ba 100644
--- a/src/framework/Utilities/LinkedList.h
+++ b/src/framework/Utilities/LinkedList.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/Utilities/LinkedReference/RefManager.h b/src/framework/Utilities/LinkedReference/RefManager.h
index bfb163cc9c9..bef8b32862c 100644
--- a/src/framework/Utilities/LinkedReference/RefManager.h
+++ b/src/framework/Utilities/LinkedReference/RefManager.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/Utilities/LinkedReference/Reference.h b/src/framework/Utilities/LinkedReference/Reference.h
index 28c77d918aa..5ca167a3948 100644
--- a/src/framework/Utilities/LinkedReference/Reference.h
+++ b/src/framework/Utilities/LinkedReference/Reference.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -44,7 +44,7 @@ template <class TO, class FROM> class Reference : public LinkedListElement
virtual ~Reference() {}
// Create new link
- inline void link(TO* toObj, FROM* fromObj)
+ void link(TO* toObj, FROM* fromObj)
{
assert(fromObj); // fromObj MUST not be NULL
if(isValid())
@@ -59,16 +59,16 @@ template <class TO, class FROM> class Reference : public LinkedListElement
// We don't need the reference anymore. Call comes from the refFrom object
// Tell our refTo object, that the link is cut
- inline void unlink() { targetObjectDestroyLink(); delink(); iRefTo = NULL; iRefFrom = NULL; }
+ void unlink() { targetObjectDestroyLink(); delink(); iRefTo = NULL; iRefFrom = NULL; }
// Link is invalid due to destruction of referenced target object. Call comes from the refTo object
// Tell our refFrom object, that the link is cut
- inline void invalidate() // the iRefFrom MUST remain!!
+ void invalidate() // the iRefFrom MUST remain!!
{
sourceObjectDestroyLink(); delink(); iRefTo = NULL;
}
- inline bool isValid() const // Only check the iRefTo
+ bool isValid() const // Only check the iRefTo
{
return iRefTo != NULL;
}
@@ -83,10 +83,10 @@ template <class TO, class FROM> class Reference : public LinkedListElement
Reference<TO,FROM> * nocheck_prev() { return((Reference<TO,FROM> *) LinkedListElement::nocheck_prev()); }
Reference<TO,FROM> const * nocheck_prev() const { return((Reference<TO,FROM> const *) LinkedListElement::nocheck_prev()); }
- inline TO* operator ->() const { return iRefTo; }
- inline TO* getTarget() const { return iRefTo; }
+ TO* operator ->() const { return iRefTo; }
+ TO* getTarget() const { return iRefTo; }
- inline FROM* getSource() const { return iRefFrom; }
+ FROM* getSource() const { return iRefFrom; }
};
//=====================================================
diff --git a/src/framework/Utilities/TypeList.h b/src/framework/Utilities/TypeList.h
index daa6886467a..fc9f869aa2b 100644
--- a/src/framework/Utilities/TypeList.h
+++ b/src/framework/Utilities/TypeList.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/framework/Utilities/UnorderedMap.h b/src/framework/Utilities/UnorderedMap.h
index 31cd453ecba..13f9d58619b 100644
--- a/src/framework/Utilities/UnorderedMap.h
+++ b/src/framework/Utilities/UnorderedMap.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/AccountMgr.cpp b/src/game/AccountMgr.cpp
index d12f07e7bfd..d5d7ee1a59a 100644
--- a/src/game/AccountMgr.cpp
+++ b/src/game/AccountMgr.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -25,11 +25,7 @@
#include "Policies/SingletonImp.h"
#include "Util.h"
-#ifdef DO_POSTGRESQL
-extern DatabasePostgre LoginDatabase;
-#else
-extern DatabaseMysql LoginDatabase;
-#endif
+extern DatabaseType LoginDatabase;
INSTANTIATE_SINGLETON_1(AccountMgr);
diff --git a/src/game/AccountMgr.h b/src/game/AccountMgr.h
index 0c1703ee2d9..a40c93989ed 100644
--- a/src/game/AccountMgr.h
+++ b/src/game/AccountMgr.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp
new file mode 100644
index 00000000000..726316666c2
--- /dev/null
+++ b/src/game/AchievementMgr.cpp
@@ -0,0 +1,1177 @@
+/*
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "AchievementMgr.h"
+#include "Common.h"
+#include "Player.h"
+#include "WorldPacket.h"
+#include "Database/DBCEnums.h"
+#include "ObjectMgr.h"
+#include "Guild.h"
+#include "Database/DatabaseEnv.h"
+#include "GameEvent.h"
+#include "World.h"
+#include "SpellMgr.h"
+#include "ProgressBar.h"
+
+#include "Policies/SingletonImp.h"
+
+INSTANTIATE_SINGLETON_1(AchievementGlobalMgr);
+
+const CriteriaCastSpellRequirement AchievementGlobalMgr::m_criteriaCastSpellRequirements[CRITERIA_CAST_SPELL_REQ_COUNT] =
+ {
+ {5272, 3057, 0, 0},
+ {5273, 2784, 0, 0},
+ {5752, 9099, 0, 0},
+ {5753, 8403, 0, 0},
+ {5772, 0, 0, RACE_GNOME},
+ {5774, 0, 0, RACE_BLOODELF},
+ {5775, 0, 0, RACE_DRAENEI},
+ {5776, 0, 0, RACE_DWARF},
+ {5777, 0, 0, RACE_HUMAN},
+ {5778, 0, 0, RACE_NIGHTELF},
+ {5779, 0, 0, RACE_ORC},
+ {5780, 0, 0, RACE_TAUREN},
+ {5781, 0, 0, RACE_TROLL},
+ {5782, 0, 0, RACE_UNDEAD_PLAYER},
+ {6225, 5661, 0, 0},
+ {6226, 26044, 0, 0},
+ {6228, 739, 0, 0},
+ {6229, 927, 0, 0},
+ {6230, 1444, 0, 0},
+ {6231, 8140, 0, 0},
+ {6232, 5489, 0, 0},
+ {6233,12336, 0, 0},
+ {6234, 1351, 0, 0},
+ {6235, 5484, 0, 0},
+ {6236, 1182, 0, 0},
+ {6237, 0, CLASS_DEATH_KNIGHT, RACE_ORC},
+ {6238, 0, CLASS_WARRIOR, RACE_HUMAN},
+ {6239, 0, CLASS_SHAMAN, RACE_TAUREN},
+ {6240, 0, CLASS_DRUID, RACE_NIGHTELF},
+ {6241, 0, CLASS_ROGUE, RACE_UNDEAD_PLAYER},
+ {6242, 0, CLASS_HUNTER, RACE_TROLL},
+ {6243, 0, CLASS_MAGE, RACE_GNOME},
+ {6244, 0, CLASS_PALADIN, RACE_DWARF},
+ {6245, 0, CLASS_WARLOCK, RACE_BLOODELF},
+ {6246, 0, CLASS_PRIEST, RACE_DRAENEI},
+ {6312, 0, CLASS_WARLOCK, RACE_GNOME},
+ {6313, 0, CLASS_DEATH_KNIGHT, RACE_HUMAN},
+ {6314, 0, CLASS_PRIEST, RACE_NIGHTELF},
+ {6315, 0, CLASS_SHAMAN, RACE_ORC},
+ {6316, 0, CLASS_DRUID, RACE_TAUREN},
+ {6317, 0, CLASS_ROGUE, RACE_TROLL},
+ {6318, 0, CLASS_WARRIOR, RACE_UNDEAD_PLAYER},
+ {6319, 0, CLASS_MAGE, RACE_BLOODELF},
+ {6320, 0, CLASS_PALADIN, RACE_DRAENEI},
+ {6321, 0, CLASS_HUNTER, RACE_DWARF},
+ {6662, 31261, 0, 0}
+ };
+
+AchievementMgr::AchievementMgr(Player *player)
+{
+ m_player = player;
+}
+
+AchievementMgr::~AchievementMgr()
+{
+}
+
+void AchievementMgr::Reset()
+{
+ for(CompletedAchievementMap::iterator iter = m_completedAchievements.begin(); iter!=m_completedAchievements.end(); ++iter)
+ {
+ WorldPacket data(SMSG_ACHIEVEMENT_DELETED,4);
+ data << uint32(iter->first);
+ m_player->SendDirectMessage(&data);
+ }
+
+ for(CriteriaProgressMap::iterator iter = m_criteriaProgress.begin(); iter!=m_criteriaProgress.end(); ++iter)
+ {
+ WorldPacket data(SMSG_CRITERIA_DELETED,4);
+ data << uint32(iter->first);
+ m_player->SendDirectMessage(&data);
+ }
+
+ m_completedAchievements.clear();
+ m_criteriaProgress.clear();
+ DeleteFromDB(m_player->GetGUIDLow());
+
+ // re-fill data
+ CheckAllAchievementCriteria();
+}
+
+void AchievementMgr::DeleteFromDB(uint32 lowguid)
+{
+ CharacterDatabase.BeginTransaction ();
+ CharacterDatabase.PExecute("DELETE FROM character_achievement WHERE guid = %u",lowguid);
+ CharacterDatabase.PExecute("DELETE FROM character_achievement_progress WHERE guid = %u",lowguid);
+ CharacterDatabase.CommitTransaction ();
+}
+
+void AchievementMgr::SaveToDB()
+{
+ if(!m_completedAchievements.empty())
+ {
+ bool need_execute = false;
+ std::ostringstream ssdel;
+ std::ostringstream ssins;
+ for(CompletedAchievementMap::iterator iter = m_completedAchievements.begin(); iter!=m_completedAchievements.end(); ++iter)
+ {
+ if(!iter->second.changed)
+ continue;
+
+ /// first new/changed record prefix
+ if(!need_execute)
+ {
+ ssdel << "DELETE FROM character_achievement WHERE guid = " << GetPlayer()->GetGUIDLow() << " AND achievement IN (";
+ ssins << "INSERT INTO character_achievement (guid, achievement, date) VALUES ";
+ need_execute = true;
+ }
+ /// next new/changed record prefix
+ else
+ {
+ ssdel << ", ";
+ ssins << ", ";
+ }
+
+ // new/changed record data
+ ssdel << iter->first;
+ ssins << "("<<GetPlayer()->GetGUIDLow() << ", " << iter->first << ", " << uint64(iter->second.date) << ")";
+
+ /// mark as saved in db
+ iter->second.changed = false;
+ }
+
+ if(need_execute)
+ ssdel << ")";
+
+ if(need_execute)
+ {
+ CharacterDatabase.BeginTransaction ();
+ CharacterDatabase.Execute( ssdel.str().c_str() );
+ CharacterDatabase.Execute( ssins.str().c_str() );
+ CharacterDatabase.CommitTransaction ();
+ }
+ }
+
+ if(!m_criteriaProgress.empty())
+ {
+ /// prepare deleting and insert
+ bool need_execute_del = false;
+ bool need_execute_ins = false;
+ std::ostringstream ssdel;
+ std::ostringstream ssins;
+ for(CriteriaProgressMap::iterator iter = m_criteriaProgress.begin(); iter!=m_criteriaProgress.end(); ++iter)
+ {
+ if(!iter->second.changed)
+ continue;
+
+ // deleted data (including 0 progress state)
+ {
+ /// first new/changed record prefix (for any counter value)
+ if(!need_execute_del)
+ {
+ ssdel << "DELETE FROM character_achievement_progress WHERE guid = " << GetPlayer()->GetGUIDLow() << " AND criteria IN (";
+ need_execute_del = true;
+ }
+ /// next new/changed record prefix
+ else
+ ssdel << ", ";
+
+ // new/changed record data
+ ssdel << iter->first;
+ }
+
+ // store data only for real progress
+ if(iter->second.counter != 0)
+ {
+ /// first new/changed record prefix
+ if(!need_execute_ins)
+ {
+ ssins << "INSERT INTO character_achievement_progress (guid, criteria, counter, date) VALUES ";
+ need_execute_ins = true;
+ }
+ /// next new/changed record prefix
+ else
+ ssins << ", ";
+
+ // new/changed record data
+ ssins << "(" << GetPlayer()->GetGUIDLow() << ", " << iter->first << ", " << iter->second.counter << ", " << iter->second.date << ")";
+ }
+
+ /// mark as updated in db
+ iter->second.changed = false;
+ }
+
+ if(need_execute_del) // DELETE ... IN (.... _)_
+ ssdel << ")";
+
+ if(need_execute_del || need_execute_ins)
+ {
+ CharacterDatabase.BeginTransaction ();
+ if(need_execute_del)
+ CharacterDatabase.Execute( ssdel.str().c_str() );
+ if(need_execute_ins)
+ CharacterDatabase.Execute( ssins.str().c_str() );
+ CharacterDatabase.CommitTransaction ();
+ }
+ }
+}
+
+void AchievementMgr::LoadFromDB(QueryResult *achievementResult, QueryResult *criteriaResult)
+{
+ if(achievementResult)
+ {
+ do
+ {
+ Field *fields = achievementResult->Fetch();
+ CompletedAchievementData& ca = m_completedAchievements[fields[0].GetUInt32()];
+ ca.date = time_t(fields[1].GetUInt64());
+ ca.changed = false;
+ } while(achievementResult->NextRow());
+ delete achievementResult;
+ }
+
+ if(criteriaResult)
+ {
+ do
+ {
+ Field *fields = criteriaResult->Fetch();
+
+ uint32 id = fields[0].GetUInt32();
+ uint32 counter = fields[1].GetUInt32();
+ time_t date = time_t(fields[2].GetUInt64());
+
+ AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(id);
+ if(!criteria || criteria->timeLimit && date + criteria->timeLimit < time(NULL))
+ continue;
+
+ CriteriaProgress& progress = m_criteriaProgress[id];
+ progress.counter = counter;
+ progress.date = date;
+ progress.changed = false;
+ } while(criteriaResult->NextRow());
+ delete criteriaResult;
+ }
+
+}
+
+void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement)
+{
+ sLog.outDebug("AchievementMgr::SendAchievementEarned(%u)", achievement->ID);
+
+ const char *msg = "|Hplayer:$N|h[$N]|h has earned the achievement $a!";
+ if(Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()))
+ {
+ WorldPacket data(SMSG_MESSAGECHAT, 200);
+ data << uint8(CHAT_MSG_GUILD_ACHIEVEMENT);
+ data << uint32(LANG_UNIVERSAL);
+ data << uint64(GetPlayer()->GetGUID());
+ data << uint32(5);
+ data << uint64(GetPlayer()->GetGUID());
+ data << uint32(strlen(msg)+1);
+ data << msg;
+ data << uint8(0);
+ data << uint32(achievement->ID);
+ guild->BroadcastPacket(&data);
+ }
+ if(achievement->flags & (ACHIEVEMENT_FLAG_REALM_FIRST_KILL|ACHIEVEMENT_FLAG_REALM_FIRST_REACH))
+ {
+ // broadcast realm first reached
+ WorldPacket data(SMSG_SERVER_FIRST_ACHIEVEMENT, strlen(GetPlayer()->GetName())+1+8+4+4);
+ data << GetPlayer()->GetName();
+ data << uint64(GetPlayer()->GetGUID());
+ data << uint32(achievement->ID);
+ data << uint32(0); // 1=link supplied string as player name, 0=display plain string
+ sWorld.SendGlobalMessage(&data);
+ }
+ else
+ {
+ WorldPacket data(SMSG_MESSAGECHAT, 200);
+ data << uint8(CHAT_MSG_ACHIEVEMENT);
+ data << uint32(LANG_UNIVERSAL);
+ data << uint64(GetPlayer()->GetGUID());
+ data << uint32(5);
+ data << uint64(GetPlayer()->GetGUID());
+ data << uint32(strlen(msg)+1);
+ data << msg;
+ data << uint8(0);
+ data << uint32(achievement->ID);
+ GetPlayer()->SendMessageToSet(&data, true);
+
+ }
+ WorldPacket data(SMSG_ACHIEVEMENT_EARNED, 8+4+8);
+ data.append(GetPlayer()->GetPackGUID());
+ data << uint32(achievement->ID);
+ data << uint32(secsToTimeBitFields(time(NULL)));
+ data << uint32(0);
+ GetPlayer()->SendMessageToSet(&data, true);
+}
+
+void AchievementMgr::SendCriteriaUpdate(uint32 id, CriteriaProgress const* progress)
+{
+ WorldPacket data(SMSG_CRITERIA_UPDATE, 8+4+8);
+ data << uint32(id);
+
+ // the counter is packed like a packed Guid
+ data.appendPackGUID(progress->counter);
+
+ data.append(GetPlayer()->GetPackGUID());
+ data << uint32(0);
+ data << uint32(secsToTimeBitFields(progress->date));
+ data << uint32(0); // timer 1
+ data << uint32(0); // timer 2
+ GetPlayer()->SendMessageToSet(&data, true);
+}
+
+/**
+ * called at player login. The player might have fulfilled some achievements when the achievement system wasn't working yet
+ */
+void AchievementMgr::CheckAllAchievementCriteria()
+{
+ // suppress sending packets
+ for(uint32 i=0; i<ACHIEVEMENT_CRITERIA_TYPE_TOTAL; ++i)
+ UpdateAchievementCriteria(AchievementCriteriaTypes(i));
+}
+
+/**
+ * this function will be called whenever the user might have done a criteria relevant action
+ */
+void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1, uint32 miscvalue2, Unit *unit, uint32 time)
+{
+ sLog.outDetail("AchievementMgr::UpdateAchievementCriteria(%u, %u, %u, %u)", type, miscvalue1, miscvalue2, time);
+
+ if (!sWorld.getConfig(CONFIG_GM_ALLOW_ACHIEVEMENT_GAINS) && m_player->GetSession()->GetSecurity() > SEC_PLAYER)
+ return;
+
+ AchievementCriteriaEntryList const& achievementCriteriaList = achievementmgr.GetAchievementCriteriaByType(type);
+ for(AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i!=achievementCriteriaList.end(); ++i)
+ {
+ AchievementCriteriaEntry const *achievementCriteria = (*i);
+
+ // don't update already completed criteria
+ if(IsCompletedCriteria(achievementCriteria))
+ continue;
+
+ if(achievementCriteria->groupFlag & ACHIEVEMENT_CRITERIA_GROUP_NOT_IN_GROUP && GetPlayer()->GetGroup())
+ continue;
+
+ AchievementEntry const *achievement = sAchievementStore.LookupEntry(achievementCriteria->referredAchievement);
+ if(!achievement)
+ continue;
+
+ if(achievement->factionFlag == ACHIEVEMENT_FACTION_FLAG_HORDE && GetPlayer()->GetTeam() != HORDE ||
+ achievement->factionFlag == ACHIEVEMENT_FACTION_FLAG_ALLIANCE && GetPlayer()->GetTeam() != ALLIANCE)
+ continue;
+
+ switch (type)
+ {
+ case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL:
+ SetCriteriaProgress(achievementCriteria, GetPlayer()->getLevel());
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT:
+ SetCriteriaProgress(achievementCriteria, GetPlayer()->GetByteValue(PLAYER_BYTES_2, 2)+1);
+ 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;
+ SetCriteriaProgress(achievementCriteria, miscvalue2, true);
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL:
+ if(uint32 skillvalue = GetPlayer()->GetBaseSkillValue(achievementCriteria->reach_skill_level.skillID))
+ SetCriteriaProgress(achievementCriteria, skillvalue);
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT:
+ {
+ uint32 counter =0;
+ for(QuestStatusMap::iterator itr = GetPlayer()->getQuestStatusMap().begin(); itr!=GetPlayer()->getQuestStatusMap().end(); itr++)
+ if(itr->second.m_rewarded)
+ counter++;
+ SetCriteriaProgress(achievementCriteria, counter);
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE:
+ {
+ uint32 counter =0;
+ for(QuestStatusMap::iterator itr = GetPlayer()->getQuestStatusMap().begin(); itr!=GetPlayer()->getQuestStatusMap().end(); itr++)
+ {
+ Quest const* quest = objmgr.GetQuestTemplate(itr->first);
+ if(itr->second.m_rewarded && quest->GetZoneOrSort() == achievementCriteria->complete_quests_in_zone.zoneID)
+ counter++;
+ }
+ SetCriteriaProgress(achievementCriteria, counter);
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST:
+ // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
+ if(!miscvalue1)
+ continue;
+ SetCriteriaProgress(achievementCriteria, miscvalue1, true);
+ 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, true);
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL:
+ if(GetPlayer()->HasSpell(achievementCriteria->learn_spell.spellID))
+ SetCriteriaProgress(achievementCriteria, 1);
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT:
+ if(m_completedAchievements.find(achievementCriteria->complete_achievement.linkedAchievement) != m_completedAchievements.end())
+ SetCriteriaProgress(achievementCriteria, 1);
+ 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, true);
+ 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, true);
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER:
+ // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
+ if(!miscvalue1)
+ continue;
+ SetCriteriaProgress(achievementCriteria, 1, true);
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING:
+ {
+ // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
+ if(!miscvalue1)
+ continue;
+ if(achievement->ID == 1260)
+ {
+ if(Player::GetDrunkenstateByValue(GetPlayer()->GetDrunkValue()) != DRUNKEN_SMASHED)
+ continue;
+ // TODO: hardcoding eventid is bad, it can differ from DB to DB - maye implement something using HolidayNames.dbc?
+ if(!gameeventmgr.IsActiveEvent(26))
+ continue;
+ }
+ // miscvalue1 is the ingame fallheight*100 as stored in dbc
+ SetCriteriaProgress(achievementCriteria, miscvalue1);
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST:
+ if(GetPlayer()->GetQuestRewardStatus(achievementCriteria->complete_quest.questID))
+ SetCriteriaProgress(achievementCriteria, 1);
+ 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;
+ SetCriteriaProgress(achievementCriteria, 1, true);
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM:
+ // speedup for non-login case
+ if(miscvalue1 && achievementCriteria->own_item.itemID!=miscvalue1)
+ continue;
+ SetCriteriaProgress(achievementCriteria, GetPlayer()->GetItemCount(achievementCriteria->own_item.itemID, true));
+ 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, true);
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET:
+ case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2:
+ if (!miscvalue1 || miscvalue1 != achievementCriteria->be_spell_target.spellID)
+ continue;
+ SetCriteriaProgress(achievementCriteria, 1, true);
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL:
+ if (!miscvalue1 || miscvalue1 != achievementCriteria->cast_spell.spellID)
+ continue;
+ SetCriteriaProgress(achievementCriteria, 1, true);
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2:
+ {
+ if (!miscvalue1 || miscvalue1 != achievementCriteria->cast_spell.spellID)
+ continue;
+
+ // those requirements couldn't be found in the dbc
+ if (CriteriaCastSpellRequirement const* requirement = AchievementGlobalMgr::GetCriteriaCastSpellRequirement(achievementCriteria))
+ {
+ if (!unit)
+ continue;
+
+ if (requirement->creatureEntry && unit->GetEntry() != requirement->creatureEntry)
+ continue;
+
+ if (requirement->playerRace && (unit->GetTypeId() != TYPEID_PLAYER || unit->getRace()!=requirement->playerRace))
+ continue;
+
+ if (requirement->playerClass && (unit->GetTypeId() != TYPEID_PLAYER || unit->getClass()!=requirement->playerClass))
+ continue;
+ }
+
+ SetCriteriaProgress(achievementCriteria, 1, true);
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS:
+ {
+ uint32 spellCount = 0;
+ for (PlayerSpellMap::const_iterator spellIter = GetPlayer()->GetSpellMap().begin();
+ spellIter != GetPlayer()->GetSpellMap().end();
+ spellIter++)
+ {
+ for(SkillLineAbilityMap::const_iterator skillIter = spellmgr.GetBeginSkillLineAbilityMap(spellIter->first);
+ skillIter != spellmgr.GetEndSkillLineAbilityMap(spellIter->first);
+ skillIter++)
+ {
+ if(skillIter->second->skillId == achievementCriteria->learn_skilline_spell.skillLine)
+ spellCount++;
+ }
+ }
+ SetCriteriaProgress(achievementCriteria, spellCount);
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP:
+ {
+ // skip for login case
+ if(!miscvalue1)
+ continue;
+ SetCriteriaProgress(achievementCriteria, 1);
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION:
+ {
+ int32 reputation = GetPlayer()->GetReputation(achievementCriteria->gain_reputation.factionID);
+ if (reputation > 0)
+ SetCriteriaProgress(achievementCriteria, reputation);
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION:
+ {
+ uint32 counter = 0;
+ const FactionStateList factionStateList = GetPlayer()->GetFactionStateList();
+ for (FactionStateList::const_iterator iter = factionStateList.begin(); iter!= factionStateList.end(); iter++)
+ {
+ if(GetPlayer()->ReputationToRank(iter->second.Standing) >= REP_EXALTED)
+ ++counter;
+ }
+ SetCriteriaProgress(achievementCriteria, counter);
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA:
+ {
+ WorldMapOverlayEntry const* worldOverlayEntry = sWorldMapOverlayStore.LookupEntry(achievementCriteria->explore_area.areaReference);
+ if(!worldOverlayEntry)
+ break;
+
+ int32 exploreFlag = GetAreaFlagByAreaID(worldOverlayEntry->areatableID);
+ if(exploreFlag < 0)
+ break;
+
+ uint32 playerIndexOffset = uint32(exploreFlag) / 32;
+ uint32 mask = 1<< (uint32(exploreFlag) % 32);
+
+ if(GetPlayer()->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + playerIndexOffset) & mask)
+ SetCriteriaProgress(achievementCriteria, 1);
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT:
+ case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT:
+ {
+ // miscvalue1 = itemid
+ // miscvalue2 = diced value
+ if(!miscvalue1)
+ continue;
+ if(miscvalue2 != achievementCriteria->roll_greed_on_loot.rollValue)
+ continue;
+ ItemPrototype const *pProto = objmgr.GetItemPrototype( miscvalue1 );
+
+ uint32 requiredItemLevel = 0;
+ if (achievementCriteria->ID == 2412 || achievementCriteria->ID == 2358)
+ requiredItemLevel = 185;
+
+ if(!pProto || pProto->ItemLevel <requiredItemLevel)
+ continue;
+ SetCriteriaProgress(achievementCriteria, 1, true);
+ break;
+ }
+ }
+ if(IsCompletedCriteria(achievementCriteria))
+ CompletedCriteria(achievementCriteria);
+ }
+}
+
+bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achievementCriteria)
+{
+ AchievementEntry const* achievement = sAchievementStore.LookupEntry(achievementCriteria->referredAchievement);
+ if(!achievement)
+ return false;
+
+ // counter can never complete
+ if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER)
+ return false;
+
+ if(achievement->flags & (ACHIEVEMENT_FLAG_REALM_FIRST_REACH | ACHIEVEMENT_FLAG_REALM_FIRST_KILL))
+ {
+ // someone on this realm has already completed that achievement
+ if(achievementmgr.IsRealmCompleted(achievement))
+ return false;
+ }
+
+ CriteriaProgressMap::const_iterator itr = m_criteriaProgress.find(achievementCriteria->ID);
+ if(itr == m_criteriaProgress.end())
+ return false;
+
+ CriteriaProgress const* progress = &itr->second;
+
+ switch(achievementCriteria->requiredType)
+ {
+ case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL:
+ if(achievement->ID == 467 && GetPlayer()->getClass() != CLASS_SHAMAN ||
+ achievement->ID == 466 && GetPlayer()->getClass() != CLASS_DRUID ||
+ achievement->ID == 465 && GetPlayer()->getClass() != CLASS_PALADIN ||
+ achievement->ID == 464 && GetPlayer()->getClass() != CLASS_PRIEST ||
+ achievement->ID == 463 && GetPlayer()->getClass() != CLASS_WARLOCK ||
+ achievement->ID == 462 && GetPlayer()->getClass() != CLASS_HUNTER ||
+ achievement->ID == 461 && GetPlayer()->getClass() != CLASS_DEATH_KNIGHT ||
+ achievement->ID == 460 && GetPlayer()->getClass() != CLASS_MAGE ||
+ achievement->ID == 459 && GetPlayer()->getClass() != CLASS_WARRIOR ||
+ achievement->ID == 458 && GetPlayer()->getClass() != CLASS_ROGUE ||
+
+ achievement->ID == 1404 && GetPlayer()->getRace() != RACE_GNOME ||
+ achievement->ID == 1405 && GetPlayer()->getRace() != RACE_BLOODELF ||
+ achievement->ID == 1406 && GetPlayer()->getRace() != RACE_DRAENEI ||
+ achievement->ID == 1407 && GetPlayer()->getRace() != RACE_DWARF ||
+ achievement->ID == 1408 && GetPlayer()->getRace() != RACE_HUMAN ||
+ achievement->ID == 1409 && GetPlayer()->getRace() != RACE_NIGHTELF ||
+ achievement->ID == 1410 && GetPlayer()->getRace() != RACE_ORC ||
+ achievement->ID == 1411 && GetPlayer()->getRace() != RACE_TAUREN ||
+ achievement->ID == 1412 && GetPlayer()->getRace() != RACE_TROLL ||
+ achievement->ID == 1413 && GetPlayer()->getRace() != RACE_UNDEAD_PLAYER )
+ return false;
+ return progress->counter >= achievementCriteria->reach_level.level;
+ case ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT:
+ return progress->counter >= achievementCriteria->buy_bank_slot.numberOfSlots;
+ case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE:
+ return progress->counter >= achievementCriteria->kill_creature.creatureCount;
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT:
+ return progress->counter >= 1;
+ case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL:
+ return progress->counter >= achievementCriteria->reach_skill_level.skillLevel;
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT:
+ return progress->counter >= achievementCriteria->complete_quest_count.totalQuestCount;
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE:
+ return progress->counter >= achievementCriteria->complete_quests_in_zone.questCount;
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST:
+ return progress->counter >= achievementCriteria->complete_daily_quest.questCount;
+ case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL:
+ return progress->counter >= 1;
+ case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING:
+ return progress->counter >= achievementCriteria->fall_without_dying.fallHeight;
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST:
+ return progress->counter >= 1;
+ case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM:
+ return progress->counter >= achievementCriteria->use_item.itemCount;
+ case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM:
+ return progress->counter >= achievementCriteria->own_item.itemCount;
+ case ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM:
+ return progress->counter >= achievementCriteria->loot_item.itemCount;
+ case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET:
+ case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2:
+ return progress->counter >= achievementCriteria->be_spell_target.spellCount;
+ case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL:
+ case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2:
+ return progress->counter >= achievementCriteria->cast_spell.castCount;
+ case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS:
+ return progress->counter >= achievementCriteria->learn_skilline_spell.spellCount;
+ case ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP:
+ return progress->counter >= achievementCriteria->visit_barber.numberOfVisits;
+ case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION:
+ return progress->counter >= achievementCriteria->gain_reputation.reputationAmount;
+ case ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION:
+ return progress->counter >= achievementCriteria->gain_exalted_reputation.numberOfExaltedFactions;
+ case ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA:
+ return progress->counter >= 1;
+ case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT:
+ case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT:
+ return progress->counter >= achievementCriteria->roll_greed_on_loot.count;
+
+ // handle all statistic-only criteria here
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND:
+ case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP:
+ case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE:
+ case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER:
+ return false;
+ }
+ return false;
+}
+
+void AchievementMgr::CompletedCriteria(AchievementCriteriaEntry const* criteria)
+{
+ AchievementEntry const* achievement = sAchievementStore.LookupEntry(criteria->referredAchievement);
+ if(!achievement)
+ return;
+ // counter can never complete
+ if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER)
+ return;
+
+ if(criteria->completionFlag & ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL || GetAchievementCompletionState(achievement)==ACHIEVEMENT_COMPLETED_COMPLETED_NOT_STORED)
+ {
+ CompletedAchievement(achievement);
+ }
+}
+
+// TODO: achievement 705 requires 4 criteria to be fulfilled
+AchievementCompletionState AchievementMgr::GetAchievementCompletionState(AchievementEntry const* entry)
+{
+ if(m_completedAchievements.find(entry->ID)!=m_completedAchievements.end())
+ return ACHIEVEMENT_COMPLETED_COMPLETED_STORED;
+
+ bool foundOutstanding = false;
+ for (uint32 entryId = 0; entryId<sAchievementCriteriaStore.GetNumRows(); entryId++)
+ {
+ AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(entryId);
+ if(!criteria || criteria->referredAchievement!= entry->ID)
+ continue;
+
+ if(IsCompletedCriteria(criteria) && criteria->completionFlag & ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL)
+ return ACHIEVEMENT_COMPLETED_COMPLETED_NOT_STORED;
+
+ // found an umcompleted criteria, but DONT return false yet - there might be a completed criteria with ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL
+ if(!IsCompletedCriteria(criteria))
+ foundOutstanding = true;
+ }
+ if(foundOutstanding)
+ return ACHIEVEMENT_COMPLETED_NONE;
+ else
+ return ACHIEVEMENT_COMPLETED_COMPLETED_NOT_STORED;
+}
+
+void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 newValue, bool relative)
+{
+ sLog.outDetail("AchievementMgr::SetCriteriaProgress(%u, %u)", entry->ID, newValue);
+ CriteriaProgress *progress = NULL;
+
+ CriteriaProgressMap::iterator iter = m_criteriaProgress.find(entry->ID);
+
+ if(iter == m_criteriaProgress.end())
+ {
+ // not create record for 0 counter
+ if(newValue == 0)
+ return;
+
+ progress = &m_criteriaProgress[entry->ID];
+ progress->counter = newValue;
+ progress->date = time(NULL);
+ }
+ else
+ {
+ progress = &iter->second;
+ if(relative)
+ newValue += progress->counter;
+
+ // not update (not mark as changed) if counter will have same value
+ if(progress->counter == newValue)
+ return;
+
+ progress->counter = newValue;
+ }
+
+ progress->changed = true;
+
+ if(entry->timeLimit)
+ {
+ time_t now = time(NULL);
+ if(progress->date + entry->timeLimit < now)
+ {
+ progress->counter = 1;
+ }
+ // also it seems illogical, the timeframe will be extended at every criteria update
+ progress->date = now;
+ }
+ SendCriteriaUpdate(entry->ID,progress);
+}
+
+void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement)
+{
+ sLog.outDetail("AchievementMgr::CompletedAchievement(%u)", achievement->ID);
+ if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER || m_completedAchievements.find(achievement->ID)!=m_completedAchievements.end())
+ return;
+
+ SendAchievementEarned(achievement);
+ CompletedAchievementData& ca = m_completedAchievements[achievement->ID];
+ ca.date = time(NULL);
+ ca.changed = true;
+
+ // don't insert for ACHIEVEMENT_FLAG_REALM_FIRST_KILL since otherwise only the first group member would reach that achievement
+ // TODO: where do set this instead?
+ if(!(achievement->flags & ACHIEVEMENT_FLAG_REALM_FIRST_KILL))
+ achievementmgr.SetRealmCompleted(achievement);
+
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT);
+
+ // reward items and titles if any
+ AchievementReward const* reward = achievementmgr.GetAchievementReward(achievement);
+
+ // no rewards
+ if(!reward)
+ return;
+
+ // titles
+ if(uint32 titleId = reward->titleId[GetPlayer()->GetTeam() == HORDE?0:1])
+ {
+ if(CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(titleId))
+ GetPlayer()->SetTitle(titleEntry);
+ }
+
+ // mail
+ if(reward->sender)
+ {
+ Item* item = reward->itemId ? Item::CreateItem(reward->itemId,1,GetPlayer ()) : NULL;
+
+ MailItemsInfo mi;
+ if(item)
+ {
+ // save new item before send
+ item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
+
+ // item
+ mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item);
+ }
+
+ int loc_idx = GetPlayer()->GetSession()->GetSessionDbLocaleIndex();
+
+ // subject and text
+ std::string subject = reward->subject;
+ std::string text = reward->text;
+ if ( loc_idx >= 0 )
+ {
+ if(AchievementRewardLocale const* loc = achievementmgr.GetAchievementRewardLocale(achievement))
+ {
+ if (loc->subject.size() > size_t(loc_idx) && !loc->subject[loc_idx].empty())
+ subject = loc->subject[loc_idx];
+ if (loc->text.size() > size_t(loc_idx) && !loc->text[loc_idx].empty())
+ text = loc->text[loc_idx];
+ }
+ }
+
+ uint32 itemTextId = objmgr.CreateItemText( text );
+
+ WorldSession::SendMailTo(GetPlayer(), MAIL_CREATURE, MAIL_STATIONERY_NORMAL, reward->sender, GetPlayer()->GetGUIDLow(), subject, itemTextId , &mi, 0, 0, MAIL_CHECK_MASK_NONE);
+ }
+}
+
+void AchievementMgr::SendAllAchievementData()
+{
+ // since we don't know the exact size of the packed GUIDs this is just an approximation
+ WorldPacket data(SMSG_ALL_ACHIEVEMENT_DATA, 4*2+m_completedAchievements.size()*4*2+m_completedAchievements.size()*7*4);
+ BuildAllDataPacket(&data);
+ GetPlayer()->GetSession()->SendPacket(&data);
+}
+
+void AchievementMgr::SendRespondInspectAchievements(Player* player)
+{
+ // since we don't know the exact size of the packed GUIDs this is just an approximation
+ WorldPacket data(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, 4+4*2+m_completedAchievements.size()*4*2+m_completedAchievements.size()*7*4);
+ data.append(GetPlayer()->GetPackGUID());
+ BuildAllDataPacket(&data);
+ player->GetSession()->SendPacket(&data);
+}
+
+/**
+ * used by both SMSG_ALL_ACHIEVEMENT_DATA and SMSG_RESPOND_INSPECT_ACHIEVEMENT
+ */
+void AchievementMgr::BuildAllDataPacket(WorldPacket *data)
+{
+ for(CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); iter!=m_completedAchievements.end(); ++iter)
+ {
+ *data << uint32(iter->first);
+ *data << uint32(secsToTimeBitFields(iter->second.date));
+ }
+ *data << int32(-1);
+
+ for(CriteriaProgressMap::const_iterator iter = m_criteriaProgress.begin(); iter!=m_criteriaProgress.end(); ++iter)
+ {
+ *data << uint32(iter->first);
+ data->appendPackGUID(iter->second.counter);
+ data->append(GetPlayer()->GetPackGUID());
+ *data << uint32(0);
+ *data << uint32(secsToTimeBitFields(iter->second.date));
+ *data << uint32(0);
+ *data << uint32(0);
+ }
+
+ *data << int32(-1);
+}
+
+//==========================================================
+AchievementCriteriaEntryList const& AchievementGlobalMgr::GetAchievementCriteriaByType(AchievementCriteriaTypes type)
+{
+ return m_AchievementCriteriasByType[type];
+}
+
+void AchievementGlobalMgr::LoadAchievementCriteriaList()
+{
+ if(sAchievementCriteriaStore.GetNumRows()==0)
+ {
+ barGoLink bar(1);
+ bar.step();
+
+ sLog.outString("");
+ sLog.outErrorDb(">> Loaded 0 achievement criteria.");
+ return;
+ }
+
+ barGoLink bar( sAchievementCriteriaStore.GetNumRows() );
+ for (uint32 entryId = 0; entryId<sAchievementCriteriaStore.GetNumRows(); entryId++)
+ {
+ bar.step();
+
+ AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(entryId);
+ if(!criteria)
+ continue;
+
+ m_AchievementCriteriasByType[criteria->requiredType].push_back(criteria);
+ }
+
+ sLog.outString();
+ sLog.outString(">> Loaded %u achievement criteria.",m_AchievementCriteriasByType->size());
+}
+
+
+void AchievementGlobalMgr::LoadCompletedAchievements()
+{
+ QueryResult *result = CharacterDatabase.Query("SELECT achievement FROM character_achievement GROUP BY achievement");
+
+ if(!result)
+ {
+ barGoLink bar(1);
+ bar.step();
+
+ sLog.outString("");
+ sLog.outString(">> Loaded 0 realm completed achievements . DB table `character_achievement` is empty.");
+ return;
+ }
+
+ barGoLink bar(result->GetRowCount());
+ do
+ {
+ bar.step();
+ Field *fields = result->Fetch();
+ m_allCompletedAchievements.insert(fields[0].GetUInt32());
+ } while(result->NextRow());
+
+ delete result;
+
+ sLog.outString("");
+ sLog.outString(">> Loaded %u realm completed achievements.",m_allCompletedAchievements.size());
+}
+
+void AchievementGlobalMgr::LoadRewards()
+{
+ m_achievementRewards.clear(); // need for reload case
+
+ // 0 1 2 3 4 5 6
+ QueryResult *result = WorldDatabase.Query("SELECT entry, title_A, title_H, item, sender, subject, text FROM achievement_reward");
+
+ if(!result)
+ {
+ barGoLink bar(1);
+
+ bar.step();
+
+ sLog.outString("");
+ sLog.outErrorDb(">> Loaded 0 achievement rewards. DB table `achievement_reward` is empty.");
+ return;
+ }
+
+ barGoLink bar(result->GetRowCount());
+
+ do
+ {
+ bar.step();
+
+ Field *fields = result->Fetch();
+ uint32 entry = fields[0].GetUInt32();
+ if (!sAchievementStore.LookupEntry(entry))
+ {
+ sLog.outErrorDb( "Table `achievement_reward` has wrong achievement (Entry: %u), ignore", entry);
+ continue;
+ }
+
+ AchievementReward reward;
+ reward.titleId[0] = fields[1].GetUInt32();
+ reward.titleId[1] = fields[2].GetUInt32();
+ reward.itemId = fields[3].GetUInt32();
+ reward.sender = fields[4].GetUInt32();
+ reward.subject = fields[5].GetCppString();
+ reward.text = fields[6].GetCppString();
+
+ if ((reward.titleId[0]==0)!=(reward.titleId[1]==0))
+ sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) has title (A: %u H: %u) only for one from teams.", entry, reward.titleId[0], reward.titleId[1]);
+
+ // must be title or mail at least
+ if (!reward.titleId[0] && !reward.titleId[1] && !reward.sender)
+ {
+ sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) not have title or item reward data, ignore.", entry);
+ continue;
+ }
+
+ if (reward.titleId[0])
+ {
+ CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(reward.titleId[0]);
+ if (!titleEntry)
+ {
+ sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) has invalid title id (%u) in `title_A`, set to 0", entry, reward.titleId[0]);
+ reward.titleId[0] = 0;
+ }
+ }
+
+ if (reward.titleId[1])
+ {
+ CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(reward.titleId[1]);
+ if (!titleEntry)
+ {
+ sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) has invalid title id (%u) in `title_A`, set to 0", entry, reward.titleId[1]);
+ reward.titleId[1] = 0;
+ }
+ }
+
+ //check mail data before item for report including wrong item case
+ if (reward.sender)
+ {
+ if (!objmgr.GetCreatureTemplate(reward.sender))
+ {
+ sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) has invalid creature entry %u as sender, mail reward skipped.", entry, reward.sender);
+ reward.sender = 0;
+ }
+ }
+ else
+ {
+ if (reward.itemId)
+ sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) not have sender data but have item reward, item will not rewarded", entry);
+
+ if (!reward.subject.empty())
+ sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) not have sender data but have mail subject.", entry);
+
+ if (!reward.text.empty())
+ sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) not have sender data but have mail text.", entry);
+ }
+
+ if (reward.itemId)
+ {
+ if (!objmgr.GetItemPrototype(reward.itemId))
+ {
+ sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) has invalid item id %u, reward mail will be without item.", entry, reward.itemId);
+ reward.itemId = 0;
+ }
+ }
+
+ m_achievementRewards[entry] = reward;
+
+ } while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u achievement reward locale strings", m_achievementRewardLocales.size() );
+}
+
+void AchievementGlobalMgr::LoadRewardLocales()
+{
+ m_achievementRewardLocales.clear(); // need for reload case
+
+ QueryResult *result = WorldDatabase.Query("SELECT entry,subject_loc1,text_loc1,subject_loc2,text_loc2,subject_loc3,text_loc3,subject_loc4,text_loc4,subject_loc5,text_loc5,subject_loc6,text_loc6,subject_loc7,text_loc7,subject_loc8,text_loc8 FROM locales_achievement_reward");
+
+ if(!result)
+ {
+ barGoLink bar(1);
+
+ bar.step();
+
+ sLog.outString("");
+ sLog.outString(">> Loaded 0 achievement reward locale strings. DB table `locales_achievement_reward` is empty.");
+ return;
+ }
+
+ barGoLink bar(result->GetRowCount());
+
+ do
+ {
+ Field *fields = result->Fetch();
+ bar.step();
+
+ uint32 entry = fields[0].GetUInt32();
+
+ if(m_achievementRewards.find(entry)==m_achievementRewards.end())
+ {
+ sLog.outErrorDb( "Table `locales_achievement_reward` (Entry: %u) has locale strings for not existed achievement reward .", entry);
+ continue;
+ }
+
+ AchievementRewardLocale& data = m_achievementRewardLocales[entry];
+
+ for(int i = 1; i < MAX_LOCALE; ++i)
+ {
+ std::string str = fields[1+2*(i-1)].GetCppString();
+ if(!str.empty())
+ {
+ int idx = objmgr.GetOrNewIndexForLocale(LocaleConstant(i));
+ if(idx >= 0)
+ {
+ if(data.subject.size() <= idx)
+ data.subject.resize(idx+1);
+
+ data.subject[idx] = str;
+ }
+ }
+ str = fields[1+2*(i-1)+1].GetCppString();
+ if(!str.empty())
+ {
+ int idx = objmgr.GetOrNewIndexForLocale(LocaleConstant(i));
+ if(idx >= 0)
+ {
+ if(data.text.size() <= idx)
+ data.text.resize(idx+1);
+
+ data.text[idx] = str;
+ }
+ }
+ }
+ } while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u achievement reward locale strings", m_achievementRewardLocales.size() );
+}
diff --git a/src/game/AchievementMgr.h b/src/game/AchievementMgr.h
new file mode 100644
index 00000000000..aadf1f16bd9
--- /dev/null
+++ b/src/game/AchievementMgr.h
@@ -0,0 +1,176 @@
+/*
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __MANGOS_ACHIEVEMENTMGR_H
+#define __MANGOS_ACHIEVEMENTMGR_H
+
+#include "Common.h"
+#include "Policies/Singleton.h"
+#include "Database/DBCEnums.h"
+#include "Database/DBCStores.h"
+#include "Database/DatabaseEnv.h"
+
+#include <map>
+#include <string>
+
+#define CRITERIA_CAST_SPELL_REQ_COUNT 46
+#define ACHIEVEMENT_REWARD_COUNT 57
+
+typedef std::list<const AchievementCriteriaEntry*> AchievementCriteriaEntryList;
+
+struct CriteriaProgress
+{
+ uint32 counter;
+ time_t date;
+ bool changed;
+};
+
+struct CriteriaCastSpellRequirement
+{
+ uint32 achievementCriteriaId;
+ uint32 creatureEntry;
+ uint8 playerClass;
+ uint8 playerRace;
+};
+
+struct AchievementReward
+{
+ uint32 titleId[2];
+ uint32 itemId;
+ uint32 sender;
+ std::string subject;
+ std::string text;
+};
+
+typedef std::map<uint32,AchievementReward> AchievementRewards;
+
+struct AchievementRewardLocale
+{
+ std::vector<std::string> subject;
+ std::vector<std::string> text;
+};
+
+typedef std::map<uint32,AchievementRewardLocale> AchievementRewardLocales;
+
+
+struct CompletedAchievementData
+{
+ time_t date;
+ bool changed;
+};
+
+typedef UNORDERED_MAP<uint32, CriteriaProgress> CriteriaProgressMap;
+typedef UNORDERED_MAP<uint32, CompletedAchievementData> CompletedAchievementMap;
+
+class Unit;
+class Player;
+class WorldPacket;
+
+enum AchievementCompletionState
+{
+ ACHIEVEMENT_COMPLETED_NONE,
+ ACHIEVEMENT_COMPLETED_COMPLETED_NOT_STORED,
+ ACHIEVEMENT_COMPLETED_COMPLETED_STORED,
+};
+
+class AchievementMgr
+{
+ public:
+ AchievementMgr(Player* pl);
+ ~AchievementMgr();
+
+ void Reset();
+ static void DeleteFromDB(uint32 lowguid);
+ void LoadFromDB(QueryResult *achievementResult, QueryResult *criteriaResult);
+ void SaveToDB();
+ void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1=0, uint32 miscvalue2=0, Unit *unit=NULL, uint32 time=0);
+ void CheckAllAchievementCriteria();
+ void SendAllAchievementData();
+ void SendRespondInspectAchievements(Player* player);
+ Player* GetPlayer() { return m_player;}
+
+ private:
+ void SendAchievementEarned(AchievementEntry const* achievement);
+ void SendCriteriaUpdate(uint32 id, CriteriaProgress const* progress);
+ void SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 newValue, bool relative=false);
+ void CompletedCriteria(AchievementCriteriaEntry const* entry);
+ void CompletedAchievement(AchievementEntry const* entry);
+ bool IsCompletedCriteria(AchievementCriteriaEntry const* entry);
+ AchievementCompletionState GetAchievementCompletionState(AchievementEntry const* entry);
+ void BuildAllDataPacket(WorldPacket *data);
+
+ Player* m_player;
+ CriteriaProgressMap m_criteriaProgress;
+ CompletedAchievementMap m_completedAchievements;
+};
+
+class AchievementGlobalMgr
+{
+ public:
+ AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type);
+
+ AchievementReward const* GetAchievementReward(AchievementEntry const* achievement) const
+ {
+ AchievementRewards::const_iterator iter = m_achievementRewards.find(achievement->ID);
+ return iter!=m_achievementRewards.end() ? &iter->second : NULL;
+ }
+
+ AchievementRewardLocale const* GetAchievementRewardLocale(AchievementEntry const* achievement) const
+ {
+ AchievementRewardLocales::const_iterator iter = m_achievementRewardLocales.find(achievement->ID);
+ return iter!=m_achievementRewardLocales.end() ? &iter->second : NULL;
+ }
+
+ static CriteriaCastSpellRequirement const * GetCriteriaCastSpellRequirement(AchievementCriteriaEntry const *achievementCriteria)
+ {
+ for (uint32 i=0; i < CRITERIA_CAST_SPELL_REQ_COUNT; ++i)
+ if (m_criteriaCastSpellRequirements[i].achievementCriteriaId == achievementCriteria->ID)
+ return &m_criteriaCastSpellRequirements[i];
+
+ return NULL;
+ }
+
+ bool IsRealmCompleted(AchievementEntry const* achievement) const
+ {
+ return m_allCompletedAchievements.find(achievement->ID) != m_allCompletedAchievements.end();
+ }
+
+ void SetRealmCompleted(AchievementEntry const* achievement)
+ {
+ m_allCompletedAchievements.insert(achievement->ID);
+ }
+
+ void LoadAchievementCriteriaList();
+ void LoadCompletedAchievements();
+ void LoadRewards();
+ void LoadRewardLocales();
+ private:
+ static const CriteriaCastSpellRequirement m_criteriaCastSpellRequirements[];
+
+ // store achievement criterias by type to speed up lookup
+ AchievementCriteriaEntryList m_AchievementCriteriasByType[ACHIEVEMENT_CRITERIA_TYPE_TOTAL];
+
+ typedef std::set<uint32> AllCompletedAchievements;
+ AllCompletedAchievements m_allCompletedAchievements;
+
+ AchievementRewards m_achievementRewards;
+ AchievementRewardLocales m_achievementRewardLocales;
+};
+
+#define achievementmgr Trinity::Singleton<AchievementGlobalMgr>::Instance()
+
+#endif
diff --git a/src/game/AddonHandler.cpp b/src/game/AddonHandler.cpp
index 74bb4d9d6bc..1372f9c323c 100644
--- a/src/game/AddonHandler.cpp
+++ b/src/game/AddonHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -66,63 +66,84 @@ bool AddonHandler::BuildAddonPacket(WorldPacket *Source, WorldPacket *Target)
if (Source->rpos() + 4 > Source->size())
return false;
- *Source >> TempValue; //get real size of the packed structure
+ *Source >> TempValue; // get real size of the packed structure
// empty addon packet, nothing process, can't be received from real client
if(!TempValue)
return false;
- AddonRealSize = TempValue; //temp value because ZLIB only excepts uLongf
+ AddonRealSize = TempValue; // temp value because ZLIB only excepts uLongf
- CurrentPosition = Source->rpos(); //get the position of the pointer in the structure
+ CurrentPosition = Source->rpos(); // get the position of the pointer in the structure
- AddOnPacked.resize(AddonRealSize); //resize target for zlib action
+ AddOnPacked.resize(AddonRealSize); // resize target for zlib action
if (!uncompress(const_cast<uint8*>(AddOnPacked.contents()), &AddonRealSize, const_cast<uint8*>((*Source).contents() + CurrentPosition), (*Source).size() - CurrentPosition)!= Z_OK)
{
Target->Initialize(SMSG_ADDON_INFO);
- while(AddOnPacked.rpos() < AddOnPacked.size())
+ uint32 addonsCount;
+ AddOnPacked >> addonsCount; // addons count?
+
+ for(uint32 i = 0; i < addonsCount; ++i)
{
- std::string AddonNames;
- uint8 unk6;
- uint32 crc, unk7;
+ std::string addonName;
+ uint8 enabled;
+ uint32 crc, unk2;
// check next addon data format correctness
- if(AddOnPacked.rpos()+1+4+4+1 > AddOnPacked.size())
+ if(AddOnPacked.rpos()+1 > AddOnPacked.size())
return false;
- AddOnPacked >> AddonNames;
+ AddOnPacked >> addonName;
// recheck next addon data format correctness
- if(AddOnPacked.rpos()+4+4+1 > AddOnPacked.size())
+ if(AddOnPacked.rpos()+1+4+4 > AddOnPacked.size())
return false;
- AddOnPacked >> crc >> unk7 >> unk6;
+ AddOnPacked >> enabled >> crc >> unk2;
- //sLog.outDebug("ADDON: Name:%s CRC:%x Unknown1 :%x Unknown2 :%x", AddonNames.c_str(), crc, unk7, unk6);
+ sLog.outDebug("ADDON: Name: %s, Enabled: 0x%x, CRC: 0x%x, Unknown2: 0x%x", addonName.c_str(), enabled, crc, unk2);
- *Target << (uint8)2;
+ uint8 state = (enabled ? 2 : 1);
+ *Target << uint8(state);
- uint8 unk1 = 1;
- *Target << (uint8)unk1;
+ uint8 unk1 = (enabled ? 1 : 0);
+ *Target << uint8(unk1);
if (unk1)
{
- uint8 unk2 = crc != 0x1c776d01LL; //If addon is Standard addon CRC
- *Target << (uint8)unk2;
+ uint8 unk2 = (crc != 0x4c1c776d); // If addon is Standard addon CRC
+ *Target << uint8(unk2);
if (unk2)
Target->append(tdata, sizeof(tdata));
- *Target << (uint32)0;
+ *Target << uint32(0);
}
- uint8 unk3 = 0;
- *Target << (uint8)unk3;
+ uint8 unk3 = (enabled ? 0 : 1);
+ *Target << uint8(unk3);
if (unk3)
{
- // String, 256
+ // String, 256 (null terminated?)
+ *Target << uint8(0);
}
}
+
+ uint32 unk4;
+ AddOnPacked >> unk4;
+
+ uint32 count = 0;
+ *Target << uint32(count);
+ /*for(uint32 i = 0; i < count; ++i)
+ {
+ uint32
+ string (16 bytes)
+ string (16 bytes)
+ uint32
+ }*/
+
+ if(AddOnPacked.rpos() != AddOnPacked.size())
+ sLog.outDebug("packet under read!");
}
else
{
diff --git a/src/game/AddonHandler.h b/src/game/AddonHandler.h
index 6a3b6d21c83..78305db42bd 100644
--- a/src/game/AddonHandler.h
+++ b/src/game/AddonHandler.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/AggressorAI.cpp b/src/game/AggressorAI.cpp
index 65dd1849217..441a526fd3b 100644
--- a/src/game/AggressorAI.cpp
+++ b/src/game/AggressorAI.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/AggressorAI.h b/src/game/AggressorAI.h
index e50a4c0ece3..ef8e081a30f 100644
--- a/src/game/AggressorAI.h
+++ b/src/game/AggressorAI.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/AnimalRandomMovementGenerator.h b/src/game/AnimalRandomMovementGenerator.h
index 8f467dfe632..86a70d0279a 100644
--- a/src/game/AnimalRandomMovementGenerator.h
+++ b/src/game/AnimalRandomMovementGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/ArenaTeam.cpp b/src/game/ArenaTeam.cpp
index 5f1dfdb93d7..3765d5e731a 100644
--- a/src/game/ArenaTeam.cpp
+++ b/src/game/ArenaTeam.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
+ * 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
@@ -304,8 +304,11 @@ void ArenaTeam::Roster(WorldSession *session)
{
Player *pl = NULL;
+ uint8 unk308 = 0;
+
WorldPacket data(SMSG_ARENA_TEAM_ROSTER, 100);
data << uint32(GetId()); // arena team id
+ data << uint8(unk308); // 308 unknown value but affect packet structure
data << uint32(GetMembersSize()); // members count
data << uint32(GetType()); // arena team type?
@@ -313,18 +316,24 @@ void ArenaTeam::Roster(WorldSession *session)
{
pl = objmgr.GetPlayer(itr->guid);
- data << uint64(itr->guid); // guid
- data << uint8((pl ? 1 : 0)); // online flag
- data << itr->name; // member name
+ data << uint64(itr->guid); // guid
+ data << uint8((pl ? 1 : 0)); // online flag
+ data << itr->name; // member name
data << uint32((itr->guid == GetCaptain() ? 0 : 1));// captain flag 0 captain 1 member
- data << uint8((pl ? pl->getLevel() : 0)); // unknown, level?
- data << uint8(itr->Class); // class
- data << uint32(itr->games_week); // played this week
- data << uint32(itr->wins_week); // wins this week
- data << uint32(itr->games_season); // played this season
- data << uint32(itr->wins_season); // wins this season
- data << uint32(itr->personal_rating); // personal rating
+ data << uint8((pl ? pl->getLevel() : 0)); // unknown, level?
+ data << uint8(itr->Class); // class
+ data << uint32(itr->games_week); // played this week
+ data << uint32(itr->wins_week); // wins this week
+ data << uint32(itr->games_season); // played this season
+ data << uint32(itr->wins_season); // wins this season
+ data << uint32(itr->personal_rating); // personal rating
+ if(unk308)
+ {
+ data << float(0.0); // 308 unk
+ data << float(0.0); // 308 unk
+ }
}
+
session->SendPacket(&data);
sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_ROSTER");
}
@@ -641,6 +650,19 @@ void ArenaTeam::FinishWeek()
}
}
+bool ArenaTeam::IsFighting() const
+{
+ for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
+ {
+ if (Player *p = objmgr.GetPlayer(itr->guid))
+ {
+ if (p->GetMap()->IsBattleArena())
+ return true;
+ }
+ }
+ return false;
+}
+
/*
arenateam fields (id from 2.3.3 client):
1414 - arena team id 2v2
diff --git a/src/game/ArenaTeam.h b/src/game/ArenaTeam.h
index 3c6972cdcd0..4b839401e12 100644
--- a/src/game/ArenaTeam.h
+++ b/src/game/ArenaTeam.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -179,18 +179,7 @@ class ArenaTeam
return NULL;
}
- bool IsFighting() const
- {
- for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
- {
- if (Player *p = objmgr.GetPlayer(itr->guid))
- {
- if (p->GetMap()->IsBattleArena())
- return true;
- }
- }
- return false;
- }
+ bool IsFighting() const;
bool LoadArenaTeamFromDB(uint32 ArenaTeamId);
void LoadMembersFromDB(uint32 ArenaTeamId);
diff --git a/src/game/ArenaTeamHandler.cpp b/src/game/ArenaTeamHandler.cpp
index d2c9f54d04b..56c9a219a73 100644
--- a/src/game/ArenaTeamHandler.cpp
+++ b/src/game/ArenaTeamHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -173,7 +173,7 @@ void WorldSession::HandleArenaTeamInviteAcceptOpcode(WorldPacket & /*recv_data*/
if(!at)
return;
- if(_player->GetArenaTeamIdFromDB(_player->GetGUIDLow(), at->GetType()))
+ if(_player->GetArenaTeamId(at->GetSlot()))
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S,"","",ERR_ALREADY_IN_ARENA_TEAM); // already in arena team that size
return;
diff --git a/src/game/AuctionHouse.cpp b/src/game/AuctionHouse.cpp
index c200c9751a6..b9bafdf0eb6 100644
--- a/src/game/AuctionHouse.cpp
+++ b/src/game/AuctionHouse.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -55,21 +55,21 @@ void WorldSession::HandleAuctionHelloOpcode( WorldPacket & recv_data )
SendAuctionHello(guid, unit);
}
-static uint8 AuctioneerFactionToLocation(uint32 faction)
+static AuctionLocation AuctioneerFactionToLocation(uint32 faction)
{
if(sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
- return 7; // neutral
+ return AUCTION_NEUTRAL;
FactionTemplateEntry const* u_entry = sFactionTemplateStore.LookupEntry(faction);
if(!u_entry)
- return 7; // neutral
+ return AUCTION_NEUTRAL;
if(u_entry->ourMask & FACTION_MASK_ALLIANCE)
- return 2;
+ return AUCTION_ALLIANCE;
else if(u_entry->ourMask & FACTION_MASK_HORDE)
- return 6;
+ return AUCTION_HORDE;
else
- return 7;
+ return AUCTION_NEUTRAL;
}
//this void causes that auction window is opened
@@ -132,13 +132,13 @@ void WorldSession::SendAuctionCommandResult(uint32 auctionId, uint32 Action, uin
void WorldSession::SendAuctionBidderNotification( uint32 location, uint32 auctionId, uint64 bidder, uint32 bidSum, uint32 diff, uint32 item_template)
{
WorldPacket data(SMSG_AUCTION_BIDDER_NOTIFICATION, (8*4));
- data << location;
- data << auctionId;
- data << (uint64) bidder;
- data << bidSum;
- data << (uint32) diff;
- data << item_template;
- data << (uint32) 0;
+ data << uint32(location);
+ data << uint32(auctionId);
+ data << uint64(bidder);
+ data << uint32(bidSum);
+ data << uint32(diff);
+ data << uint32(item_template);
+ data << uint32(0);
SendPacket(&data);
}
@@ -268,7 +268,7 @@ void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data )
return;
}
- uint32 location = AuctioneerFactionToLocation(pCreature->getFaction());
+ AuctionLocation location = AuctioneerFactionToLocation(pCreature->getFaction());
AuctionHouseObject * mAuctions;
mAuctions = objmgr.GetAuctionsMap( location );
@@ -347,7 +347,7 @@ void WorldSession::HandleAuctionPlaceBid( WorldPacket & recv_data )
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
- uint32 location = AuctioneerFactionToLocation(pCreature->getFaction());
+ AuctionLocation location = AuctioneerFactionToLocation(pCreature->getFaction());
AuctionHouseObject * mAuctions;
mAuctions = objmgr.GetAuctionsMap( location );
@@ -474,7 +474,7 @@ void WorldSession::HandleAuctionRemoveItem( WorldPacket & recv_data )
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
- uint32 location = AuctioneerFactionToLocation(pCreature->getFaction());
+ AuctionLocation location = AuctioneerFactionToLocation(pCreature->getFaction());
AuctionHouseObject * mAuctions;
mAuctions = objmgr.GetAuctionsMap( location );
@@ -562,7 +562,7 @@ void WorldSession::HandleAuctionListBidderItems( WorldPacket & recv_data )
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
- uint32 location = AuctioneerFactionToLocation(pCreature->getFaction());
+ AuctionLocation location = AuctioneerFactionToLocation(pCreature->getFaction());
AuctionHouseObject* mAuctions = objmgr.GetAuctionsMap( location );
WorldPacket data( SMSG_AUCTION_BIDDER_LIST_RESULT, (4+4+4) );
@@ -582,7 +582,7 @@ void WorldSession::HandleAuctionListBidderItems( WorldPacket & recv_data )
++count;
}
}
- for (AuctionHouseObject::AuctionEntryMap::iterator itr = mAuctions->GetAuctionsBegin();itr != mAuctions->GetAuctionsEnd();++itr)
+ for (AuctionHouseObject::AuctionEntryMap::const_iterator itr = mAuctions->GetAuctionsBegin();itr != mAuctions->GetAuctionsEnd();++itr)
{
AuctionEntry *Aentry = itr->second;
if( Aentry && Aentry->bidder == pl->GetGUIDLow() )
@@ -620,7 +620,7 @@ void WorldSession::HandleAuctionListOwnerItems( WorldPacket & recv_data )
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
- uint32 location = AuctioneerFactionToLocation(pCreature->getFaction());
+ AuctionLocation location = AuctioneerFactionToLocation(pCreature->getFaction());
AuctionHouseObject* mAuctions = objmgr.GetAuctionsMap( location );
@@ -629,7 +629,7 @@ void WorldSession::HandleAuctionListOwnerItems( WorldPacket & recv_data )
uint32 count = 0;
uint32 totalcount = 0;
- for (AuctionHouseObject::AuctionEntryMap::iterator itr = mAuctions->GetAuctionsBegin();itr != mAuctions->GetAuctionsEnd();++itr)
+ for (AuctionHouseObject::AuctionEntryMap::const_iterator itr = mAuctions->GetAuctionsBegin();itr != mAuctions->GetAuctionsEnd();++itr)
{
AuctionEntry *Aentry = itr->second;
if( Aentry && Aentry->owner == _player->GetGUIDLow() )
@@ -650,9 +650,9 @@ void WorldSession::HandleAuctionListItems( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE(recv_data,8+4+1+1+1+4+4+4+4+1);
- std::string searchedname, name;
- uint8 levelmin, levelmax, usable, location;
- uint32 count, totalcount, listfrom, auctionSlotID, auctionMainCategory, auctionSubCategory, quality;
+ std::string searchedname;
+ uint8 levelmin, levelmax, usable;
+ uint32 listfrom, auctionSlotID, auctionMainCategory, auctionSubCategory, quality;
uint64 guid;
recv_data >> guid;
@@ -677,15 +677,14 @@ void WorldSession::HandleAuctionListItems( WorldPacket & recv_data )
if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
- location = AuctioneerFactionToLocation(pCreature->getFaction());
- AuctionHouseObject * mAuctions;
- mAuctions = objmgr.GetAuctionsMap( location );
+ AuctionLocation location = AuctioneerFactionToLocation(pCreature->getFaction());
+ AuctionHouseObject * mAuctions = objmgr.GetAuctionsMap( location );
//sLog.outDebug("Auctionhouse search guid: " I64FMTD ", list from: %u, searchedname: %s, levelmin: %u, levelmax: %u, auctionSlotID: %u, auctionMainCategory: %u, auctionSubCategory: %u, quality: %u, usable: %u", guid, listfrom, searchedname.c_str(), levelmin, levelmax, auctionSlotID, auctionMainCategory, auctionSubCategory, quality, usable);
WorldPacket data( SMSG_AUCTION_LIST_RESULT, (4+4+4) );
- count = 0;
- totalcount = 0;
+ uint32 count = 0;
+ uint32 totalcount = 0;
data << (uint32) 0;
// converting string that we try to find to lower case
@@ -695,7 +694,7 @@ void WorldSession::HandleAuctionListItems( WorldPacket & recv_data )
wstrToLower(wsearchedname);
- for (AuctionHouseObject::AuctionEntryMap::iterator itr = mAuctions->GetAuctionsBegin();itr != mAuctions->GetAuctionsEnd();++itr)
+ for (AuctionHouseObject::AuctionEntryMap::const_iterator itr = mAuctions->GetAuctionsBegin();itr != mAuctions->GetAuctionsEnd();++itr)
{
AuctionEntry *Aentry = itr->second;
Item *item = objmgr.GetAItem(Aentry->item_guidlow);
@@ -716,7 +715,7 @@ void WorldSession::HandleAuctionListItems( WorldPacket & recv_data )
{
if( ( levelmin == (0x00) || proto->RequiredLevel >= levelmin ) && ( levelmax == (0x00) || proto->RequiredLevel <= levelmax ) )
{
- name = proto->Name1;
+ std::string name = proto->Name1;
// local name
int loc_idx = GetSessionDbLocaleIndex();
@@ -756,3 +755,23 @@ void WorldSession::HandleAuctionListItems( WorldPacket & recv_data )
data << (uint32) 300; // unk 2.3.0 const?
SendPacket(&data);
}
+
+void WorldSession::HandleAuctionListPendingSales( WorldPacket & recv_data )
+{
+ sLog.outDebug("CMSG_AUCTION_LIST_PENDING_SALES");
+ recv_data.hexlike();
+
+ uint32 count = 0;
+
+ WorldPacket data(SMSG_AUCTION_LIST_PENDING_SALES, 4);
+ data << uint32(count); // count
+ /*for(uint32 i = 0; i < count; ++i)
+ {
+ data << ""; // string
+ data << ""; // string
+ data << uint32(0);
+ data << uint32(0);
+ data << float(0);
+ }*/
+ SendPacket(&data);
+}
diff --git a/src/game/AuctionHouseBot.cpp b/src/game/AuctionHouseBot.cpp
index f05d31abb41..4830dcefce4 100644
--- a/src/game/AuctionHouseBot.cpp
+++ b/src/game/AuctionHouseBot.cpp
@@ -1,4 +1,3 @@
-#include "AuctionHouseBot.h"
#include "Bag.h"
#include "Config/ConfigEnv.h"
#include "Database/DatabaseEnv.h"
@@ -9,6 +8,7 @@
#include "World.h"
#include "WorldSession.h"
#include "time.h"
+#include "AuctionHouseBot.h"
#include <vector>
#include <iostream>
@@ -40,9 +40,9 @@ static bool Bind_When_Equipped = 0;
static bool Bind_When_Use = 0;
static bool Bind_Quest_Item = 0;
-static AHBConfig AllianceConfig = AHBConfig(2);
-static AHBConfig HordeConfig = AHBConfig(6);
-static AHBConfig NeutralConfig = AHBConfig(7);
+static AHBConfig AllianceConfig = AHBConfig(AUCTION_ALLIANCE);
+static AHBConfig HordeConfig = AHBConfig(AUCTION_HORDE);
+static AHBConfig NeutralConfig = AHBConfig(AUCTION_NEUTRAL);
time_t _lastrun_a;
time_t _lastrun_h;
time_t _lastrun_n;
@@ -905,18 +905,18 @@ void AuctionHouseBotInit()
sLog.outString("AuctionHouseBot now includes AHBuyer by Kerbe and Paradox");
}
-void AuctionHouseBotCommands(uint32 command, uint32 ahMapID, uint32 col, char* args)
+void AuctionHouseBotCommands(uint32 command, AuctionLocation ahMapID, uint32 col, char* args)
{
AHBConfig *config;
switch (ahMapID)
{
- case 2:
+ case AUCTION_ALLIANCE:
config = &AllianceConfig;
break;
- case 6:
+ case AUCTION_HORDE:
config = &HordeConfig;
break;
- case 7:
+ case AUCTION_NEUTRAL:
config = &NeutralConfig;
break;
}
diff --git a/src/game/AuctionHouseBot.h b/src/game/AuctionHouseBot.h
index 71b14d17a4a..afb3e15e968 100644
--- a/src/game/AuctionHouseBot.h
+++ b/src/game/AuctionHouseBot.h
@@ -3,6 +3,7 @@
#include "Common.h"
#include "Log.h"
#include "Config/ConfigEnv.h"
+#include "AuctionHouseObject.h"
#define AHB_GREY 0
#define AHB_WHITE 1
#define AHB_GREEN 2
@@ -27,7 +28,7 @@
class AHBConfig
{
private:
- uint32 AHID;
+ AuctionLocation AHID;
uint32 minItems;
uint32 maxItems;
uint32 minTime;
@@ -78,14 +79,14 @@ class AHBConfig
uint32 bip;
uint32 pip;
public:
- AHBConfig(uint32 ahid)
+ AHBConfig(AuctionLocation ahid)
{
AHID = ahid;
}
AHBConfig()
{
}
- uint32 GetAHID()
+ AuctionLocation GetAHID()
{
return AHID;
}
@@ -683,5 +684,5 @@ class AHBConfig
void AuctionHouseBot();
void AuctionHouseBotInit();
void AuctionHouseBotLoadValues(AHBConfig*);
-void AuctionHouseBotCommands(uint32, uint32, uint32, char*);
+void AuctionHouseBotCommands(uint32, AuctionLocation, uint32, char*);
#endif
diff --git a/src/game/AuctionHouseObject.h b/src/game/AuctionHouseObject.h
index cccba8413da..f82867c5742 100644
--- a/src/game/AuctionHouseObject.h
+++ b/src/game/AuctionHouseObject.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -41,6 +41,15 @@ enum AuctionAction
AUCTION_PLACE_BID = 2
};
+enum AuctionLocation
+{
+ AUCTION_ALLIANCE = 2,
+ AUCTION_HORDE = 6,
+ AUCTION_NEUTRAL = 7
+};
+
+inline bool IsValidAuctionLocation(uint32 loc) { return loc == AUCTION_ALLIANCE || loc == AUCTION_HORDE || loc == AUCTION_NEUTRAL; }
+
struct AuctionEntry
{
uint32 Id;
@@ -54,7 +63,7 @@ struct AuctionEntry
time_t time;
uint32 bidder;
uint32 deposit; //deposit can be calculated only when creating auction
- uint32 location;
+ AuctionLocation location;
};
//this class is used as auctionhouse instance
@@ -84,20 +93,12 @@ class AuctionHouseObject
AuctionEntry* GetAuction(uint32 id) const
{
AuctionEntryMap::const_iterator itr = AuctionsMap.find( id );
- if( itr != AuctionsMap.end() )
- return itr->second;
- return NULL;
+ return itr != AuctionsMap.end() ? itr->second : NULL;
}
bool RemoveAuction(uint32 id)
{
- AuctionEntryMap::iterator i = AuctionsMap.find(id);
- if (i == AuctionsMap.end())
- {
- return false;
- }
- AuctionsMap.erase(i);
- return true;
+ return AuctionsMap.erase(id) ? true : false;
}
private:
diff --git a/src/game/Bag.cpp b/src/game/Bag.cpp
index 765d40f3962..1293b058d00 100644
--- a/src/game/Bag.cpp
+++ b/src/game/Bag.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -34,7 +34,7 @@ Bag::Bag( ): Item()
m_valuesCount = CONTAINER_END;
- memset(m_bagslot, 0, sizeof(Item *) * MAX_BAG_SIZE); // Maximum 20 Slots
+ memset(m_bagslot, 0, sizeof(Item *) * MAX_BAG_SIZE);
}
Bag::~Bag()
diff --git a/src/game/Bag.h b/src/game/Bag.h
index 97f06917485..6f38057b4ce 100644
--- a/src/game/Bag.h
+++ b/src/game/Bag.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp
index d392f074600..cb122fddbcf 100644
--- a/src/game/BattleGround.cpp
+++ b/src/game/BattleGround.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -21,6 +21,7 @@
#include "Object.h"
#include "Player.h"
#include "BattleGround.h"
+#include "BattleGroundMgr.h"
#include "Creature.h"
#include "MapManager.h"
#include "Language.h"
@@ -28,11 +29,14 @@
#include "SpellAuras.h"
#include "ArenaTeam.h"
#include "World.h"
+#include "Group.h"
+#include "ObjectMgr.h"
+#include "WorldPacket.h"
#include "Util.h"
BattleGround::BattleGround()
{
- m_TypeID = 0;
+ m_TypeID = BattleGroundTypeId(0);
m_InstanceID = 0;
m_Status = 0;
m_EndTime = 0;
@@ -120,7 +124,7 @@ BattleGround::~BattleGround()
this->RemoveFromBGFreeSlotQueue();
}
-void BattleGround::Update(time_t diff)
+void BattleGround::Update(uint32 diff)
{
if(!GetPlayersSize() && !GetRemovedPlayersSize() && !GetReviveQueueSize())
//BG is empty
@@ -161,8 +165,6 @@ void BattleGround::Update(time_t diff)
m_RemovedPlayers.clear();
}
- // this code isn't efficient and its idea isn't implemented yet
- /* offline players are removed from battleground in worldsession::LogoutPlayer()
// remove offline players from bg after ~5 minutes
if(GetPlayersSize())
{
@@ -177,7 +179,7 @@ void BattleGround::Update(time_t diff)
if(itr->second.LastOnlineTime >= MAX_OFFLINE_TIME) // 5 minutes
m_RemovedPlayers[itr->first] = 1; // add to remove list (BG)
}
- }*/
+ }
m_LastResurrectTime += diff;
if (m_LastResurrectTime >= RESURRECTION_INTERVAL)
@@ -573,9 +575,10 @@ void BattleGround::EndBattleGround(uint32 winner)
sBattleGroundMgr.BuildPvpLogDataPacket(&data, this);
plr->GetSession()->SendPacket(&data);
- uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType());
+ uint32 bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType());
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime());
plr->GetSession()->SendPacket(&data);
+ plr->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, 1);
}
if(isArena() && isRated() && winner_arena_team && loser_arena_team)
@@ -593,7 +596,7 @@ void BattleGround::EndBattleGround(uint32 winner)
}
// inform invited players about the removal
- sBattleGroundMgr.m_BattleGroundQueues[sBattleGroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType())].BGEndedRemoveInvites(this);
+ sBattleGroundMgr.m_BattleGroundQueues[BattleGroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType())].BGEndedRemoveInvites(this);
if(Source)
{
@@ -788,8 +791,8 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
{
if(!team) team = plr->GetTeam();
- uint32 bgTypeId = GetTypeID();
- uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType());
+ BattleGroundTypeId bgTypeId = GetTypeID();
+ uint32 bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType());
// if arena, remove the specific arena auras
if(isArena())
{
@@ -865,9 +868,7 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
plr->SetBGTeam(0);
if(Transport)
- {
- plr->TeleportTo(plr->GetBattleGroundEntryPointMap(), plr->GetBattleGroundEntryPointX(), plr->GetBattleGroundEntryPointY(), plr->GetBattleGroundEntryPointZ(), plr->GetBattleGroundEntryPointO());
- }
+ plr->TeleportTo(plr->GetBattleGroundEntryPoint());
// Log
sLog.outDetail("BATTLEGROUND: Removed player %s from BattleGround.", plr->GetName());
@@ -975,7 +976,7 @@ void BattleGround::AddPlayer(Player *plr)
}
(plr)->RemovePet(NULL,PET_SAVE_NOT_IN_SLOT);
}
- else
+ else
(plr)->SetTemporaryUnsummonedPetNumber(0);
if(GetStatus() == STATUS_WAIT_JOIN) // not started yet
@@ -1178,7 +1179,8 @@ bool BattleGround::AddObject(uint32 type, uint32 entry, float x, float y, float
// and when loading it (in go::LoadFromDB()), a new guid would be assigned to the object, and a new object would be created
// so we must create it specific for this instance
GameObject * go = new GameObject;
- if(!go->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT),entry, map,x,y,z,o,rotation0,rotation1,rotation2,rotation3,100,1))
+ if(!go->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT),entry, map,
+ PHASEMASK_NORMAL, x,y,z,o,rotation0,rotation1,rotation2,rotation3,100,1))
{
sLog.outErrorDb("Gameobject template %u not found in database! BattleGround not created!", entry);
sLog.outError("Cannot create gameobject template %u! BattleGround not created!", entry);
@@ -1301,7 +1303,7 @@ Creature* BattleGround::AddCreature(uint32 entry, uint32 type, uint32 teamval, f
return NULL;
Creature* pCreature = new Creature;
- if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, entry, teamval))
+ if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, PHASEMASK_NORMAL, entry, teamval))
{
sLog.outError("Can't create creature entry: %u",entry);
delete pCreature;
@@ -1357,6 +1359,9 @@ void BattleGround::SpawnBGCreature(uint32 type, uint32 respawntime)
*/
bool BattleGround::DelCreature(uint32 type)
{
+ if(!m_BgCreatures[type])
+ return true;
+
Creature *cr = HashMapHolder<Creature>::Find(m_BgCreatures[type]);
if(!cr)
{
@@ -1372,6 +1377,9 @@ bool BattleGround::DelCreature(uint32 type)
bool BattleGround::DelObject(uint32 type)
{
+ if(!m_BgObjects[type])
+ return true;
+
GameObject *obj = HashMapHolder<GameObject>::Find(m_BgObjects[type]);
if(!obj)
{
@@ -1405,10 +1413,12 @@ bool BattleGround::AddSpiritGuide(uint32 type, float x, float y, float z, float
pCreature->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, pCreature->GetGUID());
// aura
- pCreature->SetUInt32Value(UNIT_FIELD_AURA, SPELL_SPIRIT_HEAL_CHANNEL);
- pCreature->SetUInt32Value(UNIT_FIELD_AURAFLAGS, 0x00000009);
- pCreature->SetUInt32Value(UNIT_FIELD_AURALEVELS, 0x0000003C);
- pCreature->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS, 0x000000FF);
+ //TODO: Fix display here
+ //pCreature->SetVisibleAura(0, SPELL_SPIRIT_HEAL_CHANNEL);
+
+ //pCreature->SetUInt32Value(UNIT_FIELD_AURAFLAGS, 0x00000009);
+ //pCreature->SetUInt32Value(UNIT_FIELD_AURALEVELS, 0x0000003C);
+ //pCreature->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS, 0x000000FF);
// casting visual effect
pCreature->SetUInt32Value(UNIT_CHANNEL_SPELL, SPELL_SPIRIT_HEAL_CHANNEL);
// correct cast speed
@@ -1440,7 +1450,7 @@ void BattleGround::EndNow()
SetStatus(STATUS_WAIT_LEAVE);
SetEndTime(TIME_TO_AUTOREMOVE);
// inform invited players about the removal
- sBattleGroundMgr.m_BattleGroundQueues[sBattleGroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType())].BGEndedRemoveInvites(this);
+ sBattleGroundMgr.m_BattleGroundQueues[BattleGroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType())].BGEndedRemoveInvites(this);
}
// Battleground messages are localized using the dbc lang, they are not client language dependent
@@ -1529,6 +1539,31 @@ uint32 BattleGround::GetPlayerTeam(uint64 guid)
return 0;
}
+bool BattleGround::IsPlayerInBattleGround(uint64 guid)
+{
+ std::map<uint64, BattleGroundPlayer>::const_iterator itr = m_Players.find(guid);
+ if(itr!=m_Players.end())
+ return true;
+ return false;
+}
+
+void BattleGround::PlayerRelogin(Player* plr)
+{
+ if(GetStatus() != STATUS_WAIT_LEAVE)
+ return;
+
+ WorldPacket data;
+ uint32 bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType());
+
+ BlockMovement(plr);
+
+ sBattleGroundMgr.BuildPvpLogDataPacket(&data, this);
+ plr->GetSession()->SendPacket(&data);
+
+ sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime());
+ plr->GetSession()->SendPacket(&data);
+}
+
uint32 BattleGround::GetAlivePlayersCountByTeam(uint32 Team) const
{
int count = 0;
@@ -1564,3 +1599,11 @@ int32 BattleGround::GetObjectType(uint64 guid)
void BattleGround::HandleKillUnit(Creature *creature, Player *killer)
{
}
+
+void BattleGround::SetBgRaid( uint32 TeamID, Group *bg_raid )
+{
+ Group* &old_raid = TeamID == ALLIANCE ? m_BgRaids[BG_TEAM_ALLIANCE] : m_BgRaids[BG_TEAM_HORDE];
+ if(old_raid) old_raid->SetBattlegroundGroup(NULL);
+ if(bg_raid) bg_raid->SetBattlegroundGroup(this);
+ old_raid = bg_raid;
+}
diff --git a/src/game/BattleGround.h b/src/game/BattleGround.h
index d1d9cb19f28..e6ab5f1359c 100644
--- a/src/game/BattleGround.h
+++ b/src/game/BattleGround.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -22,13 +22,16 @@
#define __BATTLEGROUND_H
#include "Common.h"
-#include "WorldPacket.h"
-#include "WorldSession.h"
-#include "Opcodes.h"
-#include "ObjectMgr.h"
-#include "BattleGroundMgr.h"
#include "SharedDefines.h"
+class Creature;
+class GameObject;
+class Group;
+class Player;
+class WorldPacket;
+
+struct WorldSafeLocsEntry;
+
enum BattleGroundSounds
{
SOUND_HORDE_WINS = 8454,
@@ -132,20 +135,6 @@ struct BattleGroundObjectInfo
uint32 spellid;
};
-#define MAX_QUEUED_PLAYERS_MAP 7
-
-enum BattleGroundTypeId
-{
- BATTLEGROUND_AV = 1,
- BATTLEGROUND_WS = 2,
- BATTLEGROUND_AB = 3,
- BATTLEGROUND_NA = 4,
- BATTLEGROUND_BE = 5,
- BATTLEGROUND_AA = 6,
- BATTLEGROUND_EY = 7,
- BATTLEGROUND_RL = 8
-};
-
// handle the queue types and bg types separately to enable joining queue for different sized arenas at the same time
enum BattleGroundQueueTypeId
{
@@ -153,9 +142,10 @@ enum BattleGroundQueueTypeId
BATTLEGROUND_QUEUE_WS = 2,
BATTLEGROUND_QUEUE_AB = 3,
BATTLEGROUND_QUEUE_EY = 4,
- BATTLEGROUND_QUEUE_2v2 = 5,
- BATTLEGROUND_QUEUE_3v3 = 6,
- BATTLEGROUND_QUEUE_5v5 = 7,
+ BATTLEGROUND_QUEUE_SA = 5,
+ BATTLEGROUND_QUEUE_2v2 = 6,
+ BATTLEGROUND_QUEUE_3v3 = 7,
+ BATTLEGROUND_QUEUE_5v5 = 8,
};
enum ScoreType
@@ -262,7 +252,7 @@ class BattleGround
BattleGround();
/*BattleGround(const BattleGround& bg);*/
virtual ~BattleGround();
- virtual void Update(time_t diff); // must be implemented in BG subclass of BG specific update code, but must in begginning call parent version
+ virtual void Update(uint32 diff); // must be implemented in BG subclass of BG specific update code, but must in begginning call parent version
virtual bool SetupBattleGround() // must be implemented in BG subclass
{
return true;
@@ -275,7 +265,7 @@ class BattleGround
/* Battleground */
// Get methods:
char const* GetName() const { return m_Name; }
- uint32 GetTypeID() const { return m_TypeID; }
+ BattleGroundTypeId GetTypeID() const { return m_TypeID; }
uint32 GetQueueType() const { return m_Queue_type; }
uint32 GetInstanceID() const { return m_InstanceID; }
uint32 GetStatus() const { return m_Status; }
@@ -298,7 +288,7 @@ class BattleGround
// Set methods:
void SetName(char const* Name) { m_Name = Name; }
- void SetTypeID(uint32 TypeID) { m_TypeID = TypeID; }
+ void SetTypeID(BattleGroundTypeId TypeID) { m_TypeID = TypeID; }
void SetQueueType(uint32 ID) { m_Queue_type = ID; }
void SetInstanceID(uint32 InstanceID) { m_InstanceID = InstanceID; }
void SetStatus(uint32 Status) { m_Status = Status; }
@@ -395,13 +385,7 @@ class BattleGround
/* Raid Group */
Group *GetBgRaid(uint32 TeamID) const { return TeamID == ALLIANCE ? m_BgRaids[BG_TEAM_ALLIANCE] : m_BgRaids[BG_TEAM_HORDE]; }
- void SetBgRaid(uint32 TeamID, Group *bg_raid)
- {
- Group* &old_raid = TeamID == ALLIANCE ? m_BgRaids[BG_TEAM_ALLIANCE] : m_BgRaids[BG_TEAM_HORDE];
- if(old_raid) old_raid->SetBattlegroundGroup(NULL);
- if(bg_raid) bg_raid->SetBattlegroundGroup(this);
- old_raid = bg_raid;
- }
+ void SetBgRaid(uint32 TeamID, Group *bg_raid);
virtual void UpdatePlayerScore(Player *Source, uint32 type, uint32 value);
@@ -468,6 +452,8 @@ class BattleGround
// since arenas can be AvA or Hvh, we have to get the "temporary" team of a player
uint32 GetPlayerTeam(uint64 guid);
+ bool IsPlayerInBattleGround(uint64 guid);
+ void PlayerRelogin(Player* plr);
void SetDeleteThis() {m_SetDeleteThis = true;}
@@ -496,7 +482,7 @@ class BattleGround
BGHonorMode m_HonorMode;
private:
/* Battleground */
- uint32 m_TypeID; //Battleground type, defined in enum BattleGroundTypeId
+ BattleGroundTypeId m_TypeID;
uint32 m_InstanceID; //BattleGround Instance's GUID!
uint32 m_Status;
uint32 m_StartTime;
diff --git a/src/game/BattleGroundAA.cpp b/src/game/BattleGroundAA.cpp
index 8737088894a..fa7a90014ef 100644
--- a/src/game/BattleGroundAA.cpp
+++ b/src/game/BattleGroundAA.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -32,7 +32,7 @@ BattleGroundAA::~BattleGroundAA()
}
-void BattleGroundAA::Update(time_t diff)
+void BattleGroundAA::Update(uint32 diff)
{
BattleGround::Update(diff);
}
diff --git a/src/game/BattleGroundAA.h b/src/game/BattleGroundAA.h
index edddc110600..3d4dad0be9a 100644
--- a/src/game/BattleGroundAA.h
+++ b/src/game/BattleGroundAA.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -37,7 +37,7 @@ class BattleGroundAA : public BattleGround
public:
BattleGroundAA();
~BattleGroundAA();
- void Update(time_t diff);
+ void Update(uint32 diff);
/* inherited from BattlegroundClass */
virtual void AddPlayer(Player *plr);
diff --git a/src/game/BattleGroundAB.cpp b/src/game/BattleGroundAB.cpp
index 00e1090d8d5..e4b0c82882d 100644
--- a/src/game/BattleGroundAB.cpp
+++ b/src/game/BattleGroundAB.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -29,6 +29,7 @@
#include "Language.h"
#include "World.h"
#include "Util.h"
+#include "WorldPacket.h"
// these variables aren't used outside of this file, so declare them only here
uint32 BG_AB_HonorScoreTicks[BG_HONOR_MODE_NUM] = {
@@ -52,7 +53,7 @@ BattleGroundAB::~BattleGroundAB()
{
}
-void BattleGroundAB::Update(time_t diff)
+void BattleGroundAB::Update(uint32 diff)
{
BattleGround::Update(diff);
@@ -425,9 +426,9 @@ void BattleGroundAB::_NodeDeOccupied(uint8 node)
{
WorldSafeLocsEntry const *ClosestGrave = NULL;
Player *plr;
- for (std::vector<uint64>::iterator itr = ghost_list.begin(); itr != ghost_list.end(); ++itr)
+ for (std::vector<uint64>::const_iterator itr = ghost_list.begin(); itr != ghost_list.end(); ++itr)
{
- plr = objmgr.GetPlayer(*ghost_list.begin());
+ plr = objmgr.GetPlayer(*itr);
if( !plr )
continue;
if( !ClosestGrave )
diff --git a/src/game/BattleGroundAB.h b/src/game/BattleGroundAB.h
index 464108d63c9..0844f3b5c4f 100644
--- a/src/game/BattleGroundAB.h
+++ b/src/game/BattleGroundAB.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -238,7 +238,7 @@ class BattleGroundAB : public BattleGround
BattleGroundAB();
~BattleGroundAB();
- void Update(time_t diff);
+ void Update(uint32 diff);
void AddPlayer(Player *plr);
void RemovePlayer(Player *plr,uint64 guid);
void HandleAreaTrigger(Player *Source, uint32 Trigger);
diff --git a/src/game/BattleGroundAV.cpp b/src/game/BattleGroundAV.cpp
index c65ca479712..c8d1ed3b673 100644
--- a/src/game/BattleGroundAV.cpp
+++ b/src/game/BattleGroundAV.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -30,6 +30,7 @@
#include "Language.h"
#include "SpellAuras.h"
#include "Formulas.h"
+#include "WorldPacket.h"
BattleGroundAV::BattleGroundAV()
{
@@ -294,7 +295,7 @@ Creature* BattleGroundAV::AddAVCreature(uint16 cinfoid, uint16 type )
return creature;
}
-void BattleGroundAV::Update(time_t diff)
+void BattleGroundAV::Update(uint32 diff)
{
BattleGround::Update(diff);
if (GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize())
diff --git a/src/game/BattleGroundAV.h b/src/game/BattleGroundAV.h
index e80ad47d869..d4581b07d41 100644
--- a/src/game/BattleGroundAV.h
+++ b/src/game/BattleGroundAV.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -1500,7 +1500,7 @@ class BattleGroundAV : public BattleGround
public:
BattleGroundAV();
~BattleGroundAV();
- void Update(time_t diff);
+ void Update(uint32 diff);
/* inherited from BattlegroundClass */
virtual void AddPlayer(Player *plr);
diff --git a/src/game/BattleGroundBE.cpp b/src/game/BattleGroundBE.cpp
index 6f4ac89c64e..f63c6822c5b 100644
--- a/src/game/BattleGroundBE.cpp
+++ b/src/game/BattleGroundBE.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -25,6 +25,7 @@
#include "Creature.h"
#include "ObjectMgr.h"
#include "MapManager.h"
+#include "WorldPacket.h"
#include "Language.h"
BattleGroundBE::BattleGroundBE()
@@ -37,7 +38,7 @@ BattleGroundBE::~BattleGroundBE()
}
-void BattleGroundBE::Update(time_t diff)
+void BattleGroundBE::Update(uint32 diff)
{
BattleGround::Update(diff);
diff --git a/src/game/BattleGroundBE.h b/src/game/BattleGroundBE.h
index a16464dd31b..a3826fcdd7d 100644
--- a/src/game/BattleGroundBE.h
+++ b/src/game/BattleGroundBE.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -57,7 +57,7 @@ class BattleGroundBE : public BattleGround
public:
BattleGroundBE();
~BattleGroundBE();
- void Update(time_t diff);
+ void Update(uint32 diff);
/* inherited from BattlegroundClass */
virtual void AddPlayer(Player *plr);
diff --git a/src/game/BattleGroundDS.cpp b/src/game/BattleGroundDS.cpp
new file mode 100644
index 00000000000..825a52967b6
--- /dev/null
+++ b/src/game/BattleGroundDS.cpp
@@ -0,0 +1,63 @@
+/*
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "Player.h"
+#include "BattleGround.h"
+#include "BattleGroundDS.h"
+
+BattleGroundDS::BattleGroundDS()
+{
+
+}
+
+BattleGroundDS::~BattleGroundDS()
+{
+
+}
+
+void BattleGroundDS::Update(uint32 diff)
+{
+ BattleGround::Update(diff);
+}
+
+void BattleGroundDS::AddPlayer(Player *plr)
+{
+ BattleGround::AddPlayer(plr);
+ //create score and add it to map, default values are set in constructor
+ BattleGroundDSScore* sc = new BattleGroundDSScore;
+
+ m_PlayerScores[plr->GetGUID()] = sc;
+}
+
+void BattleGroundDS::RemovePlayer(Player * /*plr*/, uint64 /*guid*/)
+{
+}
+
+void BattleGroundDS::HandleKillPlayer(Player* player, Player* killer)
+{
+ BattleGround::HandleKillPlayer(player, killer);
+}
+
+void BattleGroundDS::HandleAreaTrigger(Player * /*Source*/, uint32 /*Trigger*/)
+{
+}
+
+bool BattleGroundDS::SetupBattleGround()
+{
+ return true;
+}
diff --git a/src/game/BattleGroundDS.h b/src/game/BattleGroundDS.h
new file mode 100644
index 00000000000..7f9de8ca7de
--- /dev/null
+++ b/src/game/BattleGroundDS.h
@@ -0,0 +1,47 @@
+/*
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __BATTLEGROUNDDS_H
+#define __BATTLEGROUNDDS_H
+
+class BattleGround;
+
+class BattleGroundDSScore : public BattleGroundScore
+{
+ public:
+ BattleGroundDSScore() {};
+ virtual ~BattleGroundDSScore() {};
+ //TODO fix me
+};
+
+class BattleGroundDS : public BattleGround
+{
+ friend class BattleGroundMgr;
+
+ public:
+ BattleGroundDS();
+ ~BattleGroundDS();
+ void Update(uint32 diff);
+
+ /* inherited from BattlegroundClass */
+ virtual void AddPlayer(Player *plr);
+ void RemovePlayer(Player *plr, uint64 guid);
+ void HandleAreaTrigger(Player *Source, uint32 Trigger);
+ bool SetupBattleGround();
+ void HandleKillPlayer(Player* player, Player *killer);
+};
+#endif
diff --git a/src/game/BattleGroundEY.cpp b/src/game/BattleGroundEY.cpp
index 1af6aaabf8b..baaa345d96d 100644
--- a/src/game/BattleGroundEY.cpp
+++ b/src/game/BattleGroundEY.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -27,7 +27,8 @@
#include "ObjectMgr.h"
#include "MapManager.h"
#include "Language.h"
-#include "World.h"
+#include "World.h" //music
+#include "WorldPacket.h"
#include "Util.h"
// these variables aren't used outside of this file, so declare them only here
@@ -51,7 +52,7 @@ BattleGroundEY::~BattleGroundEY()
{
}
-void BattleGroundEY::Update(time_t diff)
+void BattleGroundEY::Update(uint32 diff)
{
BattleGround::Update(diff);
// after bg start we get there (once)
diff --git a/src/game/BattleGroundEY.h b/src/game/BattleGroundEY.h
index 0152a889f30..c99c0eeb4d4 100644
--- a/src/game/BattleGroundEY.h
+++ b/src/game/BattleGroundEY.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -300,7 +300,7 @@ class BattleGroundEY : public BattleGround
public:
BattleGroundEY();
~BattleGroundEY();
- void Update(time_t diff);
+ void Update(uint32 diff);
/* inherited from BattlegroundClass */
virtual void AddPlayer(Player *plr);
diff --git a/src/game/BattleGroundHandler.cpp b/src/game/BattleGroundHandler.cpp
index fc99fe3f1fe..33d8ab4fe4c 100644
--- a/src/game/BattleGroundHandler.cpp
+++ b/src/game/BattleGroundHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -53,7 +53,7 @@ void WorldSession::HandleBattleGroundHelloOpcode( WorldPacket & recv_data )
// Stop the npc if moving
unit->StopMoving();
- uint32 bgTypeId = objmgr.GetBattleMasterBG(unit->GetEntry());
+ BattleGroundTypeId bgTypeId = sBattleGroundMgr.GetBattleMasterBG(unit->GetEntry());
if(!_player->GetBGAccessByLevel(bgTypeId))
{
@@ -65,7 +65,7 @@ void WorldSession::HandleBattleGroundHelloOpcode( WorldPacket & recv_data )
SendBattlegGroundList(guid, bgTypeId);
}
-void WorldSession::SendBattlegGroundList( uint64 guid, uint32 bgTypeId )
+void WorldSession::SendBattlegGroundList( uint64 guid, BattleGroundTypeId bgTypeId )
{
WorldPacket data;
sBattleGroundMgr.BuildBattleGroundListPacket(&data, guid, _player, bgTypeId);
@@ -77,26 +77,28 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data )
CHECK_PACKET_SIZE(recv_data, 8+4+4+1);
uint64 guid;
- uint32 bgTypeId;
+ uint32 bgTypeId_;
uint32 instanceId;
uint8 joinAsGroup;
Group * grp;
recv_data >> guid; // battlemaster guid
- recv_data >> bgTypeId; // battleground type id (DBC id)
+ recv_data >> bgTypeId_; // battleground type id (DBC id)
recv_data >> instanceId; // instance id, 0 if First Available selected
recv_data >> joinAsGroup; // join as group
- if(bgTypeId >= MAX_BATTLEGROUND_TYPES)
+ if(!sBattlemasterListStore.LookupEntry(bgTypeId_))
{
- sLog.outError("Battleground: invalid bgtype received. possible cheater? player guid %u",_player->GetGUIDLow());
+ sLog.outError("Battleground: invalid bgtype (%u) received. possible cheater? player guid %u",bgTypeId_,_player->GetGUIDLow());
return;
}
+ BattleGroundTypeId bgTypeId = BattleGroundTypeId(bgTypeId_);
+
sLog.outDebug( "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from: " I64FMT, guid);
// can do this, since it's battleground, not arena
- uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bgTypeId, 0);
+ uint32 bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, 0);
// ignore if player is already in BG
if(_player->InBattleGround())
@@ -180,6 +182,8 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data )
}
sLog.outDebug("Battleground: group end");
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel());
+ if(!ginfo->IsInvitedToBGInstanceGUID)
+ sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AnnounceWorld(ginfo, _player->GetGUID(), true);
}
else
{
@@ -196,6 +200,8 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data )
GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, 0, false, 0);
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddPlayer(_player, ginfo);
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel());
+ if(!ginfo->IsInvitedToBGInstanceGUID)
+ sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AnnounceWorld(ginfo, _player->GetGUID(), true);
sLog.outDebug("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName());
}
}
@@ -270,19 +276,15 @@ void WorldSession::HandleBattleGroundListOpcode( WorldPacket &recv_data )
uint32 bgTypeId;
recv_data >> bgTypeId; // id from DBC
- if(bgTypeId >= MAX_BATTLEGROUND_TYPES)
+ BattlemasterListEntry const* bl = sBattlemasterListStore.LookupEntry(bgTypeId);
+ if(!bl)
{
sLog.outError("Battleground: invalid bgtype received.");
return;
}
- BattlemasterListEntry const* bl = sBattlemasterListStore.LookupEntry(bgTypeId);
-
- if(!bl)
- return;
-
WorldPacket data;
- sBattleGroundMgr.BuildBattleGroundListPacket(&data, _player->GetGUID(), _player, bgTypeId);
+ sBattleGroundMgr.BuildBattleGroundListPacket(&data, _player->GetGUID(), _player, BattleGroundTypeId(bgTypeId));
SendPacket( &data );
}
@@ -295,15 +297,15 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data )
uint8 type; // arenatype if arena
uint8 unk2; // unk, can be 0x0 (may be if was invited?) and 0x1
uint32 instanceId;
- uint32 bgTypeId; // type id from dbc
+ uint32 bgTypeId_; // type id from dbc
uint16 unk; // 0x1F90 constant?
uint8 action; // enter battle 0x1, leave queue 0x0
- recv_data >> type >> unk2 >> bgTypeId >> unk >> action;
+ recv_data >> type >> unk2 >> bgTypeId_ >> unk >> action;
- if(bgTypeId >= MAX_BATTLEGROUND_TYPES)
+ if(!sBattlemasterListStore.LookupEntry(bgTypeId_))
{
- sLog.outError("Battleground: invalid bgtype received.");
+ sLog.outError("Battleground: invalid bgtype (%u) received.",bgTypeId_);
// update battleground slots for the player to fix his UI and sent data.
// this is a HACK, I don't know why the client starts sending invalid packets in the first place.
// it usually happens with extremely high latency (if debugging / stepping in the code for example)
@@ -327,7 +329,7 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data )
BattleGround * bg = NULL;
// get possibly needed data from groupinfo
- bgTypeId = itrPlayerStatus->second.GroupInfo->BgTypeId;
+ BattleGroundTypeId bgTypeId = itrPlayerStatus->second.GroupInfo->BgTypeId;
uint8 arenatype = itrPlayerStatus->second.GroupInfo->ArenaType;
uint8 israted = itrPlayerStatus->second.GroupInfo->IsRated;
uint8 status = 0;
@@ -363,10 +365,12 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data )
return;
}
+ BattleGroundTypeId bgTypeId = BattleGroundTypeId(bgTypeId_);
+
uint32 bgQueueTypeId = 0;
// get the bg what we were invited to
BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus;
- bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bgTypeId,type);
+ bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId,type);
itrPlayerStatus = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].find(_player->GetGUID());
if(itrPlayerStatus == sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].end())
@@ -391,7 +395,7 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data )
if(!bg)
{
- sLog.outError("Battleground: bg not found.");
+ sLog.outError("Battleground: bg not found for type id %u.",bgTypeId);
return;
}
@@ -460,7 +464,7 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data )
// bg->AddPlayer(_player,team);
sLog.outDebug("Battleground: player %s (%u) joined battle for bg %u, bgtype %u, queue type %u.",_player->GetName(),_player->GetGUIDLow(),bg->GetInstanceID(),bg->GetTypeID(),bgQueueTypeId);
break;
- case 0: // leave queue
+ case 0: // leave queue
queueSlot = _player->GetBattleGroundQueueIndex(bgQueueTypeId);
/*
if player leaves rated arena match before match start, it is counted as he played but he lost
@@ -527,7 +531,7 @@ void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & /*recv_data*/ )
BattleGround *bg = _player->GetBattleGround();
if(bg)
{
- uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType());
+ uint32 bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType());
uint32 queueSlot = _player->GetBattleGroundQueueIndex(bgQueueTypeId);
if((bg->GetStatus() <= STATUS_IN_PROGRESS))
{
@@ -537,7 +541,7 @@ void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & /*recv_data*/ )
for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
{
uint32 queue_id = _player->GetBattleGroundQueueId(i); // battlegroundqueueid stores the type id, not the instance id, so this is definitely wrong
- uint8 arenatype = sBattleGroundMgr.BGArenaType(queue_id);
+ uint8 arenatype = BattleGroundMgr::BGArenaType(queue_id);
uint8 isRated = 0;
if (i == queueSlot || !queue_id) // we need to get the instance ids
continue;
@@ -549,7 +553,7 @@ void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & /*recv_data*/ )
arenatype = itrPlayerStatus->second.GroupInfo->ArenaType;
isRated = itrPlayerStatus->second.GroupInfo->IsRated;
}
- BattleGround *bg2 = sBattleGroundMgr.GetBattleGroundTemplate(sBattleGroundMgr.BGTemplateId(queue_id)); // try this
+ BattleGround *bg2 = sBattleGroundMgr.GetBattleGroundTemplate(BattleGroundMgr::BGTemplateId(queue_id)); // try this
if(bg2)
{
//in this call is small bug, this call should be filled by player's waiting time in queue
@@ -568,8 +572,8 @@ void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & /*recv_data*/ )
uint32 queue_id = _player->GetBattleGroundQueueId(i);
if(!queue_id)
continue;
- uint32 bgTypeId = sBattleGroundMgr.BGTemplateId(queue_id);
- uint8 arenatype = sBattleGroundMgr.BGArenaType(queue_id);
+ BattleGroundTypeId bgTypeId = BattleGroundMgr::BGTemplateId(queue_id);
+ uint8 arenatype = BattleGroundMgr::BGArenaType(queue_id);
uint8 isRated = 0;
BattleGround *bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus = sBattleGroundMgr.m_BattleGroundQueues[queue_id].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].find(_player->GetGUID());
@@ -696,8 +700,8 @@ void WorldSession::HandleBattleGroundArenaJoin( WorldPacket & recv_data )
return;
}
- uint8 bgTypeId = bg->GetTypeID();
- uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bgTypeId, arenatype);
+ BattleGroundTypeId bgTypeId = bg->GetTypeID();
+ uint32 bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, arenatype);
// check queueing conditions
if(!asGroup)
@@ -784,6 +788,8 @@ void WorldSession::HandleBattleGroundArenaJoin( WorldPacket & recv_data )
}
sLog.outDebug("Battleground: arena join as group end");
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel(), arenatype, isRated, arenaRating);
+ if(isRated)
+ sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AnnounceWorld(ginfo, _player->GetGUID(), true);
}
else
{
diff --git a/src/game/BattleGroundMgr.cpp b/src/game/BattleGroundMgr.cpp
index b4a28d93fd8..f86b6f4915a 100644
--- a/src/game/BattleGroundMgr.cpp
+++ b/src/game/BattleGroundMgr.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -19,6 +19,7 @@
*/
#include "Common.h"
+#include "SharedDefines.h"
#include "Player.h"
#include "BattleGroundMgr.h"
#include "BattleGroundAV.h"
@@ -29,16 +30,21 @@
#include "BattleGroundBE.h"
#include "BattleGroundAA.h"
#include "BattleGroundRL.h"
-#include "SharedDefines.h"
-#include "Policies/SingletonImp.h"
+#include "BattleGroundSA.h"
+#include "BattleGroundDS.h"
+#include "BattleGroundRV.h"
#include "MapManager.h"
#include "Map.h"
#include "MapInstanced.h"
#include "ObjectMgr.h"
#include "ProgressBar.h"
-#include "World.h"
#include "Chat.h"
#include "ArenaTeam.h"
+#include "World.h"
+#include "WorldPacket.h"
+#include "ProgressBar.h"
+
+#include "Policies/SingletonImp.h"
INSTANTIATE_SINGLETON_1( BattleGroundMgr );
@@ -71,7 +77,7 @@ BattleGroundQueue::~BattleGroundQueue()
}
// initialize eligible groups from the given source matching the given specifications
-void BattleGroundQueue::EligibleGroups::Init(BattleGroundQueue::QueuedGroupsList *source, uint32 BgTypeId, uint32 side, uint32 MaxPlayers, uint8 ArenaType, bool IsRated, uint32 MinRating, uint32 MaxRating, uint32 DisregardTime, uint32 excludeTeam)
+void BattleGroundQueue::EligibleGroups::Init(BattleGroundQueue::QueuedGroupsList *source, BattleGroundTypeId BgTypeId, uint32 side, uint32 MaxPlayers, uint8 ArenaType, bool IsRated, uint32 MinRating, uint32 MaxRating, uint32 DisregardTime, uint32 excludeTeam)
{
// clear from prev initialization
clear();
@@ -136,7 +142,7 @@ void BattleGroundQueue::SelectionPool::AddGroup(GroupQueueInfo * ginfo)
}
// add group to bg queue with the given leader and bg specifications
-GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, uint32 BgTypeId, uint8 ArenaType, bool isRated, uint32 arenaRating, uint32 arenateamid)
+GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, BattleGroundTypeId BgTypeId, uint8 ArenaType, bool isRated, uint32 arenaRating, uint32 arenateamid)
{
uint32 queue_id = leader->GetBattleGroundQueueIdFromLevel();
@@ -177,7 +183,7 @@ void BattleGroundQueue::AddPlayer(Player *plr, GroupQueueInfo *ginfo)
ginfo->Players[plr->GetGUID()] = &info;
}
-void BattleGroundQueue::RemovePlayer(uint64 guid, bool decreaseInvitedCount)
+void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCount)
{
Player *plr = objmgr.GetPlayer(guid);
@@ -260,6 +266,11 @@ void BattleGroundQueue::RemovePlayer(uint64 guid, bool decreaseInvitedCount)
// remove player queue info
m_QueuedPlayers[queue_id].erase(itr);
// remove group queue info if needed
+
+ //if we left BG queue(not porting) OR if arena team left queue for rated match
+ if((decreaseInvitedCount && !group->ArenaType) || (group->ArenaType && group->IsRated && group->Players.empty()))
+ AnnounceWorld(group, guid, false);
+
if(group->Players.empty())
{
m_QueuedGroups[queue_id].erase(group_itr);
@@ -275,7 +286,7 @@ void BattleGroundQueue::RemovePlayer(uint64 guid, bool decreaseInvitedCount)
if(Player *plr2 = objmgr.GetPlayer(group->Players.begin()->first))
{
BattleGround * bg = sBattleGroundMgr.GetBattleGroundTemplate(group->BgTypeId);
- uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(group->BgTypeId,group->ArenaType);
+ uint32 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;
@@ -288,6 +299,85 @@ void BattleGroundQueue::RemovePlayer(uint64 guid, bool decreaseInvitedCount)
}
}
+void BattleGroundQueue::AnnounceWorld(GroupQueueInfo *ginfo, const uint64& playerGUID, bool isAddedToQueue)
+{
+
+ if(ginfo->ArenaType) //if Arena
+ {
+ if( sWorld.getConfig(CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE) && ginfo->IsRated)
+ {
+ BattleGround* bg = sBattleGroundMgr.GetBattleGroundTemplate(ginfo->BgTypeId);
+ if(!bg)
+ return;
+
+ char const* bgName = bg->GetName();
+ if(isAddedToQueue)
+ sWorld.SendWorldText(LANG_ARENA_QUEUE_ANNOUNCE_WORLD_JOIN, bgName, ginfo->ArenaType, ginfo->ArenaType, ginfo->ArenaTeamRating);
+ else
+ sWorld.SendWorldText(LANG_ARENA_QUEUE_ANNOUNCE_WORLD_EXIT, bgName, ginfo->ArenaType, ginfo->ArenaType, ginfo->ArenaTeamRating);
+ }
+ }
+ else //if BG
+ {
+ if( sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE) )
+ {
+ Player *plr = objmgr.GetPlayer(playerGUID);
+ if(!plr)
+ return;
+
+ BattleGround* bg = sBattleGroundMgr.GetBattleGroundTemplate(ginfo->BgTypeId);
+ if(!bg)
+ return;
+
+ uint32 queue_id = plr->GetBattleGroundQueueIdFromLevel();
+ char const* bgName = bg->GetName();
+
+ uint32 q_min_level = Player::GetMinLevelForBattleGroundQueueId(queue_id);
+ uint32 q_max_level = Player::GetMaxLevelForBattleGroundQueueId(queue_id);
+
+ // replace hardcoded max level by player max level for nice output
+ if(q_max_level > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
+ q_max_level = sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL);
+
+ int8 MinPlayers = bg->GetMinPlayersPerTeam();
+
+ uint8 qHorde = 0;
+ uint8 qAlliance = 0;
+
+ BattleGroundTypeId bgTypeId = ginfo->BgTypeId;
+ QueuedPlayersMap::iterator itr;
+ for(itr = m_QueuedPlayers[queue_id].begin(); itr!= m_QueuedPlayers[queue_id].end(); ++itr)
+ {
+ if(itr->second.GroupInfo->BgTypeId == bgTypeId)
+ {
+ switch(itr->second.GroupInfo->Team)
+ {
+ case HORDE:
+ qHorde++; break;
+ case ALLIANCE:
+ qAlliance++; break;
+ default:
+ break;
+ }
+ }
+ }
+
+ // Show queue status to player only (when joining queue)
+ if(sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY))
+ {
+ ChatHandler(plr).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF,
+ bgName, q_min_level, q_max_level, qAlliance, MinPlayers, qHorde, MinPlayers);
+ }
+ // System message
+ else
+ {
+ sWorld.SendWorldText(LANG_BG_QUEUE_ANNOUNCE_WORLD,
+ bgName, q_min_level, q_max_level, qAlliance, MinPlayers, qHorde, MinPlayers);
+ }
+ }
+ }
+}
+
bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * bg, uint32 side)
{
// set side if needed
@@ -299,7 +389,7 @@ bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * b
// not yet invited
// set invitation
ginfo->IsInvitedToBGInstanceGUID = bg->GetInstanceID();
- uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType());
+ uint32 bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType());
// loop through the players
for(std::map<uint64,PlayerQueueInfo*>::iterator itr = ginfo->Players.begin(); itr != ginfo->Players.end(); ++itr)
{
@@ -362,26 +452,25 @@ bool BattleGroundQueue::SelectionPool::Build(uint32 MinPlayers, uint32 MaxPlayer
}
// this function is responsible for the selection of queued groups when trying to create new battlegrounds
-bool BattleGroundQueue::BuildSelectionPool(uint32 bgTypeId, uint32 queue_id, uint32 MinPlayers, uint32 MaxPlayers, SelectionPoolBuildMode mode, uint8 ArenaType, bool isRated, uint32 MinRating, uint32 MaxRating, uint32 DisregardTime, uint32 excludeTeam)
+bool BattleGroundQueue::BuildSelectionPool(BattleGroundTypeId bgTypeId, uint32 queue_id, uint32 MinPlayers, uint32 MaxPlayers, SelectionPoolBuildMode mode, uint8 ArenaType, bool isRated, uint32 MinRating, uint32 MaxRating, uint32 DisregardTime, uint32 excludeTeam)
{
uint32 side;
switch(mode)
{
- case NORMAL_ALLIANCE:
- case ONESIDE_ALLIANCE_TEAM1:
- case ONESIDE_ALLIANCE_TEAM2:
- side = ALLIANCE;
- break;
- case NORMAL_HORDE:
- case ONESIDE_HORDE_TEAM1:
- case ONESIDE_HORDE_TEAM2:
- side = HORDE;
- break;
- default:
- //unknown mode, return false
- sLog.outDebug("Battleground: unknown selection pool build mode, returning...");
- return false;
- break;
+ case NORMAL_ALLIANCE:
+ case ONESIDE_ALLIANCE_TEAM1:
+ case ONESIDE_ALLIANCE_TEAM2:
+ side = ALLIANCE;
+ break;
+ case NORMAL_HORDE:
+ case ONESIDE_HORDE_TEAM1:
+ case ONESIDE_HORDE_TEAM2:
+ side = HORDE;
+ break;
+ default:
+ //unknown mode, return false
+ sLog.outDebug("Battleground: unknown selection pool build mode, returning...");
+ return false;
}
// initiate the groups eligible to create the bg
@@ -414,7 +503,7 @@ void BattleGroundQueue::BGEndedRemoveInvites(BattleGround *bg)
{
uint32 queue_id = bg->GetQueueType();
uint32 bgInstanceId = bg->GetInstanceID();
- uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType());
+ uint32 bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType());
QueuedGroupsList::iterator itr, next;
for(itr = m_QueuedGroups[queue_id].begin(); itr != m_QueuedGroups[queue_id].end(); itr = next)
{
@@ -455,7 +544,7 @@ void BattleGroundQueue::BGEndedRemoveInvites(BattleGround *bg)
RemovePlayer(itr2->first, true);
// this is probably unneeded, since this player was already invited -> does not fit when initing eligible groups
// but updating the queue can't hurt
- Update(bgQueueTypeId, bg->GetQueueType());
+ Update(bg->GetTypeID(), bg->GetQueueType());
// send info to client
WorldPacket data;
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, team, queueSlot, STATUS_NONE, 0, 0);
@@ -471,7 +560,7 @@ this method is called when group is inserted, or player / group is removed from
it must be called after fully adding the members of a group to ensure group joining
should be called after removeplayer functions in some cases
*/
-void BattleGroundQueue::Update(uint32 bgTypeId, uint32 queue_id, uint8 arenatype, bool isRated, uint32 arenaRating)
+void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, uint32 queue_id, uint8 arenatype, bool isRated, uint32 arenaRating)
{
if (queue_id >= MAX_BATTLEGROUND_QUEUES)
{
@@ -484,7 +573,7 @@ void BattleGroundQueue::Update(uint32 bgTypeId, uint32 queue_id, uint8 arenatype
if (m_QueuedGroups[queue_id].empty())
return;
- uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bgTypeId, arenatype);
+ uint32 bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, arenatype);
//battleground with free slot for player should be always the last in this queue
BGFreeSlotQueueType::iterator itr, next;
@@ -559,6 +648,14 @@ void BattleGroundQueue::Update(uint32 bgTypeId, uint32 queue_id, uint8 arenatype
}
}
}
+ // BG case
+ else
+ {
+ if(sBattleGroundMgr.isTesting())
+ {
+ MinPlayersPerTeam = 1;
+ }
+ }
// found out the minimum and maximum ratings the newly added team should battle against
// arenaRating is the rating of the latest joined team
@@ -586,14 +683,14 @@ void BattleGroundQueue::Update(uint32 bgTypeId, uint32 queue_id, uint8 arenatype
sLog.outDebug("Battleground: horde pool wasn't created");
// if selection pools are ready, create the new bg
- if (bAllyOK && bHordeOK)
+ if ((bAllyOK && bHordeOK) || ( sBattleGroundMgr.isTesting() && (bAllyOK || bHordeOK)))
{
BattleGround * bg2 = 0;
// special handling for arenas
if(bg_template->isArena())
{
// Find a random arena, that can be created
- uint8 arenas[] = {BATTLEGROUND_NA, BATTLEGROUND_BE, BATTLEGROUND_RL};
+ BattleGroundTypeId arenas[] = {BATTLEGROUND_NA, BATTLEGROUND_BE, BATTLEGROUND_RL};
uint32 arena_num = urand(0,2);
if( !(bg2 = sBattleGroundMgr.CreateNewBattleGround(arenas[arena_num%3])) &&
!(bg2 = sBattleGroundMgr.CreateNewBattleGround(arenas[(arena_num+1)%3])) &&
@@ -635,6 +732,15 @@ void BattleGroundQueue::Update(uint32 bgTypeId, uint32 queue_id, uint8 arenatype
{
// create new battleground
bg2 = sBattleGroundMgr.CreateNewBattleGround(bgTypeId);
+ if( sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE) )
+ {
+ char const* bgName = bg2->GetName();
+ uint32 q_min_level = Player::GetMinLevelForBattleGroundQueueId(queue_id);
+ uint32 q_max_level = Player::GetMaxLevelForBattleGroundQueueId(queue_id);
+ if(q_max_level > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
+ q_max_level = sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL);
+ sWorld.SendWorldText(LANG_BG_STARTED_ANNOUNCE_WORLD, bgName, q_min_level, q_max_level);
+ }
}
if(!bg2)
@@ -748,7 +854,7 @@ void BattleGroundQueue::Update(uint32 bgTypeId, uint32 queue_id, uint8 arenatype
}
// create random arena
- uint8 arenas[] = {BATTLEGROUND_NA, BATTLEGROUND_BE, BATTLEGROUND_RL};
+ BattleGroundTypeId arenas[] = {BATTLEGROUND_NA, BATTLEGROUND_BE, BATTLEGROUND_RL};
uint32 arena_num = urand(0,2);
BattleGround* bg2 = NULL;
if( !(bg2 = sBattleGroundMgr.CreateNewBattleGround(arenas[arena_num%3])) &&
@@ -850,22 +956,18 @@ bool BGQueueInviteEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
if (!bg)
return true;
- uint32 queueSlot = plr->GetBattleGroundQueueIndex(bg->GetTypeID());
+ uint32 bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType());
+ uint32 queueSlot = plr->GetBattleGroundQueueIndex(bgQueueTypeId);
if (queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is in queue
{
- uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType());
- uint32 queueSlot = plr->GetBattleGroundQueueIndex(bgQueueTypeId);
- if (queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is in queue
+ // check if player is invited to this bg ... this check must be here, because when player leaves queue and joins another, it would cause a problems
+ BattleGroundQueue::QueuedPlayersMap const& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[plr->GetBattleGroundQueueIdFromLevel()];
+ BattleGroundQueue::QueuedPlayersMap::const_iterator qItr = qpMap.find(m_PlayerGuid);
+ if (qItr != qpMap.end() && qItr->second.GroupInfo->IsInvitedToBGInstanceGUID == m_BgInstanceGUID)
{
- // check if player is invited to this bg ... this check must be here, because when player leaves queue and joins another, it would cause a problems
- BattleGroundQueue::QueuedPlayersMap const& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[plr->GetBattleGroundQueueIdFromLevel()];
- BattleGroundQueue::QueuedPlayersMap::const_iterator qItr = qpMap.find(m_PlayerGuid);
- if (qItr != qpMap.end() && qItr->second.GroupInfo->IsInvitedToBGInstanceGUID == m_BgInstanceGUID)
- {
- WorldPacket data;
- sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, qItr->second.GroupInfo->Team, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME/2, 0);
- plr->GetSession()->SendPacket(&data);
- }
+ WorldPacket data;
+ sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, qItr->second.GroupInfo->Team, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME/2, 0);
+ plr->GetSession()->SendPacket(&data);
}
}
return true; //event will be deleted
@@ -890,7 +992,7 @@ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
sLog.outDebug("Battleground: removing player %u from bg queue for instance %u because of not pressing enter battle in time.",plr->GetGUIDLow(),m_BgInstanceGUID);
- uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType());
+ uint32 bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType());
uint32 queueSlot = plr->GetBattleGroundQueueIndex(bgQueueTypeId);
if (queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is in queue
{
@@ -910,7 +1012,7 @@ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
}
plr->RemoveBattleGroundQueueId(bgQueueTypeId);
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].RemovePlayer(m_PlayerGuid, true);
- sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgQueueTypeId, bg->GetQueueType());
+ sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bg->GetTypeID(),bg->GetQueueType());
WorldPacket data;
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, m_PlayersTeam, queueSlot, STATUS_NONE, 0, 0);
plr->GetSession()->SendPacket(&data);
@@ -933,34 +1035,38 @@ void BGQueueRemoveEvent::Abort(uint64 /*e_time*/)
/*** BATTLEGROUND MANAGER ***/
/*********************************************************/
-BattleGroundMgr::BattleGroundMgr()
+BattleGroundMgr::BattleGroundMgr() : m_AutoDistributionTimeChecker(0), m_ArenaTesting(false)
{
m_BattleGrounds.clear();
- m_AutoDistributePoints = (bool)sWorld.getConfig(CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS);
- m_MaxRatingDifference = sWorld.getConfig(CONFIG_ARENA_MAX_RATING_DIFFERENCE);
- m_RatingDiscardTimer = sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER);
- m_PrematureFinishTimer = sWorld.getConfig(CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER);
- m_NextRatingDiscardUpdate = m_RatingDiscardTimer;
- m_AutoDistributionTimeChecker = 0;
- m_ArenaTesting = false;
+ m_NextRatingDiscardUpdate = sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER);
+ m_Testing=false;
}
BattleGroundMgr::~BattleGroundMgr()
{
- BattleGroundSet::iterator itr, next;
- for(itr = m_BattleGrounds.begin(); itr != m_BattleGrounds.end(); itr = next)
+ DeleteAlllBattleGrounds();
+}
+
+void BattleGroundMgr::DeleteAlllBattleGrounds()
+{
+ for(BattleGroundSet::iterator itr = m_BattleGrounds.begin(); itr != m_BattleGrounds.end();)
{
- next = itr;
- ++next;
BattleGround * bg = itr->second;
- m_BattleGrounds.erase(itr);
+ m_BattleGrounds.erase(itr++);
delete bg;
}
- m_BattleGrounds.clear();
+
+ // destroy template battlegrounds that listed only in queues (other already terminated)
+ for(uint32 bgTypeId = 0; bgTypeId < MAX_BATTLEGROUND_TYPE_ID; ++bgTypeId)
+ {
+ // ~BattleGround call unregistring BG from queue
+ while(!BGFreeSlotQueue[bgTypeId].empty())
+ delete BGFreeSlotQueue[bgTypeId].front();
+ }
}
// used to update running battlegrounds, and delete finished ones
-void BattleGroundMgr::Update(time_t diff)
+void BattleGroundMgr::Update(uint32 diff)
{
BattleGroundSet::iterator itr, next;
for(itr = m_BattleGrounds.begin(); itr != m_BattleGrounds.end(); itr = next)
@@ -978,7 +1084,7 @@ void BattleGroundMgr::Update(time_t diff)
}
}
// if rating difference counts, maybe force-update queues
- if(m_MaxRatingDifference)
+ if(sWorld.getConfig(CONFIG_ARENA_MAX_RATING_DIFFERENCE))
{
// it's time to force update
if(m_NextRatingDiscardUpdate < diff)
@@ -987,12 +1093,12 @@ void BattleGroundMgr::Update(time_t diff)
m_BattleGroundQueues[BATTLEGROUND_QUEUE_2v2].Update(BATTLEGROUND_AA,6,ARENA_TYPE_2v2,true,0);
m_BattleGroundQueues[BATTLEGROUND_QUEUE_3v3].Update(BATTLEGROUND_AA,6,ARENA_TYPE_3v3,true,0);
m_BattleGroundQueues[BATTLEGROUND_QUEUE_5v5].Update(BATTLEGROUND_AA,6,ARENA_TYPE_5v5,true,0);
- m_NextRatingDiscardUpdate = m_RatingDiscardTimer;
+ m_NextRatingDiscardUpdate = sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER);
}
else
m_NextRatingDiscardUpdate -= diff;
}
- if(m_AutoDistributePoints)
+ if(sWorld.getConfig(CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS))
{
if(m_AutoDistributionTimeChecker < diff)
{
@@ -1054,6 +1160,15 @@ void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGro
case BATTLEGROUND_RL:
*data << uint8(8);
break;
+ case BATTLEGROUND_SA:
+ *data << uint8(9);
+ break;
+ case BATTLEGROUND_DS:
+ *data << uint8(10);
+ break;
+ case BATTLEGROUND_RV:
+ *data << uint8(11);
+ break;
default: // unknown
*data << uint8(0);
break;
@@ -1098,17 +1213,18 @@ void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGro
void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg)
{
uint8 type = (bg->isArena() ? 1 : 0);
- // last check on 2.4.1
+ // last check on 3.0.3
data->Initialize(MSG_PVP_LOG_DATA, (1+1+4+40*bg->GetPlayerScoresSize()));
- *data << uint8(type); // seems to be type (battleground=0/arena=1)
+ *data << uint8(type); // type (battleground=0/arena=1)
if(type) // arena
{
// it seems this must be according to BG_WINNER_A/H and _NOT_ BG_TEAM_A/H
for(int i = 1; i >= 0; --i)
{
- *data << uint32(3000-bg->m_ArenaTeamRatingChanges[i]); // rating change: showed value - 3000
+ *data << uint32(bg->m_ArenaTeamRatingChanges[i]);
*data << uint32(3999); // huge thanks for TOM_RUS for this!
+ *data << uint32(0); // unknown - new in 3.0.3
sLog.outDebug("rating change: %d", bg->m_ArenaTeamRatingChanges[i]);
}
for(int i = 1; i >= 0; --i)
@@ -1122,9 +1238,9 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg)
}
}
- if(bg->GetWinner() == 2)
+ if(bg->GetStatus() != STATUS_WAIT_LEAVE)
{
- *data << uint8(0); // bg in progress
+ *data << uint8(0); // bg not ended
}
else
{
@@ -1138,9 +1254,6 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg)
{
*data << (uint64)itr->first;
*data << (int32)itr->second->KillingBlows;
- Player *plr = objmgr.GetPlayer(itr->first);
- uint32 team = bg->GetPlayerTeam(itr->first);
- if(!team && plr) team = plr->GetTeam();
if(type == 0)
{
*data << (int32)itr->second->HonorableKills;
@@ -1149,18 +1262,12 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg)
}
else
{
- // that part probably wrong
- if(plr)
- {
- if(team == HORDE)
- *data << uint8(0);
- else if(team == ALLIANCE)
- {
- *data << uint8(1);
- }
- else
- *data << uint8(0);
- }
+ Player *plr = objmgr.GetPlayer(itr->first);
+ uint32 team = bg->GetPlayerTeam(itr->first);
+ if(!team && plr)
+ team = plr->GetTeam();
+ if( ( bg->GetWinner()==0 && team == ALLIANCE ) || ( bg->GetWinner()==1 && team==HORDE ) )
+ *data << uint8(1);
else
*data << uint8(0);
}
@@ -1187,13 +1294,16 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg)
*data << (uint32)((BattleGroundABScore*)itr->second)->BasesDefended; // bases defended
break;
case BATTLEGROUND_EY:
- *data << (uint32)0x00000001; // count of next fields
+ *data << (uint32)0x00000001; // count of next fields
*data << (uint32)((BattleGroundEYScore*)itr->second)->FlagCaptures; // flag captures
break;
case BATTLEGROUND_NA:
case BATTLEGROUND_BE:
case BATTLEGROUND_AA:
case BATTLEGROUND_RL:
+ case BATTLEGROUND_SA: // wotlk
+ case BATTLEGROUND_DS: // wotlk
+ case BATTLEGROUND_RV: // wotlk
*data << (int32)0; // 0
break;
default:
@@ -1204,7 +1314,7 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg)
}
}
-void BattleGroundMgr::BuildGroupJoinedBattlegroundPacket(WorldPacket *data, uint32 bgTypeId)
+void BattleGroundMgr::BuildGroupJoinedBattlegroundPacket(WorldPacket *data, BattleGroundTypeId bgTypeId)
{
/*bgTypeId is:
0 - Your group has joined a battleground queue, but you are not eligible
@@ -1281,25 +1391,24 @@ void BattleGroundMgr::InvitePlayer(Player* plr, uint32 bgInstanceGUID, uint32 te
plr->m_Events.AddEvent(removeEvent, plr->m_Events.CalculateTime(INVITE_ACCEPT_WAIT_TIME));
}
-BattleGround * BattleGroundMgr::GetBattleGroundTemplate(uint32 bgTypeId)
+BattleGround * BattleGroundMgr::GetBattleGroundTemplate(BattleGroundTypeId bgTypeId)
{
return BGFreeSlotQueue[bgTypeId].empty() ? NULL : BGFreeSlotQueue[bgTypeId].back();
}
// create a new battleground that will really be used to play
-BattleGround * BattleGroundMgr::CreateNewBattleGround(uint32 bgTypeId)
+BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeId)
{
- BattleGround *bg = NULL;
-
// get the template BG
BattleGround *bg_template = GetBattleGroundTemplate(bgTypeId);
-
if(!bg_template)
{
sLog.outError("BattleGround: CreateNewBattleGround - bg template not found for %u", bgTypeId);
- return 0;
+ return NULL;
}
+ BattleGround *bg = NULL;
+
// create a copy of the BG template
switch(bgTypeId)
{
@@ -1327,6 +1436,15 @@ BattleGround * BattleGroundMgr::CreateNewBattleGround(uint32 bgTypeId)
case BATTLEGROUND_RL:
bg = new BattleGroundRL(*(BattleGroundRL*)bg_template);
break;
+ case BATTLEGROUND_SA:
+ bg = new BattleGroundSA(*(BattleGroundSA*)bg_template);
+ break;
+ case BATTLEGROUND_DS:
+ bg = new BattleGroundDS(*(BattleGroundDS*)bg_template);
+ break;
+ case BATTLEGROUND_RV:
+ bg = new BattleGroundRV(*(BattleGroundRV*)bg_template);
+ break;
default:
//bg = new BattleGround;
return 0;
@@ -1358,7 +1476,7 @@ BattleGround * BattleGroundMgr::CreateNewBattleGround(uint32 bgTypeId)
}
// used to create the BG templates
-uint32 BattleGroundMgr::CreateBattleGround(uint32 bgTypeId, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam, uint32 LevelMin, uint32 LevelMax, char* BattleGroundName, uint32 MapID, float Team1StartLocX, float Team1StartLocY, float Team1StartLocZ, float Team1StartLocO, float Team2StartLocX, float Team2StartLocY, float Team2StartLocZ, float Team2StartLocO)
+uint32 BattleGroundMgr::CreateBattleGround(BattleGroundTypeId bgTypeId, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam, uint32 LevelMin, uint32 LevelMax, char* BattleGroundName, uint32 MapID, float Team1StartLocX, float Team1StartLocY, float Team1StartLocZ, float Team1StartLocO, float Team2StartLocX, float Team2StartLocY, float Team2StartLocZ, float Team2StartLocO)
{
// Create the BG
BattleGround *bg = NULL;
@@ -1373,6 +1491,9 @@ uint32 BattleGroundMgr::CreateBattleGround(uint32 bgTypeId, uint32 MinPlayersPer
case BATTLEGROUND_AA: bg = new BattleGroundAA; break;
case BATTLEGROUND_EY: bg = new BattleGroundEY; break;
case BATTLEGROUND_RL: bg = new BattleGroundRL; break;
+ case BATTLEGROUND_SA: bg = new BattleGroundSA; break;
+ case BATTLEGROUND_DS: bg = new BattleGroundDS; break;
+ case BATTLEGROUND_RV: bg = new BattleGroundRV; break;
default:bg = new BattleGround; break; // placeholder for non implemented BG
}
@@ -1438,16 +1559,18 @@ void BattleGroundMgr::CreateInitialBattleGrounds()
Field *fields = result->Fetch();
bar.step();
- uint32 bgTypeID = fields[0].GetUInt32();
+ uint32 bgTypeID_ = fields[0].GetUInt32();
- // can be overwrited by values from DB
- bl = sBattlemasterListStore.LookupEntry(bgTypeID);
+ // can be overwrite by values from DB
+ bl = sBattlemasterListStore.LookupEntry(bgTypeID_);
if(!bl)
{
- sLog.outError("Battleground ID %u not found in BattlemasterList.dbc. Battleground not created.",bgTypeID);
+ sLog.outError("Battleground ID %u not found in BattlemasterList.dbc. Battleground not created.",bgTypeID_);
continue;
}
+ BattleGroundTypeId bgTypeID = BattleGroundTypeId(bgTypeID_);
+
MaxPlayersPerTeam = bl->maxplayersperteam;
MinPlayersPerTeam = bl->maxplayersperteam/2;
MinLvl = bl->minlvl;
@@ -1526,7 +1649,7 @@ void BattleGroundMgr::CreateInitialBattleGrounds()
void BattleGroundMgr::InitAutomaticArenaPointDistribution()
{
- if(m_AutoDistributePoints)
+ if(sWorld.getConfig(CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS))
{
sLog.outDebug("Initializing Automatic Arena Point Distribution");
QueryResult * result = CharacterDatabase.Query("SELECT NextArenaPointDistributionTime FROM saved_variables");
@@ -1548,9 +1671,9 @@ void BattleGroundMgr::InitAutomaticArenaPointDistribution()
void BattleGroundMgr::DistributeArenaPoints()
{
// used to distribute arena points based on last week's stats
- sWorld.SendGlobalText("Flushing Arena points based on team ratings, this may take a few minutes. Please stand by...", NULL);
+ sWorld.SendWorldText(LANG_DIST_ARENA_POINTS_START);
- sWorld.SendGlobalText("Distributing arena points to players...", NULL);
+ 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;
@@ -1577,9 +1700,9 @@ void BattleGroundMgr::DistributeArenaPoints()
PlayerPoints.clear();
- sWorld.SendGlobalText("Finished setting arena points for online players.", NULL);
+ sWorld.SendWorldText(LANG_DIST_ARENA_POINTS_ONLINE_END);
- sWorld.SendGlobalText("Modifying played count, arena points etc. for loaded arena teams, sending updated stats to online players...", NULL);
+ sWorld.SendWorldText(LANG_DIST_ARENA_POINTS_TEAM_START);
for(ObjectMgr::ArenaTeamMap::iterator titr = objmgr.GetArenaTeamMapBegin(); titr != objmgr.GetArenaTeamMapEnd(); ++titr)
{
if(ArenaTeam * at = titr->second)
@@ -1590,12 +1713,12 @@ void BattleGroundMgr::DistributeArenaPoints()
}
}
- sWorld.SendGlobalText("Modification done.", NULL);
+ sWorld.SendWorldText(LANG_DIST_ARENA_POINTS_TEAM_END);
- sWorld.SendGlobalText("Done flushing Arena points.", NULL);
+ sWorld.SendWorldText(LANG_DIST_ARENA_POINTS_END);
}
-void BattleGroundMgr::BuildBattleGroundListPacket(WorldPacket *data, uint64 guid, Player* plr, uint32 bgTypeId)
+void BattleGroundMgr::BuildBattleGroundListPacket(WorldPacket *data, const uint64& guid, Player* plr, BattleGroundTypeId bgTypeId)
{
uint32 PlayerLevel = 10;
@@ -1651,7 +1774,7 @@ void BattleGroundMgr::SendToBattleGround(Player *pl, uint32 instanceId)
}
}
-void BattleGroundMgr::SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround *bg, uint64 guid)
+void BattleGroundMgr::SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround *bg, const uint64& guid)
{
WorldPacket data(SMSG_AREA_SPIRIT_HEALER_TIME, 12);
uint32 time_ = 30000 - bg->GetLastResurrectTime(); // resurrect every 30 seconds
@@ -1661,14 +1784,7 @@ void BattleGroundMgr::SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround *
pl->GetSession()->SendPacket(&data);
}
-void BattleGroundMgr::RemoveBattleGround(uint32 instanceID)
-{
- BattleGroundSet::iterator itr = m_BattleGrounds.find(instanceID);
- if(itr!=m_BattleGrounds.end())
- m_BattleGrounds.erase(itr);
-}
-
-bool BattleGroundMgr::IsArenaType(uint32 bgTypeId) const
+bool BattleGroundMgr::IsArenaType(BattleGroundTypeId bgTypeId)
{
return ( bgTypeId == BATTLEGROUND_AA ||
bgTypeId == BATTLEGROUND_BE ||
@@ -1676,95 +1792,165 @@ bool BattleGroundMgr::IsArenaType(uint32 bgTypeId) const
bgTypeId == BATTLEGROUND_RL );
}
-bool BattleGroundMgr::IsBattleGroundType(uint32 bgTypeId) const
-{
- return !IsArenaType(bgTypeId);
-}
-
-uint32 BattleGroundMgr::BGQueueTypeId(uint32 bgTypeId, uint8 arenaType) const
+uint32 BattleGroundMgr::BGQueueTypeId(BattleGroundTypeId bgTypeId, uint8 arenaType)
{
switch(bgTypeId)
{
- case BATTLEGROUND_WS:
- return BATTLEGROUND_QUEUE_WS;
- case BATTLEGROUND_AB:
- return BATTLEGROUND_QUEUE_AB;
- case BATTLEGROUND_AV:
- return BATTLEGROUND_QUEUE_AV;
- case BATTLEGROUND_EY:
- return BATTLEGROUND_QUEUE_EY;
- case BATTLEGROUND_AA:
- case BATTLEGROUND_NA:
- case BATTLEGROUND_RL:
- case BATTLEGROUND_BE:
- switch(arenaType)
- {
- case ARENA_TYPE_2v2:
- return BATTLEGROUND_QUEUE_2v2;
- case ARENA_TYPE_3v3:
- return BATTLEGROUND_QUEUE_3v3;
- case ARENA_TYPE_5v5:
- return BATTLEGROUND_QUEUE_5v5;
+ case BATTLEGROUND_WS:
+ return BATTLEGROUND_QUEUE_WS;
+ case BATTLEGROUND_AB:
+ return BATTLEGROUND_QUEUE_AB;
+ case BATTLEGROUND_AV:
+ return BATTLEGROUND_QUEUE_AV;
+ case BATTLEGROUND_EY:
+ return BATTLEGROUND_QUEUE_EY;
+ case BATTLEGROUND_SA:
+ return BATTLEGROUND_QUEUE_SA;
+ case BATTLEGROUND_AA:
+ case BATTLEGROUND_NA:
+ case BATTLEGROUND_RL:
+ case BATTLEGROUND_BE:
+ case BATTLEGROUND_DS:
+ case BATTLEGROUND_RV:
+ switch(arenaType)
+ {
+ case ARENA_TYPE_2v2:
+ return BATTLEGROUND_QUEUE_2v2;
+ case ARENA_TYPE_3v3:
+ return BATTLEGROUND_QUEUE_3v3;
+ case ARENA_TYPE_5v5:
+ return BATTLEGROUND_QUEUE_5v5;
+ default:
+ return 0;
+ }
default:
return 0;
- }
- default:
- return 0;
}
}
-uint32 BattleGroundMgr::BGTemplateId(uint32 bgQueueTypeId) const
+BattleGroundTypeId BattleGroundMgr::BGTemplateId(uint32 bgQueueTypeId)
{
switch(bgQueueTypeId)
{
- case BATTLEGROUND_QUEUE_WS:
- return BATTLEGROUND_WS;
- case BATTLEGROUND_QUEUE_AB:
- return BATTLEGROUND_AB;
- case BATTLEGROUND_QUEUE_AV:
- return BATTLEGROUND_AV;
- case BATTLEGROUND_QUEUE_EY:
- return BATTLEGROUND_EY;
- case BATTLEGROUND_QUEUE_2v2:
- case BATTLEGROUND_QUEUE_3v3:
- case BATTLEGROUND_QUEUE_5v5:
- return BATTLEGROUND_AA;
- default:
- return 0;
+ case BATTLEGROUND_QUEUE_WS:
+ return BATTLEGROUND_WS;
+ case BATTLEGROUND_QUEUE_AB:
+ return BATTLEGROUND_AB;
+ case BATTLEGROUND_QUEUE_AV:
+ return BATTLEGROUND_AV;
+ case BATTLEGROUND_QUEUE_EY:
+ return BATTLEGROUND_EY;
+ case BATTLEGROUND_QUEUE_SA:
+ return BATTLEGROUND_SA;
+ case BATTLEGROUND_QUEUE_2v2:
+ case BATTLEGROUND_QUEUE_3v3:
+ case BATTLEGROUND_QUEUE_5v5:
+ return BATTLEGROUND_AA;
+ default:
+ return BattleGroundTypeId(0); // used for unknown template (it existed and do nothing)
}
}
-uint8 BattleGroundMgr::BGArenaType(uint32 bgQueueTypeId) const
+uint8 BattleGroundMgr::BGArenaType(uint32 bgQueueTypeId)
{
switch(bgQueueTypeId)
{
- case BATTLEGROUND_QUEUE_2v2:
- return ARENA_TYPE_2v2;
- case BATTLEGROUND_QUEUE_3v3:
- return ARENA_TYPE_3v3;
- case BATTLEGROUND_QUEUE_5v5:
- return ARENA_TYPE_5v5;
- default:
- return 0;
+ case BATTLEGROUND_QUEUE_2v2:
+ return ARENA_TYPE_2v2;
+ case BATTLEGROUND_QUEUE_3v3:
+ return ARENA_TYPE_3v3;
+ case BATTLEGROUND_QUEUE_5v5:
+ return ARENA_TYPE_5v5;
+ default:
+ return 0;
}
}
+void BattleGroundMgr::ToggleTesting()
+{
+ m_Testing = !m_Testing;
+ if(m_Testing)
+ sWorld.SendWorldText(LANG_DEBUG_BG_ON);
+ else
+ sWorld.SendWorldText(LANG_DEBUG_BG_OFF);
+}
+
void BattleGroundMgr::ToggleArenaTesting()
{
m_ArenaTesting = !m_ArenaTesting;
if(m_ArenaTesting)
- sWorld.SendGlobalText("Arenas are set to 1v1 for debugging. So, don't join as group.", NULL);
+ sWorld.SendWorldText(LANG_DEBUG_ARENA_ON);
else
- sWorld.SendGlobalText("Arenas are set to normal playercount.", NULL);
+ sWorld.SendWorldText(LANG_DEBUG_ARENA_OFF);
}
void BattleGroundMgr::SetHolidayWeekends(uint32 mask)
{
- for(uint32 bgtype = 1; bgtype <= 8; ++bgtype)
+ for(uint32 bgtype = 1; bgtype < MAX_BATTLEGROUND_TYPE_ID; ++bgtype)
{
- if(BattleGround * bg = GetBattleGroundTemplate(bgtype))
+ if(BattleGround * bg = GetBattleGroundTemplate(BattleGroundTypeId(bgtype)))
{
bg->SetHoliday(mask & (1 << bgtype));
}
}
}
+
+uint32 BattleGroundMgr::GetMaxRatingDifference() const
+{
+ return sWorld.getConfig(CONFIG_ARENA_MAX_RATING_DIFFERENCE);
+}
+
+uint32 BattleGroundMgr::GetRatingDiscardTimer() const
+{
+ return sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER);
+}
+
+uint32 BattleGroundMgr::GetPrematureFinishTime() const
+{
+ return sWorld.getConfig(CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER);
+}
+
+void BattleGroundMgr::LoadBattleMastersEntry()
+{
+ mBattleMastersMap.clear(); // need for reload case
+
+ QueryResult *result = WorldDatabase.Query( "SELECT entry,bg_template FROM battlemaster_entry" );
+
+ uint32 count = 0;
+
+ if( !result )
+ {
+ barGoLink bar( 1 );
+ bar.step();
+
+ sLog.outString();
+ sLog.outString( ">> Loaded 0 battlemaster entries - table is empty!" );
+ return;
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ do
+ {
+ ++count;
+ bar.step();
+
+ Field *fields = result->Fetch();
+
+ uint32 entry = fields[0].GetUInt32();
+ uint32 bgTypeId = fields[1].GetUInt32();
+ if (!sBattlemasterListStore.LookupEntry(bgTypeId))
+ {
+ sLog.outErrorDb("Table `battlemaster_entry` contain entry %u for not existed battleground type %u, ignored.",entry,bgTypeId);
+ continue;
+ }
+
+ mBattleMastersMap[entry] = BattleGroundTypeId(bgTypeId);
+
+ } while( result->NextRow() );
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u battlemaster entries", count );
+}
diff --git a/src/game/BattleGroundMgr.h b/src/game/BattleGroundMgr.h
index 70b899d5f85..2b684487e1e 100644
--- a/src/game/BattleGroundMgr.h
+++ b/src/game/BattleGroundMgr.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -21,10 +21,8 @@
#ifndef __BATTLEGROUNDMGR_H
#define __BATTLEGROUNDMGR_H
+#include "Common.h"
#include "BattleGround.h"
-#include "Policies/Singleton.h"
-
-class BattleGround;
//TODO it is not possible to have this structure, because we should have BattlegroundSet for each queue
//so i propose to change this type to array 1..MAX_BATTLEGROUND_TYPES of sets or maps..
@@ -32,13 +30,13 @@ typedef std::map<uint32, BattleGround*> BattleGroundSet;
//typedef std::map<uint32, BattleGroundQueue*> BattleGroundQueueSet;
typedef std::deque<BattleGround*> BGFreeSlotQueueType;
-#define MAX_BATTLEGROUND_QUEUES 7 // for level ranges 10-19, 20-29, 30-39, 40-49, 50-59, 60-69, 70+
+typedef UNORDERED_MAP<uint32, BattleGroundTypeId> BattleMastersMap;
-#define MAX_BATTLEGROUND_TYPES 9 // each BG type will be in array
+#define MAX_BATTLEGROUND_QUEUES 8 // for level ranges 10-19, 20-29, 30-39, 40-49, 50-59, 60-69, 70-79, 80+
-#define MAX_BATTLEGROUND_QUEUE_TYPES 8
+#define MAX_BATTLEGROUND_QUEUE_TYPES 9
-#define BATTLEGROUND_ARENA_POINT_DISTRIBUTION_DAY 86400 // seconds in a day
+#define BATTLEGROUND_ARENA_POINT_DISTRIBUTION_DAY 86400 // seconds in a day
struct GroupQueueInfo; // type predefinition
struct PlayerQueueInfo // stores information for players in queue
@@ -53,7 +51,7 @@ struct GroupQueueInfo // stores informatio
{
std::map<uint64, PlayerQueueInfo*> Players; // player queue info map
uint32 Team; // Player team (ALLIANCE/HORDE)
- uint32 BgTypeId; // battleground type id
+ BattleGroundTypeId BgTypeId; // battleground type id
bool IsRated; // rated
uint8 ArenaType; // 2v2, 3v3, 5v5 or 0 when BG
uint32 ArenaTeamId; // team id if rated match
@@ -70,13 +68,14 @@ class BattleGroundQueue
BattleGroundQueue();
~BattleGroundQueue();
- void Update(uint32 bgTypeId, uint32 queue_id, uint8 arenatype = 0, bool isRated = false, uint32 minRating = 0);
+ void Update(BattleGroundTypeId bgTypeId, uint32 queue_id, uint8 arenatype = 0, bool isRated = false, uint32 minRating = 0);
- GroupQueueInfo * AddGroup(Player * leader, uint32 BgTypeId, uint8 ArenaType, bool isRated, uint32 ArenaRating, uint32 ArenaTeamId = 0);
+ GroupQueueInfo * AddGroup(Player * leader, BattleGroundTypeId bgTypeId, uint8 ArenaType, bool isRated, uint32 ArenaRating, uint32 ArenaTeamId = 0);
void AddPlayer(Player *plr, GroupQueueInfo *ginfo);
- void RemovePlayer(uint64 guid, bool decreaseInvitedCount);
+ void RemovePlayer(const uint64& guid, bool decreaseInvitedCount);
void DecreaseGroupLength(uint32 queueId, uint32 AsGroup);
void BGEndedRemoveInvites(BattleGround * bg);
+ void AnnounceWorld(GroupQueueInfo *ginfo, const uint64& playerGUID, bool isAddedToQueue);
typedef std::map<uint64, PlayerQueueInfo> QueuedPlayersMap;
QueuedPlayersMap m_QueuedPlayers[MAX_BATTLEGROUND_QUEUES];
@@ -88,7 +87,7 @@ class BattleGroundQueue
class EligibleGroups : public std::list<GroupQueueInfo *>
{
public:
- void Init(QueuedGroupsList * source, uint32 BgTypeId, uint32 side, uint32 MaxPlayers, uint8 ArenaType = 0, bool IsRated = false, uint32 MinRating = 0, uint32 MaxRating = 0, uint32 DisregardTime = 0, uint32 excludeTeam = 0);
+ void Init(QueuedGroupsList * source, BattleGroundTypeId BgTypeId, uint32 side, uint32 MaxPlayers, uint8 ArenaType = 0, bool IsRated = false, uint32 MinRating = 0, uint32 MaxRating = 0, uint32 DisregardTime = 0, uint32 excludeTeam = 0);
};
EligibleGroups m_EligibleGroups;
@@ -123,7 +122,7 @@ class BattleGroundQueue
SelectionPool m_SelectionPools[NUM_SELECTION_POOL_TYPES];
- bool BuildSelectionPool(uint32 bgTypeId, uint32 queue_id, uint32 MinPlayers, uint32 MaxPlayers, SelectionPoolBuildMode mode, uint8 ArenaType = 0, bool isRated = false, uint32 MinRating = 0, uint32 MaxRating = 0, uint32 DisregardTime = 0, uint32 excludeTeam = 0);
+ bool BuildSelectionPool(BattleGroundTypeId bgTypeId, uint32 queue_id, uint32 MinPlayers, uint32 MaxPlayers, SelectionPoolBuildMode mode, uint8 ArenaType = 0, bool isRated = false, uint32 MinRating = 0, uint32 MaxRating = 0, uint32 DisregardTime = 0, uint32 excludeTeam = 0);
private:
@@ -137,7 +136,7 @@ class BattleGroundQueue
class BGQueueInviteEvent : public BasicEvent
{
public:
- BGQueueInviteEvent(uint64 pl_guid, uint32 BgInstanceGUID) : m_PlayerGuid(pl_guid), m_BgInstanceGUID(BgInstanceGUID) {};
+ BGQueueInviteEvent(const uint64& pl_guid, uint32 BgInstanceGUID) : m_PlayerGuid(pl_guid), m_BgInstanceGUID(BgInstanceGUID) {};
virtual ~BGQueueInviteEvent() {};
virtual bool Execute(uint64 e_time, uint32 p_time);
@@ -153,7 +152,10 @@ class BGQueueInviteEvent : public BasicEvent
class BGQueueRemoveEvent : public BasicEvent
{
public:
- BGQueueRemoveEvent(uint64 pl_guid, uint32 bgInstanceGUID, uint32 playersTeam) : m_PlayerGuid(pl_guid), m_BgInstanceGUID(bgInstanceGUID), m_PlayersTeam(playersTeam) {};
+ BGQueueRemoveEvent(const uint64& pl_guid, uint32 bgInstanceGUID, uint32 playersTeam) :
+ m_PlayerGuid(pl_guid), m_BgInstanceGUID(bgInstanceGUID), m_PlayersTeam(playersTeam)
+ {
+ };
virtual ~BGQueueRemoveEvent() {};
virtual bool Execute(uint64 e_time, uint32 p_time);
@@ -170,83 +172,89 @@ class BattleGroundMgr
/* Construction */
BattleGroundMgr();
~BattleGroundMgr();
- void Update(time_t diff);
+ void Update(uint32 diff);
/* Packet Building */
void BuildPlayerJoinedBattleGroundPacket(WorldPacket *data, Player *plr);
void BuildPlayerLeftBattleGroundPacket(WorldPacket *data, Player *plr);
- void BuildBattleGroundListPacket(WorldPacket *data, uint64 guid, Player *plr, uint32 bgTypeId);
- void BuildGroupJoinedBattlegroundPacket(WorldPacket *data, uint32 bgTypeId);
+ void BuildBattleGroundListPacket(WorldPacket *data, const uint64& guid, Player *plr, BattleGroundTypeId bgTypeId);
+ void BuildGroupJoinedBattlegroundPacket(WorldPacket *data, BattleGroundTypeId bgTypeId);
void BuildUpdateWorldStatePacket(WorldPacket *data, uint32 field, uint32 value);
void BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg);
void BuildBattleGroundStatusPacket(WorldPacket *data, BattleGround *bg, uint32 team, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint32 arenatype = 0, uint8 israted = 0);
void BuildPlaySoundPacket(WorldPacket *data, uint32 soundid);
+ void SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround *bg, const uint64& guid);
/* Player invitation */
// called from Queue update, or from Addplayer to queue
void InvitePlayer(Player* plr, uint32 bgInstanceGUID, uint32 team);
/* Battlegrounds */
BattleGroundSet::iterator GetBattleGroundsBegin() { return m_BattleGrounds.begin(); };
- BattleGroundSet::iterator GetBattleGroundsEnd() { return m_BattleGrounds.end(); };
+ BattleGroundSet::iterator GetBattleGroundsEnd() { return m_BattleGrounds.end(); };
- BattleGround* GetBattleGround(uint32 ID)
+ BattleGround* GetBattleGround(uint32 InstanceID)
{
- BattleGroundSet::iterator i = m_BattleGrounds.find(ID);
- if(i != m_BattleGrounds.end())
- return i->second;
- else
- return NULL;
+ BattleGroundSet::iterator i = m_BattleGrounds.find(InstanceID);
+ return ( (i != m_BattleGrounds.end()) ? i->second : NULL );
};
- BattleGround * GetBattleGroundTemplate(uint32 bgTypeId);
- BattleGround * CreateNewBattleGround(uint32 bgTypeId);
+ BattleGround * GetBattleGroundTemplate(BattleGroundTypeId bgTypeId);
+ BattleGround * CreateNewBattleGround(BattleGroundTypeId bgTypeId);
- uint32 CreateBattleGround(uint32 bgTypeId, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam, uint32 LevelMin, uint32 LevelMax, char* BattleGroundName, uint32 MapID, float Team1StartLocX, float Team1StartLocY, float Team1StartLocZ, float Team1StartLocO, float Team2StartLocX, float Team2StartLocY, float Team2StartLocZ, float Team2StartLocO);
+ uint32 CreateBattleGround(BattleGroundTypeId bgTypeId, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam, uint32 LevelMin, uint32 LevelMax, char* BattleGroundName, uint32 MapID, float Team1StartLocX, float Team1StartLocY, float Team1StartLocZ, float Team1StartLocO, float Team2StartLocX, float Team2StartLocY, float Team2StartLocZ, float Team2StartLocO);
- inline void AddBattleGround(uint32 ID, BattleGround* BG) { m_BattleGrounds[ID] = BG; };
- void RemoveBattleGround(uint32 instanceID);
+ void AddBattleGround(uint32 InstanceID, BattleGround* BG) { m_BattleGrounds[InstanceID] = BG; };
+ void RemoveBattleGround(uint32 instanceID) { m_BattleGrounds.erase(instanceID); }
void CreateInitialBattleGrounds();
+ void DeleteAlllBattleGrounds();
- void SendToBattleGround(Player *pl, uint32 bgTypeId);
+ void SendToBattleGround(Player *pl, uint32 InstanceID);
/* Battleground queues */
//these queues are instantiated when creating BattlegroundMrg
BattleGroundQueue m_BattleGroundQueues[MAX_BATTLEGROUND_QUEUE_TYPES]; // public, because we need to access them in BG handler code
- BGFreeSlotQueueType BGFreeSlotQueue[MAX_BATTLEGROUND_TYPES];
-
- void SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround *bg, uint64 guid);
+ BGFreeSlotQueueType BGFreeSlotQueue[MAX_BATTLEGROUND_TYPE_ID];
- bool IsArenaType(uint32 bgTypeId) const;
- bool IsBattleGroundType(uint32 bgTypeId) const;
- uint32 BGQueueTypeId(uint32 bgTypeId, uint8 arenaType) const;
- uint32 BGTemplateId(uint32 bgQueueTypeId) const;
- uint8 BGArenaType(uint32 bgQueueTypeId) const;
-
- uint32 GetMaxRatingDifference() const {return m_MaxRatingDifference;}
- uint32 GetRatingDiscardTimer() const {return m_RatingDiscardTimer;}
+ uint32 GetMaxRatingDifference() const;
+ uint32 GetRatingDiscardTimer() const;
+ uint32 GetPrematureFinishTime() const;
void InitAutomaticArenaPointDistribution();
void DistributeArenaPoints();
- uint32 GetPrematureFinishTime() const {return m_PrematureFinishTimer;}
void ToggleArenaTesting();
- const bool isArenaTesting() const { return m_ArenaTesting; }
+ void ToggleTesting();
void SetHolidayWeekends(uint32 mask);
+ void LoadBattleMastersEntry();
+ BattleGroundTypeId GetBattleMasterBG(uint32 entry) const
+ {
+ BattleMastersMap::const_iterator itr = mBattleMastersMap.find(entry);
+ if(itr != mBattleMastersMap.end())
+ return itr->second;
+ return BATTLEGROUND_WS;
+ }
+
+ bool isArenaTesting() const { return m_ArenaTesting; }
+ bool isTesting() const { return m_Testing; }
+
+ static bool IsArenaType(BattleGroundTypeId bgTypeId);
+ static bool IsBattleGroundType(BattleGroundTypeId bgTypeId) { return !BattleGroundMgr::IsArenaType(bgTypeId); }
+ static uint32 BGQueueTypeId(BattleGroundTypeId bgTypeId, uint8 arenaType);
+ static BattleGroundTypeId BGTemplateId(uint32 bgQueueTypeId);
+ static uint8 BGArenaType(uint32 bgQueueTypeId);
private:
+ BattleMastersMap mBattleMastersMap;
/* Battlegrounds */
BattleGroundSet m_BattleGrounds;
- uint32 m_MaxRatingDifference;
- uint32 m_RatingDiscardTimer;
uint32 m_NextRatingDiscardUpdate;
- bool m_AutoDistributePoints;
uint64 m_NextAutoDistributionTime;
uint32 m_AutoDistributionTimeChecker;
- uint32 m_PrematureFinishTimer;
bool m_ArenaTesting;
+ bool m_Testing;
};
#define sBattleGroundMgr Trinity::Singleton<BattleGroundMgr>::Instance()
diff --git a/src/game/BattleGroundNA.cpp b/src/game/BattleGroundNA.cpp
index f06910af986..ad6d622e71a 100644
--- a/src/game/BattleGroundNA.cpp
+++ b/src/game/BattleGroundNA.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -25,6 +25,7 @@
#include "Creature.h"
#include "ObjectMgr.h"
#include "MapManager.h"
+#include "WorldPacket.h"
#include "Language.h"
BattleGroundNA::BattleGroundNA()
@@ -37,7 +38,7 @@ BattleGroundNA::~BattleGroundNA()
}
-void BattleGroundNA::Update(time_t diff)
+void BattleGroundNA::Update(uint32 diff)
{
BattleGround::Update(diff);
diff --git a/src/game/BattleGroundNA.h b/src/game/BattleGroundNA.h
index 45dc9efec31..9fb94263e9c 100644
--- a/src/game/BattleGroundNA.h
+++ b/src/game/BattleGroundNA.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -58,7 +58,7 @@ class BattleGroundNA : public BattleGround
public:
BattleGroundNA();
~BattleGroundNA();
- void Update(time_t diff);
+ void Update(uint32 diff);
/* inherited from BattlegroundClass */
virtual void AddPlayer(Player *plr);
diff --git a/src/game/BattleGroundRL.cpp b/src/game/BattleGroundRL.cpp
index 193578e88b0..85117acd2f6 100644
--- a/src/game/BattleGroundRL.cpp
+++ b/src/game/BattleGroundRL.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -26,6 +26,7 @@
#include "ObjectMgr.h"
#include "MapManager.h"
#include "Language.h"
+#include "WorldPacket.h"
BattleGroundRL::BattleGroundRL()
{
@@ -37,7 +38,7 @@ BattleGroundRL::~BattleGroundRL()
}
-void BattleGroundRL::Update(time_t diff)
+void BattleGroundRL::Update(uint32 diff)
{
BattleGround::Update(diff);
diff --git a/src/game/BattleGroundRL.h b/src/game/BattleGroundRL.h
index d3f58264833..0fd1af89506 100644
--- a/src/game/BattleGroundRL.h
+++ b/src/game/BattleGroundRL.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -54,7 +54,7 @@ class BattleGroundRL : public BattleGround
public:
BattleGroundRL();
~BattleGroundRL();
- void Update(time_t diff);
+ void Update(uint32 diff);
/* inherited from BattlegroundClass */
virtual void AddPlayer(Player *plr);
diff --git a/src/game/BattleGroundRV.cpp b/src/game/BattleGroundRV.cpp
new file mode 100644
index 00000000000..a66f0ce30e2
--- /dev/null
+++ b/src/game/BattleGroundRV.cpp
@@ -0,0 +1,63 @@
+/*
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "Player.h"
+#include "BattleGround.h"
+#include "BattleGroundRV.h"
+
+BattleGroundRV::BattleGroundRV()
+{
+
+}
+
+BattleGroundRV::~BattleGroundRV()
+{
+
+}
+
+void BattleGroundRV::Update(uint32 diff)
+{
+ BattleGround::Update(diff);
+}
+
+void BattleGroundRV::AddPlayer(Player *plr)
+{
+ BattleGround::AddPlayer(plr);
+ //create score and add it to map, default values are set in constructor
+ BattleGroundRVScore* sc = new BattleGroundRVScore;
+
+ m_PlayerScores[plr->GetGUID()] = sc;
+}
+
+void BattleGroundRV::RemovePlayer(Player * /*plr*/, uint64 /*guid*/)
+{
+}
+
+void BattleGroundRV::HandleKillPlayer(Player* player, Player* killer)
+{
+ BattleGround::HandleKillPlayer(player, killer);
+}
+
+void BattleGroundRV::HandleAreaTrigger(Player * /*Source*/, uint32 /*Trigger*/)
+{
+}
+
+bool BattleGroundRV::SetupBattleGround()
+{
+ return true;
+}
diff --git a/src/game/BattleGroundRV.h b/src/game/BattleGroundRV.h
new file mode 100644
index 00000000000..2d2ad12c941
--- /dev/null
+++ b/src/game/BattleGroundRV.h
@@ -0,0 +1,47 @@
+/*
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __BATTLEGROUNDRV_H
+#define __BATTLEGROUNDRV_H
+
+class BattleGround;
+
+class BattleGroundRVScore : public BattleGroundScore
+{
+ public:
+ BattleGroundRVScore() {};
+ virtual ~BattleGroundRVScore() {};
+ //TODO fix me
+};
+
+class BattleGroundRV : public BattleGround
+{
+ friend class BattleGroundMgr;
+
+ public:
+ BattleGroundRV();
+ ~BattleGroundRV();
+ void Update(uint32 diff);
+
+ /* inherited from BattlegroundClass */
+ virtual void AddPlayer(Player *plr);
+ void RemovePlayer(Player *plr, uint64 guid);
+ void HandleAreaTrigger(Player *Source, uint32 Trigger);
+ bool SetupBattleGround();
+ void HandleKillPlayer(Player* player, Player *killer);
+};
+#endif
diff --git a/src/game/BattleGroundSA.cpp b/src/game/BattleGroundSA.cpp
new file mode 100644
index 00000000000..d5585fd93e9
--- /dev/null
+++ b/src/game/BattleGroundSA.cpp
@@ -0,0 +1,68 @@
+/*
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "BattleGround.h"
+#include "BattleGroundSA.h"
+#include "Player.h"
+
+BattleGroundSA::BattleGroundSA()
+{
+
+}
+
+BattleGroundSA::~BattleGroundSA()
+{
+
+}
+
+void BattleGroundSA::Update(uint32 diff)
+{
+ BattleGround::Update(diff);
+}
+
+void BattleGroundSA::AddPlayer(Player *plr)
+{
+ BattleGround::AddPlayer(plr);
+ //create score and add it to map, default values are set in constructor
+ BattleGroundSAScore* sc = new BattleGroundSAScore;
+
+ m_PlayerScores[plr->GetGUID()] = sc;
+}
+
+void BattleGroundSA::RemovePlayer(Player* /*plr*/,uint64 /*guid*/)
+{
+
+}
+
+void BattleGroundSA::HandleAreaTrigger(Player *Source, uint32 Trigger)
+{
+ // this is wrong way to implement these things. On official it done by gameobject spell cast.
+ if(GetStatus() != STATUS_IN_PROGRESS)
+ return;
+}
+
+void BattleGroundSA::UpdatePlayerScore(Player* Source, uint32 type, uint32 value)
+{
+
+ std::map<uint64, BattleGroundScore*>::iterator itr = m_PlayerScores.find(Source->GetGUID());
+
+ if(itr == m_PlayerScores.end()) // player not found...
+ return;
+
+ BattleGround::UpdatePlayerScore(Source,type,value);
+}
diff --git a/src/game/BattleGroundSA.h b/src/game/BattleGroundSA.h
new file mode 100644
index 00000000000..331a41455fd
--- /dev/null
+++ b/src/game/BattleGroundSA.h
@@ -0,0 +1,52 @@
+/*
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __BATTLEGROUNDSA_H
+#define __BATTLEGROUNDSA_H
+
+class BattleGround;
+
+class BattleGroundSAScore : public BattleGroundScore
+{
+ public:
+ BattleGroundSAScore() {};
+ virtual ~BattleGroundSAScore() {};
+};
+
+class BattleGroundSA : public BattleGround
+{
+ friend class BattleGroundMgr;
+
+ public:
+ BattleGroundSA();
+ ~BattleGroundSA();
+ void Update(uint32 diff);
+
+ /* inherited from BattlegroundClass */
+ virtual void AddPlayer(Player *plr);
+
+ void RemovePlayer(Player *plr,uint64 guid);
+ void HandleAreaTrigger(Player *Source, uint32 Trigger);
+ //bool SetupBattleGround();
+
+ /* Scorekeeping */
+ void UpdatePlayerScore(Player *Source, uint32 type, uint32 value);
+
+ private:
+};
+#endif
diff --git a/src/game/BattleGroundWS.cpp b/src/game/BattleGroundWS.cpp
index 755089473e8..3175f2873f9 100644
--- a/src/game/BattleGroundWS.cpp
+++ b/src/game/BattleGroundWS.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -26,6 +26,8 @@
#include "GameObject.h"
#include "Chat.h"
#include "MapManager.h"
+#include "ObjectMgr.h"
+#include "WorldPacket.h"
#include "Language.h"
#include "World.h"
@@ -58,7 +60,7 @@ BattleGroundWS::~BattleGroundWS()
{
}
-void BattleGroundWS::Update(time_t diff)
+void BattleGroundWS::Update(uint32 diff)
{
BattleGround::Update(diff);
diff --git a/src/game/BattleGroundWS.h b/src/game/BattleGroundWS.h
index 17b59d98343..0c9baee1c76 100644
--- a/src/game/BattleGroundWS.h
+++ b/src/game/BattleGroundWS.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -136,7 +136,7 @@ class BattleGroundWS : public BattleGround
/* Construction */
BattleGroundWS();
~BattleGroundWS();
- void Update(time_t diff);
+ void Update(uint32 diff);
/* inherited from BattlegroundClass */
virtual void AddPlayer(Player *plr);
diff --git a/src/game/CMakeLists.txt b/src/game/CMakeLists.txt
index bcd85792b04..4d438f31d52 100644
--- a/src/game/CMakeLists.txt
+++ b/src/game/CMakeLists.txt
@@ -4,6 +4,8 @@
SET(game_STAT_SRCS
AccountMgr.cpp
AccountMgr.h
+ AchievementMgr.h
+ AchievementMgr.cpp
AddonHandler.cpp
AddonHandler.h
AggressorAI.cpp
@@ -23,22 +25,31 @@ SET(game_STAT_SRCS
BattleGroundAB.cpp
BattleGroundAV.cpp
BattleGroundBE.cpp
+ BattleGroundDS.cpp
BattleGroundEY.cpp
BattleGroundNA.cpp
BattleGroundRL.cpp
+ BattleGroundRV.cpp
+ BattleGroundSA.cpp
BattleGroundWS.cpp
BattleGround.h
BattleGroundAA.h
BattleGroundAB.h
BattleGroundAV.h
BattleGroundBE.h
+ BattleGroundDS.h
BattleGroundEY.h
BattleGroundNA.h
BattleGroundRL.h
+ BattleGroundRV.h
+ BattleGroundSA.h
BattleGroundWS.h
BattleGroundHandler.cpp
BattleGroundMgr.cpp
BattleGroundMgr.h
+ Calendar.cpp
+ Calendar.h
+ CalendarHandler.cpp
Cell.h
CellImpl.h
Channel.cpp
@@ -130,6 +141,8 @@ SET(game_STAT_SRCS
MapInstanced.h
MapManager.cpp
MapManager.h
+ MapReference.h
+ MapRefManager.h
MiscHandler.cpp
MotionMaster.cpp
MotionMaster.h
@@ -150,6 +163,8 @@ SET(game_STAT_SRCS
Object.h
ObjectMgr.cpp
ObjectMgr.h
+ ObjectPosSelector.cpp
+ ObjectPosSelector.h
Opcodes.cpp
Opcodes.h
OutdoorPvP.cpp
@@ -240,6 +255,8 @@ SET(game_STAT_SRCS
UpdateData.h
UpdateFields.h
UpdateMask.h
+ Vehicle.cpp
+ Vehicle.h
VoiceChatHandler.cpp
WaypointManager.cpp
WaypointManager.h
diff --git a/src/game/Calendar.cpp b/src/game/Calendar.cpp
new file mode 100644
index 00000000000..0c1efb20f87
--- /dev/null
+++ b/src/game/Calendar.cpp
@@ -0,0 +1,17 @@
+/*
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
diff --git a/src/game/Calendar.h b/src/game/Calendar.h
new file mode 100644
index 00000000000..7a86afa7db7
--- /dev/null
+++ b/src/game/Calendar.h
@@ -0,0 +1,26 @@
+/*
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef MANGOS_CALENDAR_H
+#define MANGOS_CALENDAR_H
+
+class Calendar
+{
+
+};
+#endif
diff --git a/src/game/CalendarHandler.cpp b/src/game/CalendarHandler.cpp
new file mode 100644
index 00000000000..e9946e1a05e
--- /dev/null
+++ b/src/game/CalendarHandler.cpp
@@ -0,0 +1,159 @@
+/*
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "Common.h"
+#include "Log.h"
+#include "Player.h"
+#include "WorldPacket.h"
+#include "WorldSession.h"
+#include "Opcodes.h"
+#include "InstanceSaveMgr.h"
+
+void WorldSession::HandleCalendarGetCalendar(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_GET_CALENDAR");
+ recv_data.hexlike();
+
+ time_t cur_time = time(NULL);
+
+ WorldPacket data(SMSG_CALENDAR_SEND_CALENDAR,4+4*0+4+4*0+4+4);
+
+ // TODO: calendar invite event output
+ data << (uint32) 0; //invite node count
+ // TODO: calendar event output
+ data << (uint32) 0; //event count
+
+ data << (uint32) 0; //wtf??
+ data << (uint32) secsToTimeBitFields(cur_time); // current time
+
+ uint32 counter = 0;
+ size_t p_counter = data.wpos();
+ data << uint32(counter); // instance save count
+
+ for(int i = 0; i < TOTAL_DIFFICULTIES; ++i)
+ {
+ for (Player::BoundInstancesMap::iterator itr = _player->m_boundInstances[i].begin(); itr != _player->m_boundInstances[i].end(); ++itr)
+ {
+ if(itr->second.perm)
+ {
+ InstanceSave *save = itr->second.save;
+ data << uint32(save->GetMapId());
+ data << uint32(save->GetDifficulty());
+ data << uint32(save->GetResetTime() - cur_time);
+ data << uint64(save->GetInstanceId()); // instance save id as unique instance copy id
+ ++counter;
+ }
+ }
+ }
+ data.put<uint32>(p_counter,counter);
+
+ data << (uint32) 1135753200; //wtf?? (28.12.2005 12:00)
+ data << (uint32) 0; // unk counter 4
+ data << (uint32) 0; // unk counter 5
+ //sLog.outDebug("Sending calendar");
+ //data.hexlike();
+ SendPacket(&data);
+}
+
+void WorldSession::HandleCalendarGetEvent(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_GET_EVENT");
+ recv_data.hexlike();
+}
+
+void WorldSession::HandleCalendarGuildFilter(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_GUILD_FILTER");
+ recv_data.hexlike();
+}
+
+void WorldSession::HandleCalendarArenaTeam(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_ARENA_TEAM");
+ recv_data.hexlike();
+}
+
+void WorldSession::HandleCalendarAddEvent(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_ADD_EVENT");
+ recv_data.hexlike();
+}
+
+void WorldSession::HandleCalendarUpdateEvent(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_UPDATE_EVENT");
+ recv_data.hexlike();
+}
+
+void WorldSession::HandleCalendarRemoveEvent(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_REMOVE_EVENT");
+ recv_data.hexlike();
+}
+
+void WorldSession::HandleCalendarCopyEvent(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_COPY_EVENT");
+ recv_data.hexlike();
+}
+
+void WorldSession::HandleCalendarEventInvite(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_INVITE");
+ recv_data.hexlike();
+}
+
+void WorldSession::HandleCalendarEventRsvp(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_RSVP");
+ recv_data.hexlike();
+}
+
+void WorldSession::HandleCalendarEventRemoveInvite(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_REMOVE_INVITE");
+ recv_data.hexlike();
+}
+
+void WorldSession::HandleCalendarEventStatus(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_STATUS");
+ recv_data.hexlike();
+}
+
+void WorldSession::HandleCalendarEventModeratorStatus(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_MODERATOR_STATUS");
+ recv_data.hexlike();
+}
+
+void WorldSession::HandleCalendarComplain(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_COMPLAIN");
+ recv_data.hexlike();
+}
+
+void WorldSession::HandleCalendarGetNumPending(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: CMSG_CALENDAR_GET_NUM_PENDING");
+ recv_data.hexlike();
+
+ WorldPacket data(SMSG_CALENDAR_SEND_NUM_PENDING, 4);
+ data << uint32(0); // 0 - no pending invites, 1 - some pending invites
+ SendPacket(&data);
+}
diff --git a/src/game/Cell.h b/src/game/Cell.h
index 35bcdbeea8a..2459e3e73d2 100644
--- a/src/game/Cell.h
+++ b/src/game/Cell.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -93,13 +93,13 @@ struct TRINITY_DLL_DECL Cell
y = data.Part.grid_y*MAX_NUMBER_OF_CELLS + data.Part.cell_y;
}
- inline bool DiffCell(const Cell &cell) const
+ bool DiffCell(const Cell &cell) const
{
return( data.Part.cell_x != cell.data.Part.cell_x ||
data.Part.cell_y != cell.data.Part.cell_y );
}
- inline bool DiffGrid(const Cell &cell) const
+ bool DiffGrid(const Cell &cell) const
{
return( data.Part.grid_x != cell.data.Part.grid_x ||
data.Part.grid_y != cell.data.Part.grid_y );
diff --git a/src/game/CellImpl.h b/src/game/CellImpl.h
index ee026ec8353..0aea067b32b 100644
--- a/src/game/CellImpl.h
+++ b/src/game/CellImpl.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/Channel.cpp b/src/game/Channel.cpp
index e05a9793857..992a20353ac 100644
--- a/src/game/Channel.cpp
+++ b/src/game/Channel.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/Channel.h b/src/game/Channel.h
index b8d322ee9f7..b4fe04feb44 100644
--- a/src/game/Channel.h
+++ b/src/game/Channel.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/ChannelHandler.cpp b/src/game/ChannelHandler.cpp
index ae869f36d4d..2fc634077c5 100644
--- a/src/game/ChannelHandler.cpp
+++ b/src/game/ChannelHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/ChannelMgr.h b/src/game/ChannelMgr.h
index c31998c0569..a664e009b90 100644
--- a/src/game/ChannelMgr.h
+++ b/src/game/ChannelMgr.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp
index 192e85a5347..ffdd9942bb5 100644
--- a/src/game/CharacterHandler.cpp
+++ b/src/game/CharacterHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -64,11 +64,11 @@ bool LoginQueryHolder::Initialize()
// NOTE: all fields in `characters` must be read to prevent lost character data at next save in case wrong DB structure.
// !!! NOTE: including unused `zone`,`online`
- res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADFROM, "SELECT guid, account, data, name, race, class, 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, dungeon_difficulty, arena_pending_points FROM characters WHERE guid = '%u'", GUID_LOPART(m_guid));
+ res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADFROM, "SELECT guid, account, data, name, race, class, 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, dungeon_difficulty, arena_pending_points,bgid,bgteam,bgmap,bgx,bgy,bgz,bgo FROM characters WHERE guid = '%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGROUP, "SELECT leaderGuid FROM group_member WHERE memberGuid ='%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADBOUNDINSTANCES, "SELECT id, permanent, map, difficulty, resettime FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = '%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADAURAS, "SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'", GUID_LOPART(m_guid));
- res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSPELLS, "SELECT spell,slot,active,disabled FROM character_spell WHERE guid = '%u'", GUID_LOPART(m_guid));
+ res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSPELLS, "SELECT spell,active,disabled FROM character_spell WHERE guid = '%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADQUESTSTATUS, "SELECT quest,status,rewarded,explored,timer,mobcount1,mobcount2,mobcount3,mobcount4,itemcount1,itemcount2,itemcount3,itemcount4 FROM character_queststatus WHERE guid = '%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADDAILYQUESTSTATUS,"SELECT quest,time FROM character_queststatus_daily WHERE guid = '%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADTUTORIALS, "SELECT tut0,tut1,tut2,tut3,tut4,tut5,tut6,tut7 FROM character_tutorial WHERE account = '%u' AND realmid = '%u'", GetAccountId(), realmID);
@@ -85,6 +85,8 @@ bool LoginQueryHolder::Initialize()
// in other case still be dummy query
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGUILD, "SELECT guildid,rank FROM guild_member WHERE guid = '%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADARENAINFO, "SELECT arenateamid, played_week, played_season, personal_rating FROM arena_team_member WHERE guid='%u'", GUID_LOPART(m_guid));
+ res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADACHIEVEMENTS, "SELECT achievement, date FROM character_achievement WHERE guid = '%u'", GUID_LOPART(m_guid));
+ res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADCRITERIAPROGRESS,"SELECT criteria, counter, date FROM character_achievement_progress WHERE guid = '%u'", GUID_LOPART(m_guid));
return res;
}
@@ -234,17 +236,16 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data )
if (raceEntry->addon > Expansion())
{
data << (uint8)CHAR_CREATE_EXPANSION;
- sLog.outError("Not Expansion 1 account:[%d] but tried to Create character with expansion 1 race (%u)",GetAccountId(),race_);
+ sLog.outError("Expansion %u account:[%d] tried to Create character with expansion %u race (%u)",Expansion(),GetAccountId(),raceEntry->addon,race_);
SendPacket( &data );
return;
}
// prevent character creating Expansion class without Expansion account
- // TODO: use possible addon field in ChrClassesEntry in next dbc version
- if (Expansion() < 2 && class_ == CLASS_DEATH_KNIGHT)
+ if (classEntry->addon > Expansion())
{
- data << (uint8)CHAR_CREATE_EXPANSION;
- sLog.outError("Not Expansion 2 account:[%d] but tried to Create character with expansion 2 class (%u)",GetAccountId(),class_);
+ data << (uint8)CHAR_CREATE_EXPANSION_CLASS;
+ sLog.outError("Expansion %u account:[%d] tried to Create character with expansion %u class (%u)",Expansion(),GetAccountId(),classEntry->addon,class_);
SendPacket( &data );
return;
}
@@ -311,29 +312,77 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data )
}
}
+ // speedup check for heroic class disabled case
+ uint32 heroic_free_slots = sWorld.getConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM);
+ if(heroic_free_slots==0 && GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT)
+ {
+ data << (uint8)CHAR_CREATE_UNIQUE_CLASS_LIMIT;
+ SendPacket( &data );
+ return;
+ }
+
+ // speedup check for heroic class disabled case
+ uint32 req_level_for_heroic = sWorld.getConfig(CONFIG_MIN_LEVEL_FOR_HEROIC_CHARACTER_CREATING);
+ if(GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT && req_level_for_heroic > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
+ {
+ data << (uint8)CHAR_CREATE_LEVEL_REQUIREMENT;
+ SendPacket( &data );
+ return;
+ }
+
bool AllowTwoSideAccounts = !sWorld.IsPvPRealm() || sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || GetSecurity() > SEC_PLAYER;
uint32 skipCinematics = sWorld.getConfig(CONFIG_SKIP_CINEMATICS);
bool have_same_race = false;
- if(!AllowTwoSideAccounts || skipCinematics == 1)
+
+ // if 0 then allowed creating without any characters
+ bool have_req_level_for_heroic = (req_level_for_heroic==0);
+
+ if(!AllowTwoSideAccounts || skipCinematics == 1 || class_ == CLASS_DEATH_KNIGHT)
{
- QueryResult *result2 = CharacterDatabase.PQuery("SELECT DISTINCT race FROM characters WHERE account = '%u' %s", GetAccountId(),skipCinematics == 1 ? "" : "LIMIT 1");
+ QueryResult *result2 = CharacterDatabase.PQuery("SELECT guid,race,class FROM characters WHERE account = '%u' %s",
+ GetAccountId(), (skipCinematics == 1 || class_ == CLASS_DEATH_KNIGHT) ? "" : "LIMIT 1");
if(result2)
{
uint32 team_= Player::TeamForRace(race_);
Field* field = result2->Fetch();
- uint8 race = field[0].GetUInt32();
+ uint8 acc_race = field[1].GetUInt32();
+
+ if(GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT)
+ {
+ uint8 acc_class = field[2].GetUInt32();
+ if(acc_class == CLASS_DEATH_KNIGHT)
+ {
+ if(heroic_free_slots > 0)
+ --heroic_free_slots;
+
+ if(heroic_free_slots==0)
+ {
+ data << (uint8)CHAR_CREATE_UNIQUE_CLASS_LIMIT;
+ SendPacket( &data );
+ return;
+ }
+ }
+
+ if(!have_req_level_for_heroic)
+ {
+ uint32 acc_guid = field[0].GetUInt32();
+ uint32 acc_level = Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,acc_guid);
+ if(acc_level >= req_level_for_heroic)
+ have_req_level_for_heroic = true;
+ }
+ }
// need to check team only for first character
// TODO: what to if account already has characters of both races?
if (!AllowTwoSideAccounts)
{
- uint32 team=0;
- if(race > 0)
- team = Player::TeamForRace(race);
+ uint32 acc_team=0;
+ if(acc_race > 0)
+ acc_team = Player::TeamForRace(acc_race);
- if(team != team_)
+ if(acc_team != team_)
{
data << (uint8)CHAR_CREATE_PVP_TEAMS_VIOLATION;
SendPacket( &data );
@@ -342,20 +391,55 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data )
}
}
- if (skipCinematics == 1)
+ // search same race for cinematic or same class if need
+ // TODO: check if cinematic already shown? (already logged in?; cinematic field)
+ while ((skipCinematics == 1 && !have_same_race) || class_ == CLASS_DEATH_KNIGHT)
{
- // TODO: check if cinematic already shown? (already logged in?; cinematic field)
- while (race_ != race && result2->NextRow())
+ if(!result2->NextRow())
+ break;
+
+ field = result2->Fetch();
+ acc_race = field[1].GetUInt32();
+
+ if(!have_same_race)
+ have_same_race = race_ == acc_race;
+
+ if(GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT)
{
- field = result2->Fetch();
- race = field[0].GetUInt32();
+ uint8 acc_class = field[2].GetUInt32();
+ if(acc_class == CLASS_DEATH_KNIGHT)
+ {
+ if(heroic_free_slots > 0)
+ --heroic_free_slots;
+
+ if(heroic_free_slots==0)
+ {
+ data << (uint8)CHAR_CREATE_UNIQUE_CLASS_LIMIT;
+ SendPacket( &data );
+ return;
+ }
+ }
+
+ if(!have_req_level_for_heroic)
+ {
+ uint32 acc_guid = field[0].GetUInt32();
+ uint32 acc_level = Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,acc_guid);
+ if(acc_level >= req_level_for_heroic)
+ have_req_level_for_heroic = true;
+ }
}
- have_same_race = race_ == race;
}
delete result2;
}
}
+ if(GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT && !have_req_level_for_heroic)
+ {
+ data << (uint8)CHAR_CREATE_LEVEL_REQUIREMENT;
+ SendPacket( &data );
+ return;
+ }
+
// extract other data required for player creating
uint8 gender, skin, face, hairStyle, hairColor, facialHair, outfitId;
recv_data >> gender >> skin >> face;
@@ -514,9 +598,11 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
data << pCurrChar->GetOrientation();
SendPacket(&data);
- data.Initialize( SMSG_ACCOUNT_DATA_TIMES, 128 );
- for(int i = 0; i < 32; i++)
- data << uint32(0);
+ data.Initialize( SMSG_ACCOUNT_DATA_TIMES, 4+1+8*4 ); // changed in WotLK
+ data << uint32(time(NULL)); // unix time of something
+ data << uint8(1);
+ for(int i = 0; i < NUM_ACCOUNT_DATA_TYPES; i++)
+ data << uint32(GetAccountData(i)->Time); // also unix time
SendPacket(&data);
data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 2); // added in 2.2.0
@@ -619,17 +705,25 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
{
pCurrChar->setCinematic(1);
- ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace());
- if(rEntry)
+ if(ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(pCurrChar->getClass()))
{
- data.Initialize( SMSG_TRIGGER_CINEMATIC,4 );
- data << uint32(rEntry->startmovie);
- SendPacket( &data );
-
+ if(cEntry->CinematicSequence)
+ {
+ data.Initialize(SMSG_TRIGGER_CINEMATIC, 4);
+ data << uint32(cEntry->CinematicSequence);
+ SendPacket( &data );
+ }
+ else if(ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace()))
+ {
+ data.Initialize(SMSG_TRIGGER_CINEMATIC, 4);
+ data << uint32(rEntry->CinematicSequence);
+ SendPacket( &data );
+ }
+
// send new char string if not empty
if (!sWorld.GetNewCharString().empty())
chH.PSendSysMessage(sWorld.GetNewCharString().c_str());
- }
+ }
}
if (!pCurrChar->GetMap()->Add(pCurrChar))
@@ -672,22 +766,6 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
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->SetUInt32Value(UNIT_FIELD_AURA+41, 8326);
- //pCurrChar->SetUInt32Value(UNIT_FIELD_AURA+42, 20584);
- //pCurrChar->SetUInt32Value(UNIT_FIELD_AURAFLAGS+6, 238);
- //pCurrChar->SetUInt32Value(UNIT_FIELD_AURALEVELS+11, 514);
- //pCurrChar->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS+11, 65535);
- //pCurrChar->SetUInt32Value(UNIT_FIELD_DISPLAYID, 1825);
- //if (pCurrChar->getRace() == RACE_NIGHTELF)
- //{
- // pCurrChar->SetSpeed(MOVE_RUN, 1.5f*1.2f, true);
- // pCurrChar->SetSpeed(MOVE_SWIM, 1.5f*1.2f, true);
- //}
- //else
- //{
- // pCurrChar->SetSpeed(MOVE_RUN, 1.5f, true);
- // pCurrChar->SetSpeed(MOVE_SWIM, 1.5f, true);
- //}
pCurrChar->SetMovement(MOVE_WATER_WALK);
}
@@ -747,7 +825,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
// Set FFA PvP for non GM in non-rest mode
if(sWorld.IsFFAPvPRealm() && !pCurrChar->isGameMaster() && !pCurrChar->HasFlag(PLAYER_FLAGS,PLAYER_FLAGS_RESTING) )
- pCurrChar->SetFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP);
+ pCurrChar->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
if(pCurrChar->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP))
pCurrChar->SetContestedPvP();
@@ -917,11 +995,11 @@ void WorldSession::HandleToggleCloakOpcode( WorldPacket & /*recv_data*/ )
void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data)
{
+ CHECK_PACKET_SIZE(recv_data, 8+1);
+
uint64 guid;
std::string newname;
- CHECK_PACKET_SIZE(recv_data, 8+1);
-
recv_data >> guid;
recv_data >> newname;
@@ -929,15 +1007,15 @@ void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data)
if(!normalizePlayerName(newname))
{
WorldPacket data(SMSG_CHAR_RENAME, 1);
- data << (uint8)CHAR_NAME_NO_NAME;
+ data << uint8(CHAR_NAME_NO_NAME);
SendPacket( &data );
return;
}
- if(!ObjectMgr::IsValidName(newname,true))
+ if(!ObjectMgr::IsValidName(newname, true))
{
WorldPacket data(SMSG_CHAR_RENAME, 1);
- data << (uint8)CHAR_NAME_INVALID_CHARACTER;
+ data << uint8(CHAR_NAME_INVALID_CHARACTER);
SendPacket( &data );
return;
}
@@ -946,7 +1024,7 @@ void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data)
if(GetSecurity() == SEC_PLAYER && objmgr.IsReservedName(newname))
{
WorldPacket data(SMSG_CHAR_RENAME, 1);
- data << (uint8)CHAR_NAME_RESERVED;
+ data << uint8(CHAR_NAME_RESERVED);
SendPacket( &data );
return;
}
@@ -975,7 +1053,7 @@ void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult *result, uin
if (!result)
{
WorldPacket data(SMSG_CHAR_RENAME, 1);
- data << (uint8)CHAR_CREATE_ERROR;
+ data << uint8(CHAR_CREATE_ERROR);
session->SendPacket( &data );
return;
}
@@ -989,11 +1067,11 @@ void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult *result, uin
CharacterDatabase.PExecute("UPDATE characters set name = '%s', at_login = at_login & ~ %u WHERE guid ='%u'", newname.c_str(), uint32(AT_LOGIN_RENAME), guidLow);
CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid ='%u'", guidLow);
- sLog.outChar("Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s",session->GetAccountId(), session->GetRemoteAddress().c_str(), oldname.c_str(), guidLow, newname.c_str());
+ sLog.outChar("Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s", session->GetAccountId(), session->GetRemoteAddress().c_str(), oldname.c_str(), guidLow, newname.c_str());
- WorldPacket data(SMSG_CHAR_RENAME,1+8+(newname.size()+1));
- data << (uint8)RESPONSE_SUCCESS;
- data << guid;
+ WorldPacket data(SMSG_CHAR_RENAME, 1+8+(newname.size()+1));
+ data << uint8(RESPONSE_SUCCESS);
+ data << uint64(guid);
data << newname;
session->SendPacket(&data);
}
@@ -1087,3 +1165,166 @@ void WorldSession::HandleDeclinedPlayerNameOpcode(WorldPacket& recv_data)
data << uint64(guid);
SendPacket(&data);
}
+
+void WorldSession::HandleAlterAppearance( WorldPacket & recv_data )
+{
+ sLog.outDebug("CMSG_ALTER_APPEARANCE");
+
+ CHECK_PACKET_SIZE(recv_data, 4+4+4);
+
+ uint32 Hair, Color, FacialHair;
+ recv_data >> Hair >> Color >> FacialHair;
+
+ BarberShopStyleEntry const* bs_hair = sBarberShopStyleStore.LookupEntry(Hair);
+
+ if(!bs_hair || bs_hair->type != 0 || bs_hair->race != _player->getRace() || bs_hair->gender != _player->getGender())
+ return;
+
+ BarberShopStyleEntry const* bs_facialHair = sBarberShopStyleStore.LookupEntry(FacialHair);
+
+ if(!bs_facialHair || bs_facialHair->type != 2 || bs_facialHair->race != _player->getRace() || bs_facialHair->gender != _player->getGender())
+ return;
+
+ uint32 Cost = _player->GetBarberShopCost(bs_hair->hair_id, Color, bs_facialHair->hair_id);
+
+ // 0 - ok
+ // 1,3 - not enough money
+ // 2 - you have to seat on barber chair
+ if(_player->GetMoney() < Cost)
+ {
+ WorldPacket data(SMSG_BARBER_SHOP_RESULT, 4);
+ data << uint32(1); // no money
+ SendPacket(&data);
+ return;
+ }
+ else
+ {
+ WorldPacket data(SMSG_BARBER_SHOP_RESULT, 4);
+ data << uint32(0); // ok
+ SendPacket(&data);
+ }
+
+ _player->SetMoney(_player->GetMoney() - Cost); // it isn't free
+
+ _player->SetByteValue(PLAYER_BYTES, 2, uint8(bs_hair->hair_id));
+ _player->SetByteValue(PLAYER_BYTES, 3, uint8(Color));
+ _player->SetByteValue(PLAYER_BYTES_2, 0, uint8(bs_facialHair->hair_id));
+
+ _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP, 1);
+
+ _player->SetStandState(0); // stand up
+}
+
+void WorldSession::HandleRemoveGlyph( WorldPacket & recv_data )
+{
+ CHECK_PACKET_SIZE(recv_data, 4);
+
+ uint32 slot;
+ recv_data >> slot;
+
+ if(slot > MAX_GLYPH_SLOT_INDEX)
+ {
+ sLog.outDebug("Client sent wrong glyph slot number in opcode CMSG_REMOVE_GLYPH %u", slot);
+ return;
+ }
+
+ if(uint32 glyph = _player->GetGlyph(slot))
+ {
+ if(GlyphPropertiesEntry const *gp = sGlyphPropertiesStore.LookupEntry(glyph))
+ {
+ _player->RemoveAurasDueToSpell(gp->SpellId);
+ _player->SetGlyph(slot, 0);
+ }
+ }
+}
+
+void WorldSession::HandleCharCustomize(WorldPacket& recv_data)
+{
+ CHECK_PACKET_SIZE(recv_data, 8+1);
+
+ uint64 guid;
+ std::string newname;
+
+ recv_data >> guid;
+ recv_data >> newname;
+
+ CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+1+1+1+1+1+1);
+
+ uint8 gender, skin, face, hairStyle, hairColor, facialHair;
+ recv_data >> gender >> skin >> face >> hairStyle >> hairColor >> facialHair;
+
+ QueryResult *result = CharacterDatabase.PQuery("SELECT at_login FROM characters WHERE guid ='%u'", GUID_LOPART(guid));
+ if (!result)
+ {
+ WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1);
+ data << uint8(CHAR_CREATE_ERROR);
+ SendPacket( &data );
+ return;
+ }
+
+ Field *fields = result->Fetch();
+ uint32 at_loginFlags = fields[0].GetUInt32();
+ delete result;
+
+ if (!(at_loginFlags & AT_LOGIN_CUSTOMIZE))
+ {
+ WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1);
+ data << uint8(CHAR_CREATE_ERROR);
+ SendPacket( &data );
+ return;
+ }
+
+ // prevent character rename to invalid name
+ if(!normalizePlayerName(newname))
+ {
+ WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1);
+ data << uint8(CHAR_NAME_NO_NAME);
+ SendPacket( &data );
+ return;
+ }
+
+ if(!ObjectMgr::IsValidName(newname,true))
+ {
+ WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1);
+ data << uint8(CHAR_NAME_INVALID_CHARACTER);
+ SendPacket( &data );
+ return;
+ }
+
+ // check name limitations
+ if(GetSecurity() == SEC_PLAYER && objmgr.IsReservedName(newname))
+ {
+ WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1);
+ data << uint8(CHAR_NAME_RESERVED);
+ SendPacket( &data );
+ return;
+ }
+
+ if(objmgr.GetPlayerGUIDByName(newname)) // character with this name already exist
+ {
+ WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1);
+ data << uint8(CHAR_CREATE_NAME_IN_USE);
+ SendPacket( &data );
+ return;
+ }
+
+ CharacterDatabase.escape_string(newname);
+ Player::Customize(guid, gender, skin, face, hairStyle, hairColor, facialHair);
+ CharacterDatabase.PExecute("UPDATE characters set name = '%s', at_login = at_login & ~ %u WHERE guid ='%u'", newname.c_str(), uint32(AT_LOGIN_CUSTOMIZE), GUID_LOPART(guid));
+ CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid ='%u'", GUID_LOPART(guid));
+
+ std::string IP_str = GetRemoteAddress();
+ sLog.outChar("Account: %d (IP: %s), Character guid: %u Customized to: %s", GetAccountId(), IP_str.c_str(), GUID_LOPART(guid), newname.c_str());
+
+ WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1+8+(newname.size()+1)+6);
+ data << uint8(RESPONSE_SUCCESS);
+ data << uint64(guid);
+ data << newname;
+ data << uint8(gender);
+ data << uint8(skin);
+ data << uint8(face);
+ data << uint8(hairStyle);
+ data << uint8(hairColor);
+ data << uint8(facialHair);
+ SendPacket(&data);
+}
diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp
index fa2bc71152c..f64dd86545a 100644
--- a/src/game/Chat.cpp
+++ b/src/game/Chat.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -33,8 +33,26 @@
#include "MapManager.h"
#include "GridNotifiersImpl.h"
#include "CellImpl.h"
+#include "AccountMgr.h"
#include "TicketMgr.h"
+// Supported shift-links (client generated and server side)
+// |color|Harea:area_id|h[name]|h|r
+// |color|Hcreature:creature_guid|h[name]|h|r
+// |color|Hcreature_entry:creature_id|h[name]|h|r
+// |color|Hgameevent:id|h[name]|h|r
+// |color|Hgameobject:go_guid|h[name]|h|r
+// |color|Hgameobject_entry:go_id|h[name]|h|r
+// |color|Hitem:item_id:perm_ench_id:0:0|h[name]|h|r
+// |color|Hitemset:itemset_id|h[name]|h|r
+// |color|Hplayer:name|h[name]|h|r - client, in some messages, at click copy only name instead link
+// |color|Hquest:quest_id|h[name]|h|r
+// |color|Hskill:skill_id|h[name]|h|r
+// |color|Hspell:spell_id|h[name]|h|r - client, spellbook spell icon shift-click
+// |color|Htalent:talent_id,rank|h[name]|h|r - client, talent icon shift-click
+// |color|Htele:id|h[name]|h|r
+// |color|Htrade:spell_id,cur_value,max_value,unk3int,unk3str|h[name]|h|r - client, spellbook profession icon shift-click
+
bool ChatHandler::load_command_table = true;
ChatCommand * ChatHandler::getCommandTable()
@@ -112,6 +130,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "hp", SEC_MODERATOR, false, &ChatHandler::HandleModifyHPCommand, "", NULL },
{ "mana", SEC_MODERATOR, false, &ChatHandler::HandleModifyManaCommand, "", NULL },
{ "rage", SEC_MODERATOR, false, &ChatHandler::HandleModifyRageCommand, "", NULL },
+ { "runicpower", SEC_MODERATOR, false, &ChatHandler::HandleModifyRunicPowerCommand, "", NULL },
{ "energy", SEC_MODERATOR, false, &ChatHandler::HandleModifyEnergyCommand, "", NULL },
{ "money", SEC_MODERATOR, false, &ChatHandler::HandleModifyMoneyCommand, "", NULL },
{ "speed", SEC_MODERATOR, false, &ChatHandler::HandleModifySpeedCommand, "", NULL },
@@ -132,6 +151,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "drunk", SEC_MODERATOR, false, &ChatHandler::HandleDrunkCommand, "", NULL },
{ "standstate", SEC_GAMEMASTER, false, &ChatHandler::HandleStandStateCommand, "", NULL },
{ "morph", SEC_GAMEMASTER, false, &ChatHandler::HandleMorphCommand, "", NULL },
+ { "phase", SEC_GAMEMASTER, false, &ChatHandler::HandleModifyPhaseCommand, "", NULL },
{ "gender", SEC_ADMINISTRATOR, false, &ChatHandler::HandleModifyGenderCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
@@ -192,6 +212,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "sellerr", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSellErrorCommand, "", NULL },
{ "buyerr", SEC_ADMINISTRATOR, false, &ChatHandler::HandleBuyErrorCommand, "", NULL },
{ "sendopcode", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSendOpcodeCommand, "", NULL },
+ { "spawnvehicle", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSpawnVehicle, "", NULL },
{ "uws", SEC_ADMINISTRATOR, false, &ChatHandler::HandleUpdateWorldStateCommand, "", NULL },
{ "ps", SEC_ADMINISTRATOR, false, &ChatHandler::HandlePlaySound2Command, "", NULL },
{ "scn", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSendChannelNotifyCommand, "", NULL },
@@ -205,6 +226,8 @@ ChatCommand * ChatHandler::getCommandTable()
{ "anim", SEC_GAMEMASTER, false, &ChatHandler::HandleAnimCommand, "", NULL },
{ "lootrecipient", SEC_GAMEMASTER, false, &ChatHandler::HandleGetLootRecipient, "", NULL },
{ "arena", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugArenaCommand, "", NULL },
+ { "bg", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugBattlegroundCommand, "", NULL },
+ { "sendlargepacket",SEC_ADMINISTRATOR, false, &ChatHandler::HandleSendLargePacketCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
@@ -265,6 +288,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "item_enchantment_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadItemEnchantementsCommand, "", NULL },
{ "item_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesItemCommand, "", NULL },
{ "trinity_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadTrinityStringCommand, "", NULL },
+ { "milling_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesMillingCommand, "", NULL },
{ "npc_gossip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcGossipCommand, "", NULL },
{ "npc_option", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcOptionCommand, "", NULL },
{ "npc_trainer", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcTrainerCommand, "", NULL },
@@ -286,8 +310,10 @@ ChatCommand * ChatHandler::getCommandTable()
{ "spell_required", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellRequiredCommand, "", NULL },
{ "spell_elixir", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellElixirCommand, "", NULL },
{ "spell_learn_spell", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellLearnSpellCommand, "", NULL },
+ { "spell_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesSpellCommand, "", NULL },
{ "spell_pet_auras", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellPetAurasCommand, "", NULL },
{ "spell_proc_event", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellProcEventCommand, "", NULL },
+ { "spell_bonus_data", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellBonusesCommand, "", NULL },
{ "spell_script_target", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellScriptTargetCommand, "", NULL },
{ "spell_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellScriptsCommand, "", NULL },
{ "spell_target_position", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellTargetPositionCommand, "", NULL },
@@ -302,7 +328,6 @@ ChatCommand * ChatHandler::getCommandTable()
{ "waypoint_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadWpScriptsCommand, "", NULL },
{ "gm_tickets", SEC_ADMINISTRATOR, true, &ChatHandler::HandleGMTicketReloadCommand, "", NULL },
- { "", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
@@ -369,6 +394,7 @@ ChatCommand * ChatHandler::getCommandTable()
static ChatCommand resetCommandTable[] =
{
+ { "achievements", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetAchievementsCommand, "", NULL },
{ "honor", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetHonorCommand, "", NULL },
{ "level", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetLevelCommand, "", NULL },
{ "spells", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetSpellsCommand, "", NULL },
@@ -435,6 +461,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "info", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcInfoCommand, "", NULL },
{ "playemote", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcPlayEmoteCommand, "", NULL },
{ "follow", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcFollowCommand, "", NULL },
+ { "setphase", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSetPhaseCommand, "", NULL },
{ "unfollow", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcUnFollowCommand, "", NULL },
{ "whisper", SEC_MODERATOR, false, &ChatHandler::HandleNpcWhisperCommand, "", NULL },
{ "yell", SEC_MODERATOR, false, &ChatHandler::HandleNpcYellCommand, "", NULL },
@@ -468,12 +495,13 @@ ChatCommand * ChatHandler::getCommandTable()
{
{ "add", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectCommand, "", NULL },
{ "delete", SEC_GAMEMASTER, false, &ChatHandler::HandleDelObjectCommand, "", NULL },
- { "target", SEC_GAMEMASTER, false, &ChatHandler::HandleTargetObjectCommand, "", NULL },
- { "turn", SEC_GAMEMASTER, false, &ChatHandler::HandleTurnObjectCommand, "", NULL },
{ "move", SEC_GAMEMASTER, false, &ChatHandler::HandleMoveObjectCommand, "", NULL },
{ "near", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNearObjectCommand, "", NULL },
{ "activate", SEC_GAMEMASTER, false, &ChatHandler::HandleActivateObjectCommand, "", NULL },
{ "addtemp", SEC_GAMEMASTER, false, &ChatHandler::HandleTempGameObjectCommand, "", NULL },
+ { "setphase", SEC_GAMEMASTER, false, &ChatHandler::HandleGOPhaseCommand, "", NULL },
+ { "target", SEC_GAMEMASTER, false, &ChatHandler::HandleTargetObjectCommand, "", NULL },
+ { "turn", SEC_GAMEMASTER, false, &ChatHandler::HandleTurnObjectCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
@@ -609,6 +637,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "sendmail", SEC_MODERATOR, true, &ChatHandler::HandleSendMailCommand, "", NULL },
{ "sendmoney", SEC_ADMINISTRATOR, true, &ChatHandler::HandleSendMoneyCommand, "", NULL },
{ "rename", SEC_GAMEMASTER, true, &ChatHandler::HandleRenameCommand, "", NULL },
+ { "customize", SEC_GAMEMASTER, true, &ChatHandler::HandleCustomizeCommand, "", NULL },
{ "loadscripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLoadScriptsCommand, "", NULL },
{ "mute", SEC_GAMEMASTER, true, &ChatHandler::HandleMuteCommand, "", NULL },
{ "unmute", SEC_GAMEMASTER, true, &ChatHandler::HandleUnmuteCommand, "", NULL },
@@ -686,6 +715,55 @@ bool ChatHandler::isAvailable(ChatCommand const& cmd) const
return m_session->GetSecurity() >= cmd.SecurityLevel;
}
+bool ChatHandler::HasLowerSecurity(Player* target, uint64 guid, bool strong)
+{
+ WorldSession* target_session = NULL;
+ uint32 target_account = 0;
+
+ if (target)
+ target_session = target->GetSession();
+ else if (guid)
+ target_account = objmgr.GetPlayerAccountIdByGUID(guid);
+
+ if(!target_session && !target_account)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return true;
+ }
+
+ return HasLowerSecurityAccount(target_session,target_account,strong);
+}
+
+bool ChatHandler::HasLowerSecurityAccount(WorldSession* target, uint32 target_account, bool strong)
+{
+ uint32 target_sec;
+
+ // allow everything from console and RA console
+ if (!m_session)
+ return false;
+
+ // ignore only for non-players for non strong checks (when allow apply command at least to same sec level)
+ if (m_session->GetSecurity() > SEC_PLAYER && !strong && !sWorld.getConfig(CONFIG_GM_LOWER_SECURITY))
+ return false;
+
+ if (target)
+ target_sec = target->GetSecurity();
+ else if (target_account)
+ target_sec = accmgr.GetSecurity(target_account);
+ else
+ return true; // caller must report error for (target==NULL && target_account==0)
+
+ if (m_session->GetSecurity() < target_sec || strong && m_session->GetSecurity() <= target_sec)
+ {
+ SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
+ SetSentErrorMessage(true);
+ return true;
+ }
+
+ return false;
+}
+
bool ChatHandler::hasStringAbbr(const char* name, const char* part)
{
// non "" command
@@ -771,9 +849,9 @@ void ChatHandler::PSendSysMessage(int32 entry, ...)
{
const char *format = GetTrinityString(entry);
va_list ap;
- char str [1024];
+ char str [2048];
va_start(ap, entry);
- vsnprintf(str,1024,format, ap );
+ vsnprintf(str,2048,format, ap );
va_end(ap);
SendSysMessage(str);
}
@@ -781,9 +859,9 @@ void ChatHandler::PSendSysMessage(int32 entry, ...)
void ChatHandler::PSendSysMessage(const char *format, ...)
{
va_list ap;
- char str [1024];
+ char str [2048];
va_start(ap, format);
- vsnprintf(str,1024,format, ap );
+ vsnprintf(str,2048,format, ap );
va_end(ap);
SendSysMessage(str);
}
@@ -1099,7 +1177,7 @@ Creature* ChatHandler::getSelectedCreature()
if(!m_session)
return NULL;
- return ObjectAccessor::GetCreatureOrPet(*m_session->GetPlayer(),m_session->GetPlayer()->GetSelection());
+ return ObjectAccessor::GetCreatureOrPetOrVehicle(*m_session->GetPlayer(),m_session->GetPlayer()->GetSelection());
}
char* ChatHandler::extractKeyFromLink(char* text, char const* linkType, char** something1)
@@ -1170,12 +1248,23 @@ char* ChatHandler::extractKeyFromLink(char* text, char const* const* linkTypes,
// [name] Shift-click form |color|linkType:key|h[name]|h|r
// or
// [name] Shift-click form |color|linkType:key:something1:...:somethingN|h[name]|h|r
+ // or
+ // [name] Shift-click form |linkType:key|h[name]|h|r
- char* check = strtok(text, "|"); // skip color
- if(!check)
- return NULL; // end of data
+ char* tail;
- char* cLinkType = strtok(NULL, ":"); // linktype
+ if(text[1]=='c')
+ {
+ char* check = strtok(text, "|"); // skip color
+ if(!check)
+ return NULL; // end of data
+
+ tail = strtok(NULL, ""); // tail
+ }
+ else
+ tail = text+1; // skip first |
+
+ char* cLinkType = strtok(tail, ":"); // linktype
if(!cLinkType)
return NULL; // end of data
@@ -1251,8 +1340,8 @@ GameObject* ChatHandler::GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
- Trinity::GameObjectWithDbGUIDCheck go_check(*pl,lowguid);
- Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck> checker(obj,go_check);
+ MaNGOS::GameObjectWithDbGUIDCheck go_check(*pl,lowguid);
+ MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck> checker(pl,obj,go_check);
TypeContainerVisitor<Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
@@ -1262,9 +1351,18 @@ GameObject* ChatHandler::GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid
return obj;
}
-static char const* const spellTalentKeys[] = {
- "Hspell",
- "Htalent",
+enum SpellLinkType
+{
+ SPELL_LINK_SPELL = 0,
+ SPELL_LINK_TALENT = 1,
+ SPELL_LINK_TRADE = 2
+};
+
+static char const* const spellKeys[] =
+{
+ "Hspell", // normal spell
+ "Htalent", // talent spell
+ "Htrade", // profession/skill spell
0
};
@@ -1272,31 +1370,41 @@ uint32 ChatHandler::extractSpellIdFromLink(char* text)
{
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
// number or [name] Shift-click form |color|Htalent:talent_id,rank|h[name]|h|r
+ // number or [name] Shift-click form |color|Htrade:spell_id,skill_id,max_value,cur_value|h[name]|h|r
int type = 0;
- char* rankS = NULL;
- char* idS = extractKeyFromLink(text,spellTalentKeys,&type,&rankS);
+ char* param1_str = NULL;
+ char* idS = extractKeyFromLink(text,spellKeys,&type,&param1_str);
if(!idS)
return 0;
uint32 id = (uint32)atol(idS);
- // spell
- if(type==0)
- return id;
+ switch(type)
+ {
+ case SPELL_LINK_SPELL:
+ return id;
+ case SPELL_LINK_TALENT:
+ {
+ // talent
+ TalentEntry const* talentEntry = sTalentStore.LookupEntry(id);
+ if(!talentEntry)
+ return 0;
- // talent
- TalentEntry const* talentEntry = sTalentStore.LookupEntry(id);
- if(!talentEntry)
- return 0;
+ int32 rank = param1_str ? (uint32)atol(param1_str) : 0;
+ if(rank >= 5)
+ return 0;
- int32 rank = rankS ? (uint32)atol(rankS) : 0;
- if(rank >= 5)
- return 0;
+ if(rank < 0)
+ rank = 0;
- if(rank < 0)
- rank = 0;
+ return talentEntry->RankID[rank];
+ }
+ case SPELL_LINK_TRADE:
+ return id;
+ }
- return talentEntry->RankID[rank];
+ // unknown type?
+ return 0;
}
GameTele const* ChatHandler::extractGameTeleFromLink(char* text)
@@ -1314,9 +1422,84 @@ GameTele const* ChatHandler::extractGameTeleFromLink(char* text)
return objmgr.GetGameTele(cId);
}
-const char *ChatHandler::GetName() const
+enum GuidLinkType
+{
+ SPELL_LINK_PLAYER = 0, // must be first for selection in not link case
+ SPELL_LINK_CREATURE = 1,
+ SPELL_LINK_GAMEOBJECT = 2
+};
+
+static char const* const guidKeys[] =
+{
+ "Hplayer",
+ "Hcreature",
+ "Hgameobject",
+ 0
+};
+
+uint64 ChatHandler::extractGuidFromLink(char* text)
{
- return m_session->GetPlayer()->GetName();
+ int type = 0;
+
+ // |color|Hcreature:creature_guid|h[name]|h|r
+ // |color|Hgameobject:go_guid|h[name]|h|r
+ // |color|Hplayer:name|h[name]|h|r
+ char* idS = extractKeyFromLink(text,guidKeys,&type);
+ if(!idS)
+ return 0;
+
+ switch(type)
+ {
+ case SPELL_LINK_PLAYER:
+ {
+ std::string name = idS;
+ if(!normalizePlayerName(name))
+ return 0;
+
+ if(Player* player = objmgr.GetPlayer(name.c_str()))
+ return player->GetGUID();
+
+ if(uint64 guid = objmgr.GetPlayerGUIDByName(name))
+ return guid;
+
+ return 0;
+ }
+ case SPELL_LINK_CREATURE:
+ {
+ uint32 lowguid = (uint32)atol(idS);
+
+ if(CreatureData const* data = objmgr.GetCreatureData(lowguid) )
+ return MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT);
+ else
+ return 0;
+ }
+ case SPELL_LINK_GAMEOBJECT:
+ {
+ uint32 lowguid = (uint32)atol(idS);
+
+ if(GameObjectData const* data = objmgr.GetGOData(lowguid) )
+ return MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_GAMEOBJECT);
+ else
+ return 0;
+ }
+ }
+
+ // unknown type?
+ return 0;
+}
+
+std::string ChatHandler::extractPlayerNameFromLink(char* text)
+{
+ // |color|Hplayer:name|h[name]|h|r
+ char* name_str = extractKeyFromLink(text,"Hplayer");
+ if(!name_str)
+ return "";
+
+ std::string name = name_str;
+ if(!normalizePlayerName(name))
+ return "";
+
+ return name;
}
bool ChatHandler::needReportToTarget(Player* chr) const
@@ -1342,7 +1525,7 @@ void CliHandler::SendSysMessage(const char *str)
m_print("\r\n");
}
-const char *CliHandler::GetName() const
+std::string CliHandler::GetNameLink() const
{
return GetTrinityString(LANG_CONSOLE_COMMAND);
}
diff --git a/src/game/Chat.h b/src/game/Chat.h
index 8329aab4d67..a24de275f78 100644
--- a/src/game/Chat.h
+++ b/src/game/Chat.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -72,8 +72,6 @@ class ChatHandler
int ParseCommands(const char* text);
- virtual char const* GetName() const;
-
protected:
explicit ChatHandler() : m_session(NULL) {} // for CLI subclass
@@ -81,6 +79,8 @@ class ChatHandler
virtual bool isAvailable(ChatCommand const& cmd) const;
virtual bool needReportToTarget(Player* chr) const;
+ bool HasLowerSecurity(Player* target, uint64 guid, bool strong = false);
+ bool HasLowerSecurityAccount(WorldSession* target, uint32 account, bool strong = false);
void SendGlobalSysMessage(const char *str);
void SendGlobalGMSysMessage(const char *str);
@@ -166,6 +166,7 @@ class ChatHandler
bool HandleModifyHPCommand(const char* args);
bool HandleModifyManaCommand(const char* args);
bool HandleModifyRageCommand(const char* args);
+ bool HandleModifyRunicPowerCommand(const char* args);
bool HandleModifyEnergyCommand(const char* args);
bool HandleModifyMoneyCommand(const char* args);
bool HandleModifyASpeedCommand(const char* args);
@@ -182,6 +183,7 @@ class ChatHandler
bool HandleModifyHonorCommand (const char* args);
bool HandleModifyRepCommand(const char* args);
bool HandleModifyArenaCommand(const char* args);
+ bool HandleModifyPhaseCommand(const char* args);
bool HandleModifyGenderCommand(const char* args);
bool HandleNpcAddCommand(const char* args);
@@ -197,6 +199,7 @@ class ChatHandler
bool HandleNpcSayCommand(const char* args);
bool HandleNpcSetModelCommand(const char* args);
bool HandleNpcSetMoveTypeCommand(const char* args);
+ bool HandleNpcSetPhaseCommand(const char* args);
bool HandleNpcSpawnDistCommand(const char* args);
bool HandleNpcSpawnTimeCommand(const char* args);
bool HandleNpcTameCommand(const char* args);
@@ -206,7 +209,6 @@ class ChatHandler
bool HandleNpcYellCommand(const char* args);
bool HandleNpcAddFormationCommand(const char* args);
- bool HandleReloadCommand(const char* args);
bool HandleReloadAllCommand(const char* args);
bool HandleReloadAllAreaCommand(const char* args);
bool HandleReloadAllItemCommand(const char* args);
@@ -237,11 +239,13 @@ class ChatHandler
bool HandleReloadLootTemplatesFishingCommand(const char* args);
bool HandleReloadLootTemplatesGameobjectCommand(const char* args);
bool HandleReloadLootTemplatesItemCommand(const char* args);
+ bool HandleReloadLootTemplatesMillingCommand(const char* args);
bool HandleReloadLootTemplatesPickpocketingCommand(const char* args);
bool HandleReloadLootTemplatesProspectingCommand(const char* args);
bool HandleReloadLootTemplatesReferenceCommand(const char* args);
bool HandleReloadLootTemplatesQuestMailCommand(const char* args);
bool HandleReloadLootTemplatesSkinningCommand(const char* args);
+ bool HandleReloadLootTemplatesSpellCommand(const char* args);
bool HandleReloadTrinityStringCommand(const char* args);
bool HandleReloadNpcGossipCommand(const char* args);
bool HandleReloadNpcOptionCommand(const char* args);
@@ -260,6 +264,7 @@ class ChatHandler
bool HandleReloadSpellElixirCommand(const char* args);
bool HandleReloadSpellLearnSpellCommand(const char* args);
bool HandleReloadSpellProcEventCommand(const char* args);
+ bool HandleReloadSpellBonusesCommand(const char* args);
bool HandleReloadSpellScriptTargetCommand(const char* args);
bool HandleReloadSpellScriptsCommand(const char* args);
bool HandleReloadSpellTargetPositionCommand(const char* args);
@@ -321,6 +326,7 @@ class ChatHandler
bool HandleTargetObjectCommand(const char* args);
bool HandleDelObjectCommand(const char* args);
bool HandleMoveObjectCommand(const char* args);
+ bool HandleGOPhaseCommand(const char* args);
bool HandleTurnObjectCommand(const char* args);
bool HandleObjectStateCommand(const char* args);
bool HandlePInfoCommand(const char* args);
@@ -401,6 +407,7 @@ class ChatHandler
bool HandleDelTeleCommand(const char * args);
bool HandleListAurasCommand(const char * args);
+ bool HandleResetAchievementsCommand(const char * args);
bool HandleResetHonorCommand(const char * args);
bool HandleResetLevelCommand(const char * args);
bool HandleResetSpellsCommand(const char * args);
@@ -452,6 +459,7 @@ class ChatHandler
bool HandleSendChannelNotifyCommand(const char* args);
bool HandleSendChatMsgCommand(const char* args);
bool HandleRenameCommand(const char * args);
+ bool HandleCustomizeCommand(const char * args);
bool HandleLoadPDumpCommand(const char *args);
bool HandleWritePDumpCommand(const char *args);
bool HandleCastCommand(const char *args);
@@ -488,15 +496,26 @@ class ChatHandler
bool HandleUnPossessCommand(const char* args);
bool HandleBindSightCommand(const char* args);
bool HandleUnbindSightCommand(const char* args);
+ bool HandleDebugBattlegroundCommand(const char * args);
+ bool HandleSpawnVehicle(const char * args);
+ bool HandleSendLargePacketCommand(const char * args);
Player* getSelectedPlayer();
Creature* getSelectedCreature();
Unit* getSelectedUnit();
+
char* extractKeyFromLink(char* text, char const* linkType, char** something1 = NULL);
char* extractKeyFromLink(char* text, char const* const* linkTypes, int* found_idx, char** something1 = NULL);
+
uint32 extractSpellIdFromLink(char* text);
+ uint64 extractGuidFromLink(char* text);
GameTele const* extractGameTeleFromLink(char* text);
bool GetPlayerGroupAndGUIDByName(const char* cname, Player* &plr, Group* &group, uint64 &guid, bool offline = false);
+ std::string extractPlayerNameFromLink(char* text);
+
+ std::string playerLink(std::string const& name) const { return m_session ? "|cffffffff|Hplayer:"+name+"|h["+name+"]|h|r" : name; }
+ virtual std::string GetNameLink() const { return GetNameLink(m_session->GetPlayer()); }
+ std::string GetNameLink(Player* chr) const { return playerLink(chr->GetName()); }
GameObject* GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid,uint32 entry);
@@ -527,7 +546,7 @@ class CliHandler : public ChatHandler
const char *GetTrinityString(int32 entry) const;
bool isAvailable(ChatCommand const& cmd) const;
void SendSysMessage(const char *str);
- char const* GetName() const;
+ std::string GetNameLink() const;
bool needReportToTarget(Player* chr) const;
private:
diff --git a/src/game/ChatHandler.cpp b/src/game/ChatHandler.cpp
index 7b5b552e74e..8a79dc42397 100644
--- a/src/game/ChatHandler.cpp
+++ b/src/game/ChatHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -192,7 +192,7 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
Player *player = objmgr.GetPlayer(to.c_str());
uint32 tSecurity = GetSecurity();
- uint32 pSecurity = player ? player->GetSession()->GetSecurity() : 0;
+ uint32 pSecurity = player ? player->GetSession()->GetSecurity() : SEC_PLAYER;
if(!player || tSecurity == SEC_PLAYER && pSecurity > SEC_PLAYER && !player->isAcceptWhispers())
{
WorldPacket data(SMSG_CHAT_PLAYER_NOT_FOUND, (to.size()+1));
diff --git a/src/game/CombatHandler.cpp b/src/game/CombatHandler.cpp
index 0ab8814fa29..1458af5fcef 100644
--- a/src/game/CombatHandler.cpp
+++ b/src/game/CombatHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/ConfusedMovementGenerator.cpp b/src/game/ConfusedMovementGenerator.cpp
index ad8bab6e369..483c4979194 100644
--- a/src/game/ConfusedMovementGenerator.cpp
+++ b/src/game/ConfusedMovementGenerator.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/ConfusedMovementGenerator.h b/src/game/ConfusedMovementGenerator.h
index 8847460c504..2ad5990214f 100644
--- a/src/game/ConfusedMovementGenerator.h
+++ b/src/game/ConfusedMovementGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/Corpse.cpp b/src/game/Corpse.cpp
index 989ccd61151..75c89ba7287 100644
--- a/src/game/Corpse.cpp
+++ b/src/game/Corpse.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -36,7 +36,7 @@ Corpse::Corpse(CorpseType type) : WorldObject()
m_objectType |= TYPEMASK_CORPSE;
m_objectTypeId = TYPEID_CORPSE;
// 2.3.2 - 0x58
- m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION);
+ m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION);
m_valuesCount = CORPSE_END;
@@ -71,26 +71,26 @@ bool Corpse::Create( uint32 guidlow )
return true;
}
-bool Corpse::Create( uint32 guidlow, Player *owner, uint32 mapid, float x, float y, float z, float ang )
+bool Corpse::Create( uint32 guidlow, Player *owner)
{
SetInstanceId(owner->GetInstanceId());
- WorldObject::_Create(guidlow, HIGHGUID_CORPSE, mapid);
+ WorldObject::_Create(guidlow, HIGHGUID_CORPSE, owner->GetMapId(), owner->GetPhaseMask());
- Relocate(x,y,z,ang);
+ Relocate(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ(), owner->GetOrientation());
if(!IsPositionValid())
{
sLog.outError("ERROR: Corpse (guidlow %d, owner %s) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
- guidlow,owner->GetName(),x,y);
+ guidlow,owner->GetName(),owner->GetPositionX(), owner->GetPositionY());
return false;
}
SetFloatValue( OBJECT_FIELD_SCALE_X, 1 );
- SetFloatValue( CORPSE_FIELD_POS_X, x );
- SetFloatValue( CORPSE_FIELD_POS_Y, y );
- SetFloatValue( CORPSE_FIELD_POS_Z, z );
- SetFloatValue( CORPSE_FIELD_FACING, ang );
+ SetFloatValue( CORPSE_FIELD_POS_X, GetPositionX() );
+ SetFloatValue( CORPSE_FIELD_POS_Y, GetPositionY() );
+ SetFloatValue( CORPSE_FIELD_POS_Z, GetPositionZ() );
+ SetFloatValue( CORPSE_FIELD_FACING, GetOrientation() );
SetUInt64Value( CORPSE_FIELD_OWNER, owner->GetGUID() );
m_grid = Trinity::ComputeGridPair(GetPositionX(), GetPositionY());
@@ -100,17 +100,18 @@ bool Corpse::Create( uint32 guidlow, Player *owner, uint32 mapid, float x, float
void Corpse::SaveToDB()
{
- // prevent DB data inconsistance problems and duplicates
+ // prevent DB data inconsistence problems and duplicates
CharacterDatabase.BeginTransaction();
DeleteFromDB();
std::ostringstream ss;
- ss << "INSERT INTO corpse (guid,player,position_x,position_y,position_z,orientation,zone,map,data,time,corpse_type,instance) VALUES ("
+ ss << "INSERT INTO corpse (guid,player,position_x,position_y,position_z,orientation,zone,map,data,time,corpse_type,instance,phaseMask) VALUES ("
<< GetGUIDLow() << ", " << GUID_LOPART(GetOwnerGUID()) << ", " << GetPositionX() << ", " << GetPositionY() << ", " << GetPositionZ() << ", "
<< GetOrientation() << ", " << GetZoneId() << ", " << GetMapId() << ", '";
for(uint16 i = 0; i < m_valuesCount; i++ )
ss << GetUInt32Value(i) << " ";
- ss << "'," << uint64(m_time) <<", " << uint32(GetType()) << ", " << int(GetInstanceId()) << ")";
+ ss << "'," << uint64(m_time) <<", " << uint32(GetType())
+ << ", " << int(GetInstanceId()) << ", " << int(GetPhaseMask()) << ")";
CharacterDatabase.Execute( ss.str().c_str() );
CharacterDatabase.CommitTransaction();
}
@@ -143,8 +144,8 @@ bool Corpse::LoadFromDB(uint32 guid, QueryResult *result, uint32 InstanceId)
{
bool external = (result != NULL);
if (!external)
- // 0 1 2 3 4 5 6 7 8
- result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map,data,time,corpse_type,instance FROM corpse WHERE guid = '%u'",guid);
+ // 0 1 2 3 4 5 6 7 8 9
+ result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map,data,time,corpse_type,instance,phaseMask FROM corpse WHERE guid = '%u'",guid);
if( ! result )
{
@@ -166,8 +167,8 @@ bool Corpse::LoadFromDB(uint32 guid, QueryResult *result, uint32 InstanceId)
bool Corpse::LoadFromDB(uint32 guid, Field *fields)
{
- // 0 1 2 3 4 5 6 7 8
- //result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map,data,time,corpse_type,instance FROM corpse WHERE guid = '%u'",guid);
+ // 0 1 2 3 4 5 6 7 8 9
+ //result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map,data,time,corpse_type,instance,phaseMask FROM corpse WHERE guid = '%u'",guid);
float positionX = fields[0].GetFloat();
float positionY = fields[1].GetFloat();
float positionZ = fields[2].GetFloat();
@@ -188,6 +189,7 @@ bool Corpse::LoadFromDB(uint32 guid, Field *fields)
return false;
}
uint32 instanceid = fields[8].GetUInt32();
+ uint32 phaseMask = fields[9].GetUInt32();
// overwrite possible wrong/corrupted guid
SetUInt64Value(OBJECT_FIELD_GUID, MAKE_NEW_GUID(guid, 0, HIGHGUID_CORPSE));
@@ -195,6 +197,7 @@ bool Corpse::LoadFromDB(uint32 guid, Field *fields)
// place
SetInstanceId(instanceid);
SetMapId(mapid);
+ SetPhaseMask(phaseMask,false);
Relocate(positionX,positionY,positionZ,ort);
if(!IsPositionValid())
diff --git a/src/game/Corpse.h b/src/game/Corpse.h
index 3cd6299a494..45203a9de76 100644
--- a/src/game/Corpse.h
+++ b/src/game/Corpse.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -58,7 +58,7 @@ class Corpse : public WorldObject
void RemoveFromWorld();
bool Create( uint32 guidlow );
- bool Create( uint32 guidlow, Player *owner, uint32 mapid, float x, float y, float z, float ang );
+ bool Create( uint32 guidlow, Player *owner );
void SaveToDB();
bool LoadFromDB(uint32 guid, QueryResult *result, uint32 InstanceId);
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
index 681aab3ebe3..9a4b35f21f7 100644
--- a/src/game/Creature.cpp
+++ b/src/game/Creature.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -39,7 +39,7 @@
#include "SpellAuras.h"
#include "WaypointMovementGenerator.h"
#include "InstanceData.h"
-#include "BattleGround.h"
+#include "BattleGroundMgr.h"
#include "Util.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
@@ -55,7 +55,7 @@ void TrainerSpellData::Clear()
{
for (TrainerSpellList::iterator itr = spellList.begin(); itr != spellList.end(); ++itr)
delete (*itr);
- spellList.empty();
+ spellList.clear();
}
TrainerSpell const* TrainerSpellData::Find(uint32 spell_id) const
@@ -145,14 +145,15 @@ Unit(), i_AI(NULL), i_AI_possessed(NULL),
lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLeaderGUID(0),
m_lootMoney(0), m_lootRecipient(0),
m_deathTimer(0), m_respawnTime(0), m_respawnDelay(25), m_corpseDelay(60), m_respawnradius(0.0f),
-m_gossipOptionLoaded(false), m_emoteState(0), m_isPet(false), m_isTotem(false), m_reactState(REACT_AGGRESSIVE),
-m_regenTimer(2000), m_defaultMovementType(IDLE_MOTION_TYPE), m_equipmentId(0),
+m_gossipOptionLoaded(false), m_emoteState(0), m_isPet(false), m_isTotem(false), m_isVehicle(false), m_reactState(REACT_AGGRESSIVE),
+m_defaultMovementType(IDLE_MOTION_TYPE), m_equipmentId(0),
m_AlreadyCallAssistance(false), m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false),
m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),m_creatureInfo(NULL), m_DBTableGuid(0), m_formationID(0)
{
+ m_regenTimer = 200;
m_valuesCount = UNIT_END;
- for(int i =0; i<4; ++i)
+ for(int i =0; i<CREATURE_MAX_SPELLS; ++i)
m_spells[i] = 0;
m_CreatureSpellCooldowns.clear();
@@ -316,7 +317,6 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData *data )
// creatures always have melee weapon ready if any
SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE );
- SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_AURAS );
SelectLevel(GetCreatureInfo());
if (team == HORDE)
@@ -360,10 +360,8 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData *data )
SetPvP(true);
}
- m_spells[0] = GetCreatureInfo()->spell1;
- m_spells[1] = GetCreatureInfo()->spell2;
- m_spells[2] = GetCreatureInfo()->spell3;
- m_spells[3] = GetCreatureInfo()->spell4;
+ for(int i=0; i < CREATURE_MAX_SPELLS; ++i)
+ m_spells[i] = GetCreatureInfo()->spells[i];
// HACK: trigger creature is always not selectable
if(isTrigger())
@@ -637,11 +635,11 @@ void Creature::DisablePossessedAI()
m_AI_enabled = true;
}
-bool Creature::Create (uint32 guidlow, Map *map, uint32 Entry, uint32 team, const CreatureData *data)
+bool Creature::Create (uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 team, const CreatureData *data)
{
SetMapId(map->GetId());
SetInstanceId(map->GetInstanceId());
- //m_DBTableGuid = guidlow;
+ SetPhaseMask(phaseMask,false);
//oX = x; oY = y; dX = x; dY = y; m_moveTime = 0; m_startMove = 0;
const bool bResult = CreateFromProto(guidlow, Entry, team, data);
@@ -762,7 +760,7 @@ bool Creature::isCanInteractWithBattleMaster(Player* pPlayer, bool msg) const
if(!isBattleMaster())
return false;
- uint32 bgTypeId = objmgr.GetBattleMasterBG(GetEntry());
+ BattleGroundTypeId bgTypeId = sBattleGroundMgr.GetBattleMasterBG(GetEntry());
if(!msg)
return pPlayer->GetBGAccessByLevel(bgTypeId);
@@ -778,8 +776,11 @@ bool Creature::isCanInteractWithBattleMaster(Player* pPlayer, bool msg) const
case BATTLEGROUND_NA:
case BATTLEGROUND_BE:
case BATTLEGROUND_AA:
- case BATTLEGROUND_RL: pPlayer->PlayerTalkClass->SendGossipMenu(10024,GetGUID()); break;
- break;
+ case BATTLEGROUND_RL:
+ case BATTLEGROUND_SA:
+ case BATTLEGROUND_DS:
+ case BATTLEGROUND_RV: pPlayer->PlayerTalkClass->SendGossipMenu(10024,GetGUID()); break;
+ default: break;
}
return false;
}
@@ -926,13 +927,11 @@ void Creature::sendPreparedGossip(Player* player)
if(!player)
return;
- GossipMenu& gossipmenu = player->PlayerTalkClass->GetGossipMenu();
-
if(GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_WORLDEVENT) // if world event npc then
gameeventmgr.HandleWorldEventGossip(player, this); // update world state with progress
// in case empty gossip menu open quest menu if any
- if (gossipmenu.Empty() && GetNpcTextId() == 0)
+ if (player->PlayerTalkClass->GetGossipMenu().Empty() && !player->PlayerTalkClass->GetQuestMenu().Empty())
{
player->SendPreparedQuest(GetGUID());
return;
@@ -1033,7 +1032,7 @@ void Creature::OnGossipSelect(Player* player, uint32 option)
break;
case GOSSIP_OPTION_BATTLEFIELD:
{
- uint32 bgTypeId = objmgr.GetBattleMasterBG(GetEntry());
+ BattleGroundTypeId bgTypeId = sBattleGroundMgr.GetBattleMasterBG(GetEntry());
player->GetSession()->SendBattlegGroundList( GetGUID(), bgTypeId );
break;
}
@@ -1196,10 +1195,10 @@ void Creature::SaveToDB()
return;
}
- SaveToDB(GetMapId(), data->spawnMask);
+ SaveToDB(GetMapId(), data->spawnMask,GetPhaseMask());
}
-void Creature::SaveToDB(uint32 mapid, uint8 spawnMask)
+void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
{
// update in loaded data
if (!m_DBTableGuid)
@@ -1219,6 +1218,7 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask)
// data->guid = guid don't must be update at save
data.id = GetEntry();
data.mapid = mapid;
+ data.phaseMask = phaseMask;
data.displayid = displayId;
data.equipmentId = GetEquipmentId();
data.posX = GetPositionX();
@@ -1248,6 +1248,7 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask)
<< GetEntry() << ","
<< mapid <<","
<< (uint32)spawnMask << ","
+ << (uint32)GetPhaseMask() << ","
<< displayId <<","
<< GetEquipmentId() <<","
<< GetPositionX() << ","
@@ -1417,7 +1418,7 @@ bool Creature::LoadFromDB(uint32 guid, Map *map)
if (map->GetInstanceId() != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_UNIT);
uint16 team = 0;
- if(!Create(guid,map,data->id,team,data))
+ if(!Create(guid,map,data->phaseMask,data->id,team,data))
return false;
Relocate(data->posX,data->posY,data->posZ,data->orientation);
@@ -1478,11 +1479,7 @@ void Creature::LoadEquipment(uint32 equip_entry, bool force)
if (force)
{
for (uint8 i = 0; i < 3; i++)
- {
- SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + i, 0);
- SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + (i * 2), 0);
- SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + (i * 2) + 1, 0);
- }
+ SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + i, 0);
m_equipmentId = 0;
}
return;
@@ -1494,11 +1491,7 @@ void Creature::LoadEquipment(uint32 equip_entry, bool force)
m_equipmentId = equip_entry;
for (uint8 i = 0; i < 3; i++)
- {
- SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + i, einfo->equipmodel[i]);
- SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + (i * 2), einfo->equipinfo[i]);
- SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + (i * 2) + 1, einfo->equipslot[i]);
- }
+ SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + i, einfo->equipentry[i]);
}
bool Creature::hasQuest(uint32 quest_id) const
@@ -1556,6 +1549,10 @@ bool Creature::canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList, bo
if (u == this)
return true;
+ // phased visibility (both must phased in same way)
+ if(!InSamePhase(u))
+ return false;
+
// always seen by owner
if(GetGUID() == u->GetCharmerOrOwnerGUID())
return true;
@@ -1726,7 +1723,7 @@ void Creature::Respawn()
}
}
-bool Creature::IsImmunedToSpell(SpellEntry const* spellInfo, bool useCharges)
+bool Creature::IsImmunedToSpell(SpellEntry const* spellInfo)
{
if (!spellInfo)
return false;
@@ -1734,15 +1731,15 @@ bool Creature::IsImmunedToSpell(SpellEntry const* spellInfo, bool useCharges)
if (GetCreatureInfo()->MechanicImmuneMask & (1 << (spellInfo->Mechanic - 1)))
return true;
- return Unit::IsImmunedToSpell(spellInfo, useCharges);
+ return Unit::IsImmunedToSpell(spellInfo);
}
-bool Creature::IsImmunedToSpellEffect(uint32 effect, uint32 mechanic) const
+bool Creature::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const
{
- if (GetCreatureInfo()->MechanicImmuneMask & (1 << (mechanic-1)))
+ if (GetCreatureInfo()->MechanicImmuneMask & (1 << (spellInfo->EffectMechanic[index] - 1)))
return true;
- return Unit::IsImmunedToSpellEffect(effect, mechanic);
+ return Unit::IsImmunedToSpellEffect(spellInfo, index);
}
SpellEntry const *Creature::reachWithSpellAttack(Unit *pVictim)
@@ -1786,7 +1783,9 @@ SpellEntry const *Creature::reachWithSpellAttack(Unit *pVictim)
// continue;
if( dist > range || dist < minrange )
continue;
- if(HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))
+ if(spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))
+ continue;
+ if(spellInfo->PreventionType == SPELL_PREVENTION_TYPE_PACIFY && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED))
continue;
return spellInfo;
}
@@ -1830,7 +1829,9 @@ SpellEntry const *Creature::reachWithSpellCure(Unit *pVictim)
// continue;
if( dist > range || dist < minrange )
continue;
- if(HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))
+ if(spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))
+ continue;
+ if(spellInfo->PreventionType == SPELL_PREVENTION_TYPE_PACIFY && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED))
continue;
return spellInfo;
}
@@ -1878,7 +1879,7 @@ void Creature::DoFleeToGetAssistance(float radius) // Optional parameter
Creature* pCreature = NULL;
Trinity::NearestAssistCreatureInCreatureRangeCheck u_check(this,getVictim(),radius);
- Trinity::CreatureLastSearcher<Trinity::NearestAssistCreatureInCreatureRangeCheck> searcher(pCreature, u_check);
+ Trinity::CreatureLastSearcher<Trinity::NearestAssistCreatureInCreatureRangeCheck> searcher(this, pCreature, u_check);
VisitNearbyGridObject(radius, searcher);
if(!pCreature)
@@ -1898,7 +1899,7 @@ Unit* Creature::SelectNearestTarget(float dist) const
{
Trinity::NearestHostileUnitInAttackDistanceCheck u_check(this, dist);
- Trinity::UnitLastSearcher<Trinity::NearestHostileUnitInAttackDistanceCheck> searcher(target, u_check);
+ Trinity::UnitLastSearcher<Trinity::NearestHostileUnitInAttackDistanceCheck> searcher(this, target, u_check);
TypeContainerVisitor<Trinity::UnitLastSearcher<Trinity::NearestHostileUnitInAttackDistanceCheck>, WorldTypeMapContainer > world_unit_searcher(searcher);
TypeContainerVisitor<Trinity::UnitLastSearcher<Trinity::NearestHostileUnitInAttackDistanceCheck>, GridTypeMapContainer > grid_unit_searcher(searcher);
@@ -1928,8 +1929,8 @@ void Creature::CallAssistance()
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
- Trinity::AnyAssistCreatureInRangeCheck u_check(this, getVictim(), radius);
- Trinity::CreatureListSearcher<Trinity::AnyAssistCreatureInRangeCheck> searcher(assistList, u_check);
+ MaNGOS::AnyAssistCreatureInRangeCheck u_check(this, getVictim(), radius);
+ MaNGOS::CreatureListSearcher<MaNGOS::AnyAssistCreatureInRangeCheck> searcher(this, assistList, u_check);
TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AnyAssistCreatureInRangeCheck>, GridTypeMapContainer > grid_creature_searcher(searcher);
diff --git a/src/game/Creature.h b/src/game/Creature.h
index 97796f3e639..e79164bfed6 100644
--- a/src/game/Creature.h
+++ b/src/game/Creature.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -176,7 +176,7 @@ struct CreatureInfo
uint32 rangeattacktime;
uint32 unit_flags; // enum UnitFlags mask values
uint32 dynamicflags;
- uint32 family; // enum CreatureFamily values for type==CREATURE_TYPE_BEAST, or 0 in another cases
+ uint32 family; // enum CreatureFamily values (optional)
uint32 trainer_type;
uint32 trainer_spell;
uint32 classNum;
@@ -195,10 +195,7 @@ struct CreatureInfo
int32 resistance4;
int32 resistance5;
int32 resistance6;
- uint32 spell1;
- uint32 spell2;
- uint32 spell3;
- uint32 spell4;
+ uint32 spells[CREATURE_MAX_SPELLS];
uint32 PetSpellDataId;
uint32 mingold;
uint32 maxgold;
@@ -221,6 +218,8 @@ struct CreatureInfo
return SKILL_HERBALISM;
else if(type_flags & CREATURE_TYPEFLAGS_MININGLOOT)
return SKILL_MINING;
+ else if(type_flags & CREATURE_TYPEFLAGS_ENGINEERLOOT)
+ return SKILL_ENGINERING;
else
return SKILL_SKINNING; // normal case
}
@@ -246,9 +245,7 @@ struct NpcOptionLocale
struct EquipmentInfo
{
uint32 entry;
- uint32 equipmodel[3];
- uint32 equipinfo[3];
- uint32 equipslot[3];
+ uint32 equipentry[3];
};
// from `creature` table
@@ -256,6 +253,7 @@ struct CreatureData
{
uint32 id; // entry in creature_template
uint16 mapid;
+ uint16 phaseMask;
uint32 displayid;
int32 equipmentId;
float posX;
@@ -352,6 +350,7 @@ struct VendorItemData
{
for (VendorItemList::iterator itr = m_items.begin(); itr != m_items.end(); ++itr)
delete (*itr);
+ m_items.clear();
}
};
@@ -370,10 +369,14 @@ typedef std::list<VendorItemCount> VendorItemCounts;
struct TrainerSpell
{
uint32 spell;
- uint32 spellcost;
- uint32 reqskill;
- uint32 reqskillvalue;
- uint32 reqlevel;
+ uint32 spellCost;
+ uint32 reqSkill;
+ uint32 reqSkillValue;
+ uint32 reqLevel;
+ uint32 learnedSpell;
+
+ // helpers
+ bool IsCastable() const { return learnedSpell != spell; }
};
typedef std::vector<TrainerSpell*> TrainerSpellList;
@@ -412,7 +415,7 @@ class TRINITY_DLL_SPEC Creature : public Unit
void AddToWorld();
void RemoveFromWorld();
- bool Create (uint32 guidlow, Map *map, uint32 Entry, uint32 team, const CreatureData *data = NULL);
+ bool Create (uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 team, const CreatureData *data = NULL);
bool LoadCreaturesAddon(bool reload = false);
void SelectLevel(const CreatureInfo *cinfo);
void LoadEquipment(uint32 equip_entry, bool force=false);
@@ -425,6 +428,7 @@ class TRINITY_DLL_SPEC Creature : public Unit
uint32 GetEquipmentId() const { return m_equipmentId; }
bool isPet() const { return m_isPet; }
+ bool isVehicle() const { return m_isVehicle; }
void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; }
bool isTotem() const { return m_isTotem; }
bool isRacialLeader() const { return GetCreatureInfo()->RacialLeader; }
@@ -441,9 +445,9 @@ class TRINITY_DLL_SPEC Creature : public Unit
bool isCanInteractWithBattleMaster(Player* player, bool msg) const;
bool isCanTrainingAndResetTalentsOf(Player* pPlayer) const;
bool IsOutOfThreatArea(Unit* pVictim) const;
- bool IsImmunedToSpell(SpellEntry const* spellInfo, bool useCharges = false);
+ bool IsImmunedToSpell(SpellEntry const* spellInfo);
// redefine Unit::IsImmunedToSpell
- bool IsImmunedToSpellEffect(uint32 effect, uint32 mechanic) const;
+ bool IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const;
// redefine Unit::IsImmunedToSpellEffect
bool isElite() const
{
@@ -544,7 +548,7 @@ class TRINITY_DLL_SPEC Creature : public Unit
bool LoadFromDB(uint32 guid, Map *map);
void SaveToDB();
// overwrited in Pet
- virtual void SaveToDB(uint32 mapid, uint8 spawnMask);
+ virtual void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask);
virtual void DeleteFromDB(); // overwrited in Pet
Loot loot;
@@ -660,11 +664,11 @@ class TRINITY_DLL_SPEC Creature : public Unit
uint8 m_emoteState;
bool m_isPet; // set only in Pet::Pet
+ bool m_isVehicle; // set only in Vehicle::Vehicle
bool m_isTotem; // set only in Totem::Totem
ReactStates m_reactState; // for AI, not charmInfo
void RegenerateMana();
void RegenerateHealth();
- uint32 m_regenTimer;
MovementGeneratorType m_defaultMovementType;
Cell m_currentCell; // store current cell where creature listed
uint32 m_DBTableGuid; ///< For new or temporary creatures is 0 for saved it is lowguid
diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp
index 885d9ddcadb..7343bb8333a 100644
--- a/src/game/CreatureAI.cpp
+++ b/src/game/CreatureAI.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h
index c39fb6ce9dd..4e0051c3d0c 100644
--- a/src/game/CreatureAI.h
+++ b/src/game/CreatureAI.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/CreatureAIImpl.h b/src/game/CreatureAIImpl.h
index 2122adeb61c..cb422c2a016 100644
--- a/src/game/CreatureAIImpl.h
+++ b/src/game/CreatureAIImpl.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/CreatureAIRegistry.cpp b/src/game/CreatureAIRegistry.cpp
index 12b4aa97d0d..9ed1763141f 100644
--- a/src/game/CreatureAIRegistry.cpp
+++ b/src/game/CreatureAIRegistry.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/CreatureAIRegistry.h b/src/game/CreatureAIRegistry.h
index 0fecef476dc..53776e3d4e9 100644
--- a/src/game/CreatureAIRegistry.h
+++ b/src/game/CreatureAIRegistry.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/CreatureAISelector.cpp b/src/game/CreatureAISelector.cpp
index bebc810e6c0..8b4205980be 100644
--- a/src/game/CreatureAISelector.cpp
+++ b/src/game/CreatureAISelector.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/CreatureAISelector.h b/src/game/CreatureAISelector.h
index 8a354a4007e..a6fc47e3913 100644
--- a/src/game/CreatureAISelector.h
+++ b/src/game/CreatureAISelector.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/CreatureGroups.cpp b/src/game/CreatureGroups.cpp
index 3669c638c45..a45c59f9186 100644
--- a/src/game/CreatureGroups.cpp
+++ b/src/game/CreatureGroups.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/CreatureGroups.h b/src/game/CreatureGroups.h
index c8dd45c1b3f..45df16086b1 100644
--- a/src/game/CreatureGroups.h
+++ b/src/game/CreatureGroups.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/Debugcmds.cpp b/src/game/Debugcmds.cpp
index daa8a2f8fa3..60f1536963f 100644
--- a/src/game/Debugcmds.cpp
+++ b/src/game/Debugcmds.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -63,6 +63,7 @@ bool ChatHandler::HandleDebugSpellFailCommand(const char* args)
uint8 failnum = (uint8)atoi(px);
WorldPacket data(SMSG_CAST_FAILED, 5);
+ data << uint8(0);
data << uint32(133);
data << uint8(failnum);
m_session->SendPacket(&data);
@@ -132,8 +133,12 @@ bool ChatHandler::HandleBuyErrorCommand(const char* args)
bool ChatHandler::HandleSendOpcodeCommand(const char* /*args*/)
{
Unit *unit = getSelectedUnit();
+ Player *player = NULL;
if (!unit || (unit->GetTypeId() != TYPEID_PLAYER))
- unit = m_session->GetPlayer();
+ player = m_session->GetPlayer();
+ else
+ player = (Player*)unit;
+ if(!unit) unit = player;
std::ifstream ifs("opcode.txt");
if(ifs.bad())
@@ -192,6 +197,14 @@ bool ChatHandler::HandleSendOpcodeCommand(const char* /*args*/)
{
data.append(unit->GetPackGUID());
}
+ else if(type == "myguid")
+ data.append(player->GetPackGUID());
+ else if(type == "pos")
+ {
+ data << unit->GetPositionX();
+ data << unit->GetPositionY();
+ data << unit->GetPositionZ();
+ }
else
{
sLog.outDebug("Sending opcode: unknown type '%s'", type.c_str());
@@ -201,7 +214,7 @@ bool ChatHandler::HandleSendOpcodeCommand(const char* /*args*/)
ifs.close();
sLog.outDebug("Sending opcode %u", data.GetOpcode());
data.hexlike();
- ((Player*)unit)->GetSession()->SendPacket(&data);
+ player->GetSession()->SendPacket(&data);
PSendSysMessage(LANG_COMMAND_OPCODESENT, data.GetOpcode(), unit->GetName());
return true;
}
@@ -522,6 +535,12 @@ bool ChatHandler::HandleGetItemState(const char* args)
return true;
}
+bool ChatHandler::HandleDebugBattlegroundCommand(const char * /*args*/)
+{
+ sBattleGroundMgr.ToggleTesting();
+ return true;
+}
+
bool ChatHandler::HandleDebugArenaCommand(const char * /*args*/)
{
sBattleGroundMgr.ToggleArenaTesting();
@@ -570,3 +589,63 @@ bool ChatHandler::HandleDebugHostilRefList(const char * /*args*/)
SendSysMessage("End of hostil reference list.");
return true;
}
+
+bool ChatHandler::HandleSpawnVehicle(const char* args)
+{
+ if(!args)
+ return false;
+
+ char* e = strtok((char*)args, " ");
+ char* i = strtok(NULL, " ");
+
+ if (!e || !i)
+ return false;
+
+ uint32 entry = (uint32)atoi(e);
+ uint32 id = (uint32)atoi(i);
+
+ CreatureInfo const *ci = objmgr.GetCreatureTemplate(entry);
+
+ if(!ci)
+ return false;
+
+ VehicleEntry const *ve = sVehicleStore.LookupEntry(id);
+
+ if(!ve)
+ return false;
+
+ Vehicle *v = new Vehicle;
+ Map *map = m_session->GetPlayer()->GetMap();
+ if(!v->Create(objmgr.GenerateLowGuid(HIGHGUID_VEHICLE), map, entry, id, m_session->GetPlayer()->GetTeam()))
+ {
+ delete v;
+ return false;
+ }
+
+ float px, py, pz;
+ m_session->GetPlayer()->GetClosePoint(px, py, pz, m_session->GetPlayer()->GetObjectSize());
+
+ v->Relocate(px, py, pz, m_session->GetPlayer()->GetOrientation());
+
+ if(!v->IsPositionValid())
+ {
+ sLog.outError("ERROR: Vehicle (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
+ v->GetGUIDLow(), v->GetEntry(), v->GetPositionX(), v->GetPositionY());
+ delete v;
+ return false;
+ }
+
+ map->Add((Creature*)v);
+
+ return true;
+}
+
+bool ChatHandler::HandleSendLargePacketCommand(const char* args)
+{
+ const char* stuffingString = "This is a dummy string to push the packet's size beyond 128000 bytes. ";
+ std::ostringstream ss;
+ while(strlen(ss.str().c_str()) < 128000)
+ ss << stuffingString;
+ SendSysMessage(ss.str().c_str());
+ return true;
+}
diff --git a/src/game/DestinationHolder.cpp b/src/game/DestinationHolder.cpp
index 1a9beab4a01..6f4e08256c5 100644
--- a/src/game/DestinationHolder.cpp
+++ b/src/game/DestinationHolder.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/DestinationHolder.h b/src/game/DestinationHolder.h
index 311fb4f4d70..a1d295ead09 100644
--- a/src/game/DestinationHolder.h
+++ b/src/game/DestinationHolder.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/DestinationHolderImp.h b/src/game/DestinationHolderImp.h
index 443f6a90211..963e074fff9 100644
--- a/src/game/DestinationHolderImp.h
+++ b/src/game/DestinationHolderImp.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/DuelHandler.cpp b/src/game/DuelHandler.cpp
index bc3cf7db4bf..acde3b4ef51 100644
--- a/src/game/DuelHandler.cpp
+++ b/src/game/DuelHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/DynamicObject.cpp b/src/game/DynamicObject.cpp
index 4f63a149244..09856f1233e 100644
--- a/src/game/DynamicObject.cpp
+++ b/src/game/DynamicObject.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -38,7 +38,7 @@ DynamicObject::DynamicObject() : WorldObject()
m_objectType |= TYPEMASK_DYNAMICOBJECT;
m_objectTypeId = TYPEID_DYNAMICOBJECT;
// 2.3.2 - 0x58
- m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION);
+ m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION);
m_valuesCount = DYNAMICOBJECT_END;
}
@@ -61,7 +61,7 @@ bool DynamicObject::Create( uint32 guidlow, Unit *caster, uint32 spellId, uint32
{
SetInstanceId(caster->GetInstanceId());
- WorldObject::_Create(guidlow, HIGHGUID_DYNAMICOBJECT, caster->GetMapId());
+ WorldObject::_Create(guidlow, HIGHGUID_DYNAMICOBJECT, caster->GetMapId(), caster->GetPhaseMask());
Relocate(x,y,z,0);
if(!IsPositionValid())
diff --git a/src/game/DynamicObject.h b/src/game/DynamicObject.h
index a27be9a521c..05a5f3d930d 100644
--- a/src/game/DynamicObject.h
+++ b/src/game/DynamicObject.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/FleeingMovementGenerator.cpp b/src/game/FleeingMovementGenerator.cpp
index ff3d2f21b78..a3bbb965961 100644
--- a/src/game/FleeingMovementGenerator.cpp
+++ b/src/game/FleeingMovementGenerator.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -301,19 +301,26 @@ FleeingMovementGenerator<T>::Initialize(T &owner)
if(!&owner)
return;
- Unit * fright = ObjectAccessor::GetUnit(owner, i_frightGUID);
- if(!fright)
- return;
-
_Init(owner);
owner.CastStop();
owner.addUnitState(UNIT_STAT_FLEEING);
owner.SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING);
owner.SetUInt64Value(UNIT_FIELD_TARGET, 0);
owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
- i_caster_x = fright->GetPositionX();
- i_caster_y = fright->GetPositionY();
- i_caster_z = fright->GetPositionZ();
+
+ if(Unit * fright = ObjectAccessor::GetUnit(owner, i_frightGUID))
+ {
+ i_caster_x = fright->GetPositionX();
+ i_caster_y = fright->GetPositionY();
+ i_caster_z = fright->GetPositionZ();
+ }
+ else
+ {
+ i_caster_x = owner.GetPositionX();
+ i_caster_y = owner.GetPositionY();
+ i_caster_z = owner.GetPositionZ();
+ }
+
i_only_forward = true;
i_cur_angle = 0.0f;
i_last_distance_from_caster = 0.0f;
diff --git a/src/game/FleeingMovementGenerator.h b/src/game/FleeingMovementGenerator.h
index 23b5a0ad589..9bf967fa42d 100644
--- a/src/game/FleeingMovementGenerator.h
+++ b/src/game/FleeingMovementGenerator.h
@@ -1,7 +1,7 @@
/*
-* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
-* Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+* Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/FollowerRefManager.h b/src/game/FollowerRefManager.h
index ab445fa29df..06e04c8d3ae 100644
--- a/src/game/FollowerRefManager.h
+++ b/src/game/FollowerRefManager.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/FollowerReference.cpp b/src/game/FollowerReference.cpp
index c554f6b44ba..d6a113a8bb6 100644
--- a/src/game/FollowerReference.cpp
+++ b/src/game/FollowerReference.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/FollowerReference.h b/src/game/FollowerReference.h
index 1a7c09d13e9..d15664ab6db 100644
--- a/src/game/FollowerReference.h
+++ b/src/game/FollowerReference.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/Formulas.h b/src/game/Formulas.h
index f9915a2001c..720a7a2825d 100644
--- a/src/game/Formulas.h
+++ b/src/game/Formulas.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -80,8 +80,17 @@ namespace Trinity
inline uint32 BaseGain(uint32 pl_level, uint32 mob_level, ContentLevels content)
{
- //TODO: need modifier for CONTENT_71_80 different from CONTENT_61_70?
- const uint32 nBaseExp = content == CONTENT_1_60 ? 45 : 235;
+ uint32 nBaseExp;
+ switch(content)
+ {
+ case CONTENT_1_60: nBaseExp = 45; break;
+ case CONTENT_61_70: nBaseExp = 235; break;
+ case CONTENT_71_80: nBaseExp = 580; break;
+ default:
+ sLog.outError("BaseGain: Unsupported content level %u",content);
+ nBaseExp = 45; break;
+ }
+
if( mob_level >= pl_level )
{
uint32 nLevelDiff = mob_level - pl_level;
@@ -118,66 +127,6 @@ namespace Trinity
return (uint32)(xp_gain*sWorld.getRate(RATE_XP_KILL));
}
- inline uint32 xp_Diff(uint32 lvl)
- {
- if( lvl < 29 )
- return 0;
- if( lvl == 29 )
- return 1;
- if( lvl == 30 )
- return 3;
- if( lvl == 31 )
- return 6;
- else
- return (5*(lvl-30));
- }
-
- inline uint32 mxp(uint32 lvl)
- {
- if (lvl < 60)
- {
- return (45 + (5*lvl));
- }
- else
- {
- return (235 + (5*lvl));
- }
- }
-
- inline uint32 xp_to_level(uint32 lvl)
- {
- uint32 xp = 0;
- if (lvl < 60)
- {
- xp = (8*lvl + xp_Diff(lvl)) * mxp(lvl);
- }
- else if (lvl == 60)
- {
- xp = (155 + mxp(lvl) * (1344 - 70 - ((69 - lvl) * (7 + (69 - lvl) * 8 - 1)/2)));
- }
- else if (lvl < 70)
- {
- xp = (155 + mxp(lvl) * (1344 - ((69-lvl) * (7 + (69 - lvl) * 8 - 1)/2)));
- }else
- {
- // level higher than 70 is not supported
- xp = (uint32)(779700 * (pow(sWorld.getRate(RATE_XP_PAST_70), (int32)lvl - 69)));
- return ((xp < 0x7fffffff) ? xp : 0x7fffffff);
- }
-
- // The XP to Level is always rounded to the nearest 100 points (50 rounded to high).
- xp = ((xp + 50) / 100) * 100; // use additional () for prevent free association operations in C++
-
- if ((lvl > 10) && (lvl < 60)) // compute discount added in 2.3.x
- {
- uint32 discount = (lvl < 28) ? (lvl - 10) : 18;
- xp = (xp * (100 - discount)) / 100; // apply discount
- xp = (xp / 100) * 100; // floor to hundreds
- }
-
- return xp;
- }
-
inline float xp_in_group_rate(uint32 count, bool isRaid)
{
if(isRaid)
diff --git a/src/game/GameEvent.cpp b/src/game/GameEvent.cpp
index ee6f348296a..62f285e25ac 100644
--- a/src/game/GameEvent.cpp
+++ b/src/game/GameEvent.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -190,50 +190,52 @@ void GameEvent::LoadFromDB()
if( !result )
{
mGameEvent.clear();
- sLog.outString(">> Table game_event is empty:");
+ sLog.outString(">> Table game_event is empty!");
sLog.outString();
return;
}
uint32 count = 0;
- barGoLink bar( result->GetRowCount() );
- do
{
- ++count;
- Field *fields = result->Fetch();
+ barGoLink bar( result->GetRowCount() );
+ do
+ {
+ ++count;
+ Field *fields = result->Fetch();
- bar.step();
+ bar.step();
- uint16 event_id = fields[0].GetUInt16();
- if(event_id==0)
- {
- sLog.outErrorDb("`game_event` game event id (%i) is reserved and can't be used.",event_id);
- continue;
- }
+ uint16 event_id = fields[0].GetUInt16();
+ if(event_id==0)
+ {
+ sLog.outErrorDb("`game_event` game event id (%i) is reserved and can't be used.",event_id);
+ continue;
+ }
- GameEventData& pGameEvent = mGameEvent[event_id];
- uint64 starttime = fields[1].GetUInt64();
- pGameEvent.start = time_t(starttime);
- uint64 endtime = fields[2].GetUInt64();
- pGameEvent.end = time_t(endtime);
- pGameEvent.occurence = fields[3].GetUInt32();
- pGameEvent.length = fields[4].GetUInt32();
- pGameEvent.description = fields[5].GetCppString();
- pGameEvent.state = (GameEventState)(fields[6].GetUInt8());
- pGameEvent.nextstart = 0;
-
- if(pGameEvent.length==0 && pGameEvent.state == GAMEEVENT_NORMAL) // length>0 is validity check
- {
- sLog.outErrorDb("`game_event` game event id (%i) isn't a world event and has length = 0, thus it can't be used.",event_id);
- continue;
- }
+ GameEventData& pGameEvent = mGameEvent[event_id];
+ uint64 starttime = fields[1].GetUInt64();
+ pGameEvent.start = time_t(starttime);
+ uint64 endtime = fields[2].GetUInt64();
+ pGameEvent.end = time_t(endtime);
+ pGameEvent.occurence = fields[3].GetUInt32();
+ pGameEvent.length = fields[4].GetUInt32();
+ pGameEvent.description = fields[5].GetCppString();
+ pGameEvent.state = (GameEventState)(fields[6].GetUInt8());
+ pGameEvent.nextstart = 0;
+
+ if(pGameEvent.length==0 && pGameEvent.state == GAMEEVENT_NORMAL) // length>0 is validity check
+ {
+ sLog.outErrorDb("`game_event` game event id (%i) isn't a world event and has length = 0, thus it can't be used.",event_id);
+ continue;
+ }
- } while( result->NextRow() );
+ } while( result->NextRow() );
+ delete result;
- sLog.outString();
- sLog.outString( ">> Loaded %u game events", count );
- delete result;
+ sLog.outString();
+ sLog.outString( ">> Loaded %u game events", count );
+ }
// load game event saves
// 0 1 2
@@ -346,8 +348,8 @@ void GameEvent::LoadFromDB()
count = 0;
if( !result )
{
- barGoLink bar2(1);
- bar2.step();
+ barGoLink bar(1);
+ bar.step();
sLog.outString();
sLog.outString(">> Loaded %u creatures in game events", count );
@@ -355,12 +357,12 @@ void GameEvent::LoadFromDB()
else
{
- barGoLink bar2( result->GetRowCount() );
+ barGoLink bar( result->GetRowCount() );
do
{
Field *fields = result->Fetch();
- bar2.step();
+ bar.step();
uint32 guid = fields[0].GetUInt32();
int16 event_id = fields[1].GetInt16();
@@ -378,9 +380,10 @@ void GameEvent::LoadFromDB()
crelist.push_back(guid);
} while( result->NextRow() );
+ delete result;
+
sLog.outString();
sLog.outString( ">> Loaded %u creatures in game events", count );
- delete result;
}
mGameEventGameobjectGuids.resize(mGameEvent.size()*2-1);
@@ -391,8 +394,8 @@ void GameEvent::LoadFromDB()
count = 0;
if( !result )
{
- barGoLink bar3(1);
- bar3.step();
+ barGoLink bar(1);
+ bar.step();
sLog.outString();
sLog.outString(">> Loaded %u gameobjects in game events", count );
@@ -400,12 +403,12 @@ void GameEvent::LoadFromDB()
else
{
- barGoLink bar3( result->GetRowCount() );
+ barGoLink bar( result->GetRowCount() );
do
{
Field *fields = result->Fetch();
- bar3.step();
+ bar.step();
uint32 guid = fields[0].GetUInt32();
int16 event_id = fields[1].GetInt16();
@@ -423,10 +426,10 @@ void GameEvent::LoadFromDB()
golist.push_back(guid);
} while( result->NextRow() );
+ delete result;
+
sLog.outString();
sLog.outString( ">> Loaded %u gameobjects in game events", count );
-
- delete result;
}
mGameEventModelEquip.resize(mGameEvent.size());
@@ -439,8 +442,8 @@ void GameEvent::LoadFromDB()
count = 0;
if( !result )
{
- barGoLink bar3(1);
- bar3.step();
+ barGoLink bar(1);
+ bar.step();
sLog.outString();
sLog.outString(">> Loaded %u model/equipment changes in game events", count );
@@ -448,12 +451,12 @@ void GameEvent::LoadFromDB()
else
{
- barGoLink bar3( result->GetRowCount() );
+ barGoLink bar( result->GetRowCount() );
do
{
Field *fields = result->Fetch();
- bar3.step();
+ bar.step();
uint32 guid = fields[0].GetUInt32();
uint16 event_id = fields[1].GetUInt16();
@@ -483,10 +486,10 @@ void GameEvent::LoadFromDB()
equiplist.push_back(std::pair<uint32, ModelEquip>(guid, newModelEquipSet));
} while( result->NextRow() );
+ delete result;
+
sLog.outString();
sLog.outString( ">> Loaded %u model/equipment changes in game events", count );
-
- delete result;
}
mGameEventCreatureQuests.resize(mGameEvent.size());
@@ -496,8 +499,8 @@ void GameEvent::LoadFromDB()
count = 0;
if( !result )
{
- barGoLink bar3(1);
- bar3.step();
+ barGoLink bar(1);
+ bar.step();
sLog.outString();
sLog.outString(">> Loaded %u quests additions in game events", count );
@@ -505,12 +508,12 @@ void GameEvent::LoadFromDB()
else
{
- barGoLink bar3( result->GetRowCount() );
+ barGoLink bar( result->GetRowCount() );
do
{
Field *fields = result->Fetch();
- bar3.step();
+ bar.step();
uint32 id = fields[0].GetUInt32();
uint32 quest = fields[1].GetUInt32();
uint16 event_id = fields[2].GetUInt16();
@@ -569,10 +572,10 @@ void GameEvent::LoadFromDB()
questlist.push_back(QuestRelation(id, quest));
} while( result->NextRow() );
+ delete result;
+
sLog.outString();
sLog.outString( ">> Loaded %u quests additions in game events", count );
-
- delete result;
}
// Load quest to (event,condition) mapping
diff --git a/src/game/GameEvent.h b/src/game/GameEvent.h
index 2655a5925db..ab5a1ed3292 100644
--- a/src/game/GameEvent.h
+++ b/src/game/GameEvent.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp
index b7487568e62..f2bf5739334 100644
--- a/src/game/GameObject.cpp
+++ b/src/game/GameObject.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -46,7 +46,7 @@ GameObject::GameObject() : WorldObject()
m_objectType |= TYPEMASK_GAMEOBJECT;
m_objectTypeId = TYPEID_GAMEOBJECT;
// 2.3.2 - 0x58
- m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION);
+ m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION);
m_valuesCount = GAMEOBJECT_END;
m_respawnTime = 0;
@@ -93,11 +93,12 @@ void GameObject::RemoveFromWorld()
WorldObject::RemoveFromWorld();
}
-bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, uint32 go_state, uint32 ArtKit)
+bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, uint32 go_state, uint32 ArtKit)
{
Relocate(x,y,z,ang);
SetMapId(map->GetId());
SetInstanceId(map->GetInstanceId());
+ SetPhaseMask(phaseMask,false);
if(!IsPositionValid())
{
@@ -127,17 +128,33 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, float x, float
SetFloatValue(GAMEOBJECT_POS_Z, z);
SetFloatValue(GAMEOBJECT_FACING, ang); //this is not facing angle
- SetFloatValue (GAMEOBJECT_ROTATION, rotation0);
- SetFloatValue (GAMEOBJECT_ROTATION+1, rotation1);
- SetFloatValue (GAMEOBJECT_ROTATION+2, rotation2);
- SetFloatValue (GAMEOBJECT_ROTATION+3, rotation3);
+ int64 rotation = 0;
+
+ float f_rot1 = sin(ang / 2.0f);
+ int64 i_rot1 = f_rot1 / atan(pow(2.0f, -20.0f));
+ rotation |= (i_rot1 << 43 >> 43) & 0x00000000001FFFFF;
+
+ //float f_rot2 = sin(0.0f / 2.0f);
+ //int64 i_rot2 = f_rot2 / atan(pow(2.0f, -20.0f));
+ //rotation |= (((i_rot2 << 22) >> 32) >> 11) & 0x000003FFFFE00000;
+
+ //float f_rot3 = sin(0.0f / 2.0f);
+ //int64 i_rot3 = f_rot3 / atan(pow(2.0f, -21.0f));
+ //rotation |= (i_rot3 >> 42) & 0x7FFFFC0000000000;
+
+ SetUInt64Value(GAMEOBJECT_ROTATION, rotation);
+
+ SetFloatValue(GAMEOBJECT_PARENTROTATION+0, rotation0);
+ SetFloatValue(GAMEOBJECT_PARENTROTATION+1, rotation1);
+ SetFloatValue(GAMEOBJECT_PARENTROTATION+2, rotation2);
+ SetFloatValue(GAMEOBJECT_PARENTROTATION+3, rotation3);
SetFloatValue(OBJECT_FIELD_SCALE_X, goinfo->size);
SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction);
SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags);
- SetUInt32Value(OBJECT_FIELD_ENTRY, goinfo->id);
+ SetEntry(goinfo->id);
SetUInt32Value(GAMEOBJECT_DISPLAYID, goinfo->displayId);
@@ -146,7 +163,7 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, float x, float
SetGoAnimProgress(animprogress);
- SetUInt32Value (GAMEOBJECT_ARTKIT, ArtKit);
+ SetByteValue(GAMEOBJECT_BYTES_1, 2, ArtKit);
// Spell charges for GAMEOBJECT_TYPE_SPELLCASTER (22)
if (goinfo->type == GAMEOBJECT_TYPE_SPELLCASTER)
@@ -264,7 +281,7 @@ void GameObject::Update(uint32 /*p_time*/)
return;
}
// respawn timer
- MapManager::Instance().GetMap(GetMapId(), this)->Add(this);
+ GetMap()->Add(this);
break;
}
}
@@ -309,8 +326,8 @@ void GameObject::Update(uint32 /*p_time*/)
// search unfriendly creature
if(owner && NeedDespawn) // hunter trap
{
- Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(this, owner, radius);
- Trinity::UnitSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> checker(ok, u_check);
+ MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck u_check(this, owner, radius);
+ MaNGOS::UnitSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck> checker(this,ok, u_check);
CellLock<GridReadGuard> cell_lock(cell, p);
@@ -330,8 +347,8 @@ void GameObject::Update(uint32 /*p_time*/)
// affect only players
Player* p_ok = NULL;
- Trinity::AnyPlayerInObjectRangeCheck p_check(this, radius);
- Trinity::PlayerSearcher<Trinity::AnyPlayerInObjectRangeCheck> checker(p_ok, p_check);
+ MaNGOS::AnyPlayerInObjectRangeCheck p_check(this, radius);
+ MaNGOS::PlayerSearcher<MaNGOS::AnyPlayerInObjectRangeCheck> checker(this,p_ok, p_check);
CellLock<GridReadGuard> cell_lock(cell, p);
@@ -344,8 +361,8 @@ void GameObject::Update(uint32 /*p_time*/)
{
//Unit *caster = owner ? owner : ok;
- //caster->CastSpell(ok, goInfo->trap.spellId, true);
CastSpell(ok, goInfo->trap.spellId);
+ //caster->CastSpell(ok, goInfo->trap.spellId, true, 0, 0, GetGUID());
m_cooldownTime = time(NULL) + 4; // 4 seconds
if(NeedDespawn)
@@ -395,7 +412,7 @@ void GameObject::Update(uint32 /*p_time*/)
for (; it != end; it++)
{
Unit* owner = Unit::GetUnit(*this, uint64(*it));
- if (owner) owner->CastSpell(owner, spellId, false);
+ if (owner) owner->CastSpell(owner, spellId, false, 0, 0, GetGUID());
}
m_unique_users.clear();
@@ -414,7 +431,7 @@ void GameObject::Update(uint32 /*p_time*/)
//burning flags in some battlegrounds, if you find better condition, just add it
if (GetGoAnimProgress() > 0)
{
- SendObjectDeSpawnAnim(this->GetGUID());
+ SendObjectDeSpawnAnim(GetGUID());
//reset flags
SetUInt32Value(GAMEOBJECT_FLAGS, GetGOInfo()->flags);
}
@@ -451,7 +468,7 @@ void GameObject::Refresh()
return;
if(isSpawned())
- MapManager::Instance().GetMap(GetMapId(), this)->Add(this);
+ GetMap()->Add(this);
}
void GameObject::AddUniqueUse(Player* player)
@@ -470,7 +487,7 @@ void GameObject::Delete()
AddObjectToRemoveList();
}
-void GameObject::getFishLoot(Loot *fishloot)
+void GameObject::getFishLoot(Loot *fishloot, Player* loot_owner)
{
fishloot->clear();
@@ -478,10 +495,10 @@ void GameObject::getFishLoot(Loot *fishloot)
// if subzone loot exist use it
if(LootTemplates_Fishing.HaveLootFor(subzone))
- fishloot->FillLoot(subzone, LootTemplates_Fishing, NULL);
+ fishloot->FillLoot(subzone, LootTemplates_Fishing, loot_owner,true);
// else use zone loot
else
- fishloot->FillLoot(GetZoneId(), LootTemplates_Fishing, NULL);
+ fishloot->FillLoot(GetZoneId(), LootTemplates_Fishing, loot_owner,true);
}
void GameObject::SaveToDB()
@@ -495,10 +512,10 @@ void GameObject::SaveToDB()
return;
}
- SaveToDB(GetMapId(), data->spawnMask);
+ SaveToDB(GetMapId(), data->spawnMask, data->phaseMask);
}
-void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask)
+void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
{
const GameObjectInfo *goI = GetGOInfo();
@@ -513,38 +530,40 @@ void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask)
// data->guid = guid don't must be update at save
data.id = GetEntry();
data.mapid = mapid;
+ data.phaseMask = phaseMask;
data.posX = GetFloatValue(GAMEOBJECT_POS_X);
data.posY = GetFloatValue(GAMEOBJECT_POS_Y);
data.posZ = GetFloatValue(GAMEOBJECT_POS_Z);
data.orientation = GetFloatValue(GAMEOBJECT_FACING);
- data.rotation0 = GetFloatValue(GAMEOBJECT_ROTATION+0);
- data.rotation1 = GetFloatValue(GAMEOBJECT_ROTATION+1);
- data.rotation2 = GetFloatValue(GAMEOBJECT_ROTATION+2);
- data.rotation3 = GetFloatValue(GAMEOBJECT_ROTATION+3);
+ data.rotation0 = GetFloatValue(GAMEOBJECT_PARENTROTATION+0);
+ data.rotation1 = GetFloatValue(GAMEOBJECT_PARENTROTATION+1);
+ data.rotation2 = GetFloatValue(GAMEOBJECT_PARENTROTATION+2);
+ data.rotation3 = GetFloatValue(GAMEOBJECT_PARENTROTATION+3);
data.spawntimesecs = m_spawnedByDefault ? m_respawnDelayTime : -(int32)m_respawnDelayTime;
data.animprogress = GetGoAnimProgress();
data.go_state = GetGoState();
data.spawnMask = spawnMask;
- data.ArtKit = GetUInt32Value (GAMEOBJECT_ARTKIT);
+ data.ArtKit = GetGoArtKit();
// updated in DB
std::ostringstream ss;
ss << "INSERT INTO gameobject VALUES ( "
<< m_DBTableGuid << ", "
- << GetUInt32Value (OBJECT_FIELD_ENTRY) << ", "
+ << GetEntry() << ", "
<< mapid << ", "
<< (uint32)spawnMask << ", "
+ << (uint32)GetPhaseMask() << ","
<< GetFloatValue(GAMEOBJECT_POS_X) << ", "
<< GetFloatValue(GAMEOBJECT_POS_Y) << ", "
<< GetFloatValue(GAMEOBJECT_POS_Z) << ", "
<< GetFloatValue(GAMEOBJECT_FACING) << ", "
- << GetFloatValue(GAMEOBJECT_ROTATION) << ", "
- << GetFloatValue(GAMEOBJECT_ROTATION+1) << ", "
- << GetFloatValue(GAMEOBJECT_ROTATION+2) << ", "
- << GetFloatValue(GAMEOBJECT_ROTATION+3) << ", "
+ << GetFloatValue(GAMEOBJECT_PARENTROTATION) << ", "
+ << GetFloatValue(GAMEOBJECT_PARENTROTATION+1) << ", "
+ << GetFloatValue(GAMEOBJECT_PARENTROTATION+2) << ", "
+ << GetFloatValue(GAMEOBJECT_PARENTROTATION+3) << ", "
<< m_respawnDelayTime << ", "
- << GetGoAnimProgress() << ", "
- << GetGoState() << ")";
+ << (uint32)GetGoAnimProgress() << ", "
+ << (uint32)GetGoState() << ")";
WorldDatabase.BeginTransaction();
WorldDatabase.PExecuteLog("DELETE FROM gameobject WHERE guid = '%u'", m_DBTableGuid);
@@ -563,7 +582,8 @@ bool GameObject::LoadFromDB(uint32 guid, Map *map)
}
uint32 entry = data->id;
- uint32 map_id = data->mapid;
+ //uint32 map_id = data->mapid; // already used before call
+ uint32 phaseMask = data->phaseMask;
float x = data->posX;
float y = data->posY;
float z = data->posZ;
@@ -581,7 +601,7 @@ bool GameObject::LoadFromDB(uint32 guid, Map *map)
m_DBTableGuid = guid;
if (map->GetInstanceId() != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT);
- if (!Create(guid,entry, map, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, animprogress, go_state, ArtKit) )
+ if (!Create(guid,entry, map, phaseMask, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, animprogress, go_state, ArtKit) )
return false;
switch(GetGOInfo()->type)
@@ -724,10 +744,6 @@ bool GameObject::isVisibleForInState(Player const* u, bool inVisibleList) const
if(owner && u->IsHostileTo(owner) && !canDetectTrap(u, GetDistance(u)))
return false;
}
-
- // Smuggled Mana Cell required 10 invisibility type detection/state
- if(GetEntry()==187039 && ((u->m_detectInvisibilityMask | u->m_invisibilityMask) & (1<<10))==0)
- return false;
}
// check distance
@@ -820,8 +836,8 @@ void GameObject::TriggeringLinkedGameObject( uint32 trapEntry, Unit* target)
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
- Trinity::NearestGameObjectEntryInObjectRangeCheck go_check(*target,trapEntry,range);
- Trinity::GameObjectLastSearcher<Trinity::NearestGameObjectEntryInObjectRangeCheck> checker(trapGO,go_check);
+ MaNGOS::NearestGameObjectEntryInObjectRangeCheck go_check(*target,trapEntry,range);
+ MaNGOS::GameObjectLastSearcher<MaNGOS::NearestGameObjectEntryInObjectRangeCheck> checker(this, trapGO,go_check);
TypeContainerVisitor<Trinity::GameObjectLastSearcher<Trinity::NearestGameObjectEntryInObjectRangeCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
@@ -831,7 +847,7 @@ void GameObject::TriggeringLinkedGameObject( uint32 trapEntry, Unit* target)
// found correct GO
// FIXME: when GO casting will be implemented trap must cast spell to target
if(trapGO)
- target->CastSpell(target,trapSpell,true);
+ target->CastSpell(target,trapSpell,true, 0, 0, GetGUID());
}
GameObject* GameObject::LookupFishingHoleAround(float range)
@@ -841,8 +857,8 @@ GameObject* GameObject::LookupFishingHoleAround(float range)
CellPair p(Trinity::ComputeCellPair(GetPositionX(),GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
- Trinity::NearestGameObjectFishingHole u_check(*this, range);
- Trinity::GameObjectSearcher<Trinity::NearestGameObjectFishingHole> checker(ok, u_check);
+ MaNGOS::NearestGameObjectFishingHole u_check(*this, range);
+ MaNGOS::GameObjectSearcher<MaNGOS::NearestGameObjectFishingHole> checker(this, ok, u_check);
CellLock<GridReadGuard> cell_lock(cell, p);
@@ -867,9 +883,9 @@ void GameObject::UseDoorOrButton(uint32 time_to_restore)
}
-void GameObject::SetGoArtKit(uint32 kit)
+void GameObject::SetGoArtKit(uint8 kit)
{
- SetUInt32Value(GAMEOBJECT_ARTKIT, kit);
+ SetByteValue(GAMEOBJECT_BYTES_1, 2, kit);
GameObjectData *data = const_cast<GameObjectData*>(objmgr.GetGOData(m_DBTableGuid));
if(data)
data->ArtKit = kit;
@@ -974,7 +990,7 @@ void GameObject::Use(Unit* user)
// fallback, will always work
player->TeleportTo(GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation(),TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET);
}
- player->SetStandState(PLAYER_STATE_SIT_LOW_CHAIR+info->chair.height);
+ player->SetStandState(UNIT_STAND_STATE_SIT_LOW_CHAIR+info->chair.height);
return;
}
//big gun, its a spell/aura
@@ -1268,6 +1284,26 @@ void GameObject::Use(Unit* user)
}
break;
}
+ case GAMEOBJECT_TYPE_BARBER_CHAIR: //32
+ {
+ GameObjectInfo const* info = GetGOInfo();
+ if(!info)
+ return;
+
+ if(user->GetTypeId()!=TYPEID_PLAYER)
+ return;
+
+ Player* player = (Player*)user;
+
+ // fallback, will always work
+ player->TeleportTo(GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation(),TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET);
+
+ WorldPacket data(SMSG_ENABLE_BARBER_SHOP, 0);
+ player->GetSession()->SendPacket(&data);
+
+ player->SetStandState(UNIT_STAND_STATE_SIT_LOW_CHAIR+info->barberChair.chairheight);
+ return;
+ }
default:
sLog.outDebug("Unknown Object Type %u", GetGoType());
break;
diff --git a/src/game/GameObject.h b/src/game/GameObject.h
index 3b837a0550c..a492e4dad35 100644
--- a/src/game/GameObject.h
+++ b/src/game/GameObject.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -336,12 +336,12 @@ struct GameObjectInfo
uint32 mapID; //0
uint32 difficulty; //1
} dungeonDifficulty;
- //32 GAMEOBJECT_TYPE_DO_NOT_USE_YET
+ //32 GAMEOBJECT_TYPE_BARBER_CHAIR
struct
{
- uint32 mapID; //0
- uint32 difficulty; //1
- } doNotUseYet;
+ uint32 chairheight; //0
+ uint32 heightOffset; //1
+ } barberChair;
//33 GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING
struct
{
@@ -350,6 +350,13 @@ struct GameObjectInfo
uint32 state1Name; //2
uint32 state2Name; //3
} destructibleBuilding;
+ //34 GAMEOBJECT_TYPE_TRAPDOOR
+ struct
+ {
+ uint32 whenToPause; // 0
+ uint32 startOpen; // 1
+ uint32 autoClose; // 2
+ } trapDoor;
// not use for specific field access (only for output with loop by all filed), also this determinate max union size
struct // GAMEOBJECT_TYPE_SPELLCASTER
@@ -370,7 +377,8 @@ struct GameObjectLocale
struct GameObjectData
{
uint32 id; // entry in gamobject_template
- uint32 mapid;
+ uint16 mapid;
+ uint16 phaseMask;
float posX;
float posY;
float posZ;
@@ -419,7 +427,7 @@ class TRINITY_DLL_SPEC GameObject : public WorldObject
void AddToWorld();
void RemoveFromWorld();
- bool Create(uint32 guidlow, uint32 name_id, Map *map, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, uint32 go_state, uint32 ArtKit = 0);
+ bool Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, uint32 go_state, uint32 ArtKit = 0);
void Update(uint32 p_time);
static GameObject* GetGameObject(WorldObject& object, uint64 guid);
GameObjectInfo const* GetGOInfo() const;
@@ -449,7 +457,7 @@ class TRINITY_DLL_SPEC GameObject : public WorldObject
const char* GetNameForLocaleIdx(int32 locale_idx) const;
void SaveToDB();
- void SaveToDB(uint32 mapid, uint8 spawnMask);
+ void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask);
bool LoadFromDB(uint32 guid, Map *map);
void DeleteFromDB();
void SetLootState(LootState s) { m_lootState = s; }
@@ -503,15 +511,15 @@ class TRINITY_DLL_SPEC GameObject : public WorldObject
void Delete();
void SetSpellId(uint32 id) { m_spellId = id;}
uint32 GetSpellId() const { return m_spellId;}
- void getFishLoot(Loot *loot);
- GameobjectTypes GetGoType() const { return GameobjectTypes(GetUInt32Value(GAMEOBJECT_TYPE_ID)); }
- void SetGoType(GameobjectTypes type) { SetUInt32Value(GAMEOBJECT_TYPE_ID, type); }
- uint32 GetGoState() const { return GetUInt32Value(GAMEOBJECT_STATE); }
- void SetGoState(uint32 state) { SetUInt32Value(GAMEOBJECT_STATE, state); }
- uint32 GetGoArtKit() const { return GetUInt32Value(GAMEOBJECT_ARTKIT); }
- void SetGoArtKit(uint32 artkit);
- uint32 GetGoAnimProgress() const { return GetUInt32Value(GAMEOBJECT_ANIMPROGRESS); }
- void SetGoAnimProgress(uint32 animprogress) { SetUInt32Value(GAMEOBJECT_ANIMPROGRESS, animprogress); }
+ void getFishLoot(Loot *loot, Player* loot_owner);
+ GameobjectTypes GetGoType() const { return GameobjectTypes(GetByteValue(GAMEOBJECT_BYTES_1, 1)); }
+ void SetGoType(GameobjectTypes type) { SetByteValue(GAMEOBJECT_BYTES_1, 1, type); }
+ uint8 GetGoState() const { return GetByteValue(GAMEOBJECT_BYTES_1, 0); }
+ void SetGoState(uint8 state) { SetByteValue(GAMEOBJECT_BYTES_1, 0, state); }
+ uint8 GetGoArtKit() const { return GetByteValue(GAMEOBJECT_BYTES_1, 2); }
+ void SetGoArtKit(uint8 artkit);
+ uint8 GetGoAnimProgress() const { return GetByteValue(GAMEOBJECT_BYTES_1, 3); }
+ void SetGoAnimProgress(uint8 animprogress) { SetByteValue(GAMEOBJECT_BYTES_1, 3, animprogress); }
void Use(Unit* user);
diff --git a/src/game/GlobalEvents.cpp b/src/game/GlobalEvents.cpp
index 635d426f694..807b0c695d0 100644
--- a/src/game/GlobalEvents.cpp
+++ b/src/game/GlobalEvents.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -55,7 +55,7 @@ static void CorpsesEraseCallBack(QueryResult *result, bool bones)
{
if(!ObjectAccessor::Instance().ConvertCorpseForPlayer(player_guid))
{
- sLog.outDebug("Corpse %u not found in world. Delete from DB.",guidlow);
+ sLog.outDebug("Corpse %u not found in world or bones creating forbidden. Delete from DB.",guidlow);
CharacterDatabase.PExecute("DELETE FROM corpse WHERE guid = '%u'",guidlow);
}
}
diff --git a/src/game/GlobalEvents.h b/src/game/GlobalEvents.h
index a1c6b31a406..0b76b09330a 100644
--- a/src/game/GlobalEvents.h
+++ b/src/game/GlobalEvents.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/GossipDef.cpp b/src/game/GossipDef.cpp
index 85414fa3372..f8b1ac04f99 100644
--- a/src/game/GossipDef.cpp
+++ b/src/game/GossipDef.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -127,7 +127,7 @@ bool PlayerMenu::GossipOptionCoded( unsigned int Selection )
void PlayerMenu::SendGossipMenu( uint32 TitleTextId, uint64 npcGUID )
{
WorldPacket data( SMSG_GOSSIP_MESSAGE, (100) ); // guess size
- data << npcGUID;
+ data << uint64(npcGUID);
data << uint32(0); // new 2.4.0
data << uint32( TitleTextId );
data << uint32( mGossipMenu.MenuItemCount() ); // max count 0x0F
@@ -417,10 +417,14 @@ void PlayerMenu::SendQuestGiverQuestDetails( Quest const *pQuest, uint64 npcGUID
}
data << uint64(npcGUID);
+ data << uint64(0); // wotlk, something todo with quest sharing?
data << uint32(pQuest->GetQuestId());
- data << Title << Details << Objectives;
+ data << Title;
+ data << Details;
+ data << Objectives;
data << uint32(ActivateAccept);
data << uint32(pQuest->GetSuggestedPlayers());
+ data << uint8(0); // new wotlk
if (pQuest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS))
{
@@ -466,6 +470,7 @@ void PlayerMenu::SendQuestGiverQuestDetails( Quest const *pQuest, uint64 npcGUID
data << uint32(pQuest->GetRewSpell()); // reward spell, this spell will display (icon) (casted if RewSpellCast==0)
data << uint32(pQuest->GetRewSpellCast()); // casted spell
data << uint32(pQuest->GetCharTitleId()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles)
+ data << uint32(pQuest->GetBonusTalents()); // bonus talents
data << uint32(QUEST_EMOTE_COUNT);
for (uint32 i=0; i < QUEST_EMOTE_COUNT; i++)
@@ -542,6 +547,8 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest )
data << uint32(pQuest->GetSrcItemId());
data << uint32(pQuest->GetFlags() & 0xFFFF);
data << uint32(pQuest->GetCharTitleId()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles)
+ data << uint32(pQuest->GetPlayersSlain()); // players slain
+ data << uint32(pQuest->GetBonusTalents()); // bonus talents
int iI;
@@ -588,15 +595,23 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest )
data << uint32(pQuest->ReqCreatureOrGOId[iI]);
}
data << uint32(pQuest->ReqCreatureOrGOCount[iI]);
+ data << uint32(0); // added in WotLK, dunno if offset if correct
+ }
+
+ for (iI = 0; iI < QUEST_OBJECTIVES_COUNT; ++iI)
+ {
data << uint32(pQuest->ReqItemId[iI]);
data << uint32(pQuest->ReqItemCount[iI]);
}
+ data << uint32(0); // TODO: 5 item objective
+ data << uint32(0);
+
for (iI = 0; iI < QUEST_OBJECTIVES_COUNT; iI++)
data << ObjectiveText[iI];
pSession->SendPacket( &data );
- sLog.outDebug( "WORLD: Sent SMSG_QUEST_QUERY_RESPONSE questid=%u",pQuest->GetQuestId() );
+ sLog.outDebug( "WORLD: Sent SMSG_QUEST_QUERY_RESPONSE questid=%u", pQuest->GetQuestId() );
}
void PlayerMenu::SendQuestGiverOfferReward( Quest const* pQuest, uint64 npcGUID, bool EnbleNext )
@@ -678,9 +693,10 @@ void PlayerMenu::SendQuestGiverOfferReward( Quest const* pQuest, uint64 npcGUID,
data << uint32(0x08); // unused by client?
data << uint32(pQuest->GetRewSpell()); // reward spell, this spell will display (icon) (casted if RewSpellCast==0)
data << uint32(pQuest->GetRewSpellCast()); // casted spell
- data << uint32(0x00); // unk, NOT honor
+ data << uint32(0); // unknown
+ data << uint32(pQuest->GetBonusTalents()); // bonus talents
pSession->SendPacket( &data );
- sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_OFFER_REWARD NPCGuid=%u, questid=%u",GUID_LOPART(npcGUID),pQuest->GetQuestId() );
+ sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_OFFER_REWARD NPCGuid=%u, questid=%u", GUID_LOPART(npcGUID), pQuest->GetQuestId() );
}
void PlayerMenu::SendQuestGiverRequestItems( Quest const *pQuest, uint64 npcGUID, bool Completable, bool CloseOnCancel )
diff --git a/src/game/GossipDef.h b/src/game/GossipDef.h
index ac4ac213b3d..cb93a4e7a91 100644
--- a/src/game/GossipDef.h
+++ b/src/game/GossipDef.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/GridDefines.h b/src/game/GridDefines.h
index 1c67bd0ca3a..58871f68c03 100644
--- a/src/game/GridDefines.h
+++ b/src/game/GridDefines.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/GridNotifiers.cpp b/src/game/GridNotifiers.cpp
index a189aa72304..638de03fe45 100644
--- a/src/game/GridNotifiers.cpp
+++ b/src/game/GridNotifiers.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -146,7 +146,7 @@ VisibleNotifier::Notify()
// send data at target visibility change (adding to client)
for(std::set<WorldObject*>::const_iterator vItr = i_visibleNow.begin(); vItr != i_visibleNow.end(); ++vItr)
if((*vItr)!=&i_player && (*vItr)->isType(TYPEMASK_UNIT))
- i_player.SendAuraDurationsForTarget((Unit*)(*vItr));
+ i_player.SendAurasForTarget((Unit*)(*vItr));
}
void
@@ -154,6 +154,11 @@ Deliverer::Visit(PlayerMapType &m)
{
for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
{
+ //if (!i_source.InSamePhase(iter->getSource()))
+ // continue;
+ if(!iter->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if (!i_dist || iter->getSource()->GetDistance(&i_source) <= i_dist)
{
// Send packet to all who are sharing the player's vision
@@ -174,6 +179,9 @@ Deliverer::Visit(CreatureMapType &m)
{
for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
{
+ if(!iter->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if (!i_dist || iter->getSource()->GetDistance(&i_source) <= i_dist)
{
// Send packet to all who are sharing the creature's vision
@@ -192,6 +200,9 @@ Deliverer::Visit(DynamicObjectMapType &m)
{
for (DynamicObjectMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
{
+ if(!iter->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if (IS_PLAYER_GUID(iter->getSource()->GetCasterGUID()))
{
// Send packet back to the caster if the caster has vision of dynamic object
@@ -249,9 +260,6 @@ ObjectUpdater::Visit(GridRefManager<T> &m)
}
}
-template void ObjectUpdater::Visit<GameObject>(GameObjectMapType &);
-template void ObjectUpdater::Visit<DynamicObject>(DynamicObjectMapType &);
-
bool CannibalizeObjectCheck::operator()(Corpse* u)
{
// ignore bones
@@ -268,3 +276,6 @@ bool CannibalizeObjectCheck::operator()(Corpse* u)
return false;
}
+
+template void ObjectUpdater::Visit<GameObject>(GameObjectMapType &);
+template void ObjectUpdater::Visit<DynamicObject>(DynamicObjectMapType &);
diff --git a/src/game/GridNotifiers.h b/src/game/GridNotifiers.h
index 4bbb31c65c0..740ded8e17e 100644
--- a/src/game/GridNotifiers.h
+++ b/src/game/GridNotifiers.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -96,8 +96,10 @@ namespace Trinity
std::set<uint64> plr_list;
bool i_toPossessor;
bool i_toSelf;
+ uint32 i_phaseMask;
float i_dist;
- Deliverer(WorldObject &src, WorldPacket *msg, bool to_possessor, bool to_self, float dist = 0.0f) : i_source(src), i_message(msg), i_toPossessor(to_possessor), i_toSelf(to_self), i_dist(dist) {}
+ Deliverer(WorldObject &src, WorldPacket *msg, bool to_possessor, bool to_self, float dist = 0.0f)
+ : i_source(src), i_message(msg), i_toPossessor(to_possessor), i_toSelf(to_self), i_dist(dist), i_phaseMask(src.GetPhaseMask()) {}
void Visit(PlayerMapType &m);
void Visit(CreatureMapType &m);
void Visit(DynamicObjectMapType &m);
@@ -215,10 +217,12 @@ namespace Trinity
template<class Check>
struct TRINITY_DLL_DECL WorldObjectSearcher
{
+ uint32 i_phaseMask;
WorldObject* &i_object;
Check &i_check;
- WorldObjectSearcher(WorldObject* & result, Check& check) : i_object(result),i_check(check) {}
+ WorldObjectSearcher(WorldObject const* searcher, WorldObject* & result, Check& check)
+ : i_phaseMask(searcher->GetPhaseMask()), i_object(result),i_check(check) {}
void Visit(GameObjectMapType &m);
void Visit(PlayerMapType &m);
@@ -232,10 +236,12 @@ namespace Trinity
template<class Check>
struct TRINITY_DLL_DECL WorldObjectListSearcher
{
+ uint32 i_phaseMask;
std::list<WorldObject*> &i_objects;
Check& i_check;
- WorldObjectListSearcher(std::list<WorldObject*> &objects, Check & check) : i_objects(objects),i_check(check) {}
+ WorldObjectListSearcher(WorldObject const* searcher, std::list<WorldObject*> &objects, Check & check)
+ : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects),i_check(check) {}
void Visit(PlayerMapType &m);
void Visit(CreatureMapType &m);
@@ -249,37 +255,44 @@ namespace Trinity
template<class Do>
struct TRINITY_DLL_DECL WorldObjectWorker
{
+ uint32 i_phaseMask;
Do const& i_do;
- explicit WorldObjectWorker(Do const& _do) : i_do(_do) {}
+ WorldObjectWorker(WorldObject const* searcher, Do const& _do)
+ : i_phaseMask(searcher->GetPhaseMask()), i_do(_do) {}
void Visit(GameObjectMapType &m)
{
for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- i_do(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ i_do(itr->getSource());
}
void Visit(PlayerMapType &m)
{
for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- i_do(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ i_do(itr->getSource());
}
void Visit(CreatureMapType &m)
{
for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- i_do(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ i_do(itr->getSource());
}
void Visit(CorpseMapType &m)
{
for(CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- i_do(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ i_do(itr->getSource());
}
void Visit(DynamicObjectMapType &m)
{
for(DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- i_do(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ i_do(itr->getSource());
}
template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
@@ -290,10 +303,12 @@ namespace Trinity
template<class Check>
struct TRINITY_DLL_DECL GameObjectSearcher
{
+ uint32 i_phaseMask;
GameObject* &i_object;
Check &i_check;
- GameObjectSearcher(GameObject* & result, Check& check) : i_object(result),i_check(check) {}
+ GameObjectSearcher(WorldObject const* searcher, GameObject* & result, Check& check)
+ : i_phaseMask(searcher->GetPhaseMask()), i_object(result),i_check(check) {}
void Visit(GameObjectMapType &m);
@@ -304,10 +319,12 @@ namespace Trinity
template<class Check>
struct TRINITY_DLL_DECL GameObjectLastSearcher
{
+ uint32 i_phaseMask;
GameObject* &i_object;
Check& i_check;
- GameObjectLastSearcher(GameObject* & result, Check& check) : i_object(result),i_check(check) {}
+ GameObjectLastSearcher(WorldObject const* searcher, GameObject* & result, Check& check)
+ : i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) {}
void Visit(GameObjectMapType &m);
@@ -317,10 +334,12 @@ namespace Trinity
template<class Check>
struct TRINITY_DLL_DECL GameObjectListSearcher
{
+ uint32 i_phaseMask;
std::list<GameObject*> &i_objects;
Check& i_check;
- GameObjectListSearcher(std::list<GameObject*> &objects, Check & check) : i_objects(objects),i_check(check) {}
+ GameObjectListSearcher(WorldObject const* searcher, std::list<GameObject*> &objects, Check & check)
+ : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects), i_check(check) {}
void Visit(GameObjectMapType &m);
@@ -333,10 +352,12 @@ namespace Trinity
template<class Check>
struct TRINITY_DLL_DECL UnitSearcher
{
+ uint32 i_phaseMask;
Unit* &i_object;
Check & i_check;
- UnitSearcher(Unit* & result, Check & check) : i_object(result),i_check(check) {}
+ UnitSearcher(WorldObject const* searcher, Unit* & result, Check & check)
+ : i_phaseMask(searcher->GetPhaseMask()), i_object(result),i_check(check) {}
void Visit(CreatureMapType &m);
void Visit(PlayerMapType &m);
@@ -348,10 +369,12 @@ namespace Trinity
template<class Check>
struct TRINITY_DLL_DECL UnitLastSearcher
{
+ uint32 i_phaseMask;
Unit* &i_object;
Check & i_check;
- UnitLastSearcher(Unit* & result, Check & check) : i_object(result),i_check(check) {}
+ UnitLastSearcher(WorldObject const* searcher, Unit* & result, Check & check)
+ : i_phaseMask(searcher->GetPhaseMask()), i_object(result),i_check(check) {}
void Visit(CreatureMapType &m);
void Visit(PlayerMapType &m);
@@ -363,10 +386,12 @@ namespace Trinity
template<class Check>
struct TRINITY_DLL_DECL UnitListSearcher
{
+ uint32 i_phaseMask;
std::list<Unit*> &i_objects;
Check& i_check;
- UnitListSearcher(std::list<Unit*> &objects, Check & check) : i_objects(objects),i_check(check) {}
+ UnitListSearcher(WorldObject const* searcher, std::list<Unit*> &objects, Check & check)
+ : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects),i_check(check) {}
void Visit(PlayerMapType &m);
void Visit(CreatureMapType &m);
@@ -379,10 +404,12 @@ namespace Trinity
template<class Check>
struct TRINITY_DLL_DECL CreatureSearcher
{
+ uint32 i_phaseMask;
Creature* &i_object;
Check & i_check;
- CreatureSearcher(Creature* & result, Check & check) : i_object(result),i_check(check) {}
+ CreatureSearcher(WorldObject const* searcher, Creature* & result, Check & check)
+ : i_phaseMask(searcher->GetPhaseMask()), i_object(result),i_check(check) {}
void Visit(CreatureMapType &m);
@@ -393,10 +420,12 @@ namespace Trinity
template<class Check>
struct TRINITY_DLL_DECL CreatureLastSearcher
{
+ uint32 i_phaseMask;
Creature* &i_object;
Check & i_check;
- CreatureLastSearcher(Creature* & result, Check & check) : i_object(result),i_check(check) {}
+ CreatureLastSearcher(WorldObject const* searcher, Creature* & result, Check & check)
+ : i_phaseMask(searcher->GetPhaseMask()), i_object(result),i_check(check) {}
void Visit(CreatureMapType &m);
@@ -406,10 +435,12 @@ namespace Trinity
template<class Check>
struct TRINITY_DLL_DECL CreatureListSearcher
{
+ uint32 i_phaseMask;
std::list<Creature*> &i_objects;
Check& i_check;
- CreatureListSearcher(std::list<Creature*> &objects, Check & check) : i_objects(objects),i_check(check) {}
+ CreatureListSearcher(WorldObject const* searcher, std::list<Creature*> &objects, Check & check)
+ : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects),i_check(check) {}
void Visit(CreatureMapType &m);
@@ -421,10 +452,12 @@ namespace Trinity
template<class Check>
struct TRINITY_DLL_DECL PlayerSearcher
{
+ uint32 i_phaseMask;
Player* &i_object;
Check & i_check;
- PlayerSearcher(Player* & result, Check & check) : i_object(result),i_check(check) {}
+ PlayerSearcher(WorldObject const* searcher, Player* & result, Check & check)
+ : i_phaseMask(searcher->GetPhaseMask()), i_object(result),i_check(check) {}
void Visit(PlayerMapType &m);
@@ -434,14 +467,17 @@ namespace Trinity
template<class Do>
struct TRINITY_DLL_DECL PlayerWorker
{
+ uint32 i_phaseMask;
Do& i_do;
- explicit PlayerWorker(Do& _do) : i_do(_do) {}
+ PlayerWorker(WorldObject const* searcher, Do& _do)
+ : i_phaseMask(searcher->GetPhaseMask()), i_do(_do) {}
void Visit(PlayerMapType &m)
{
for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- i_do(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ i_do(itr->getSource());
}
template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
diff --git a/src/game/GridNotifiersImpl.h b/src/game/GridNotifiersImpl.h
index dfb202a37e1..c237c95a28b 100644
--- a/src/game/GridNotifiersImpl.h
+++ b/src/game/GridNotifiersImpl.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -155,7 +155,7 @@ inline void Trinity::DynamicObjectUpdater::VisitHelper(Unit* target)
if( target->GetTypeId()==TYPEID_PLAYER && target != i_check && (((Player*)target)->isGameMaster() || ((Player*)target)->GetVisibility()==VISIBILITY_OFF) )
return;
- if( i_check->GetTypeId()==TYPEID_PLAYER )
+ if (i_check->GetTypeId()==TYPEID_PLAYER )
{
if (i_check->IsFriendlyTo( target ))
return;
@@ -172,7 +172,7 @@ inline void Trinity::DynamicObjectUpdater::VisitHelper(Unit* target)
SpellEntry const *spellInfo = sSpellStore.LookupEntry(i_dynobject.GetSpellId());
uint32 eff_index = i_dynobject.GetEffIndex();
// Check target immune to spell or aura
- if (target->IsImmunedToSpell(spellInfo) || target->IsImmunedToSpellEffect(spellInfo->Effect[eff_index], spellInfo->EffectMechanic[eff_index]))
+ if (target->IsImmunedToSpell(spellInfo) || target->IsImmunedToSpellEffect(spellInfo, eff_index))
return;
// Apply PersistentAreaAura on target
PersistentAreaAura* Aur = new PersistentAreaAura(spellInfo, eff_index, NULL, target, i_dynobject.GetCaster());
@@ -209,7 +209,10 @@ void Trinity::WorldObjectSearcher<Check>::Visit(GameObjectMapType &m)
for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
- if(i_check(itr->getSource()))
+ if(!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
+ if (i_check(itr->getSource()))
{
i_object = itr->getSource();
return;
@@ -226,6 +229,9 @@ void Trinity::WorldObjectSearcher<Check>::Visit(PlayerMapType &m)
for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
+ if(!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if(i_check(itr->getSource()))
{
i_object = itr->getSource();
@@ -243,6 +249,9 @@ void Trinity::WorldObjectSearcher<Check>::Visit(CreatureMapType &m)
for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
+ if(!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if(i_check(itr->getSource()))
{
i_object = itr->getSource();
@@ -260,6 +269,9 @@ void Trinity::WorldObjectSearcher<Check>::Visit(CorpseMapType &m)
for(CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
+ if(!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if(i_check(itr->getSource()))
{
i_object = itr->getSource();
@@ -277,6 +289,9 @@ void Trinity::WorldObjectSearcher<Check>::Visit(DynamicObjectMapType &m)
for(DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
+ if(!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if(i_check(itr->getSource()))
{
i_object = itr->getSource();
@@ -289,40 +304,45 @@ template<class Check>
void Trinity::WorldObjectListSearcher<Check>::Visit(PlayerMapType &m)
{
for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- if(i_check(itr->getSource()))
- i_objects.push_back(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ if(i_check(itr->getSource()))
+ i_objects.push_back(itr->getSource());
}
template<class Check>
void Trinity::WorldObjectListSearcher<Check>::Visit(CreatureMapType &m)
{
for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- if(i_check(itr->getSource()))
- i_objects.push_back(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ if(i_check(itr->getSource()))
+ i_objects.push_back(itr->getSource());
}
template<class Check>
void Trinity::WorldObjectListSearcher<Check>::Visit(CorpseMapType &m)
{
for(CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- if(i_check(itr->getSource()))
- i_objects.push_back(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ if(i_check(itr->getSource()))
+ i_objects.push_back(itr->getSource());
}
template<class Check>
void Trinity::WorldObjectListSearcher<Check>::Visit(GameObjectMapType &m)
{
for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- if(i_check(itr->getSource()))
- i_objects.push_back(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ if(i_check(itr->getSource()))
+ i_objects.push_back(itr->getSource());
}
template<class Check>
void Trinity::WorldObjectListSearcher<Check>::Visit(DynamicObjectMapType &m)
{
for(DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- if(i_check(itr->getSource()))
- i_objects.push_back(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ if(i_check(itr->getSource()))
+ i_objects.push_back(itr->getSource());
}
// Gameobject searchers
@@ -336,6 +356,9 @@ void Trinity::GameObjectSearcher<Check>::Visit(GameObjectMapType &m)
for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
+ if(!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if(i_check(itr->getSource()))
{
i_object = itr->getSource();
@@ -349,6 +372,9 @@ void Trinity::GameObjectLastSearcher<Check>::Visit(GameObjectMapType &m)
{
for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
+ if(!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if(i_check(itr->getSource()))
i_object = itr->getSource();
}
@@ -358,8 +384,9 @@ template<class Check>
void Trinity::GameObjectListSearcher<Check>::Visit(GameObjectMapType &m)
{
for(GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- if(i_check(itr->getSource()))
- i_objects.push_back(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ if(i_check(itr->getSource()))
+ i_objects.push_back(itr->getSource());
}
// Unit searchers
@@ -373,6 +400,9 @@ void Trinity::UnitSearcher<Check>::Visit(CreatureMapType &m)
for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
+ if(!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if(i_check(itr->getSource()))
{
i_object = itr->getSource();
@@ -390,6 +420,9 @@ void Trinity::UnitSearcher<Check>::Visit(PlayerMapType &m)
for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
+ if(!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if(i_check(itr->getSource()))
{
i_object = itr->getSource();
@@ -403,6 +436,9 @@ void Trinity::UnitLastSearcher<Check>::Visit(CreatureMapType &m)
{
for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
+ if(!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if(i_check(itr->getSource()))
i_object = itr->getSource();
}
@@ -413,6 +449,9 @@ void Trinity::UnitLastSearcher<Check>::Visit(PlayerMapType &m)
{
for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
+ if(!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if(i_check(itr->getSource()))
i_object = itr->getSource();
}
@@ -422,16 +461,18 @@ template<class Check>
void Trinity::UnitListSearcher<Check>::Visit(PlayerMapType &m)
{
for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- if(i_check(itr->getSource()))
- i_objects.push_back(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ if(i_check(itr->getSource()))
+ i_objects.push_back(itr->getSource());
}
template<class Check>
void Trinity::UnitListSearcher<Check>::Visit(CreatureMapType &m)
{
for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- if(i_check(itr->getSource()))
- i_objects.push_back(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ if(i_check(itr->getSource()))
+ i_objects.push_back(itr->getSource());
}
// Creature searchers
@@ -445,6 +486,9 @@ void Trinity::CreatureSearcher<Check>::Visit(CreatureMapType &m)
for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
+ if(!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if(i_check(itr->getSource()))
{
i_object = itr->getSource();
@@ -458,6 +502,9 @@ void Trinity::CreatureLastSearcher<Check>::Visit(CreatureMapType &m)
{
for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
+ if(!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if(i_check(itr->getSource()))
i_object = itr->getSource();
}
@@ -467,8 +514,9 @@ template<class Check>
void Trinity::CreatureListSearcher<Check>::Visit(CreatureMapType &m)
{
for(CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- if(i_check(itr->getSource()))
- i_objects.push_back(itr->getSource());
+ if(itr->getSource()->InSamePhase(i_phaseMask))
+ if( i_check(itr->getSource()))
+ i_objects.push_back(itr->getSource());
}
template<class Check>
@@ -480,6 +528,9 @@ void Trinity::PlayerSearcher<Check>::Visit(PlayerMapType &m)
for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
+ if(!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
if(i_check(itr->getSource()))
{
i_object = itr->getSource();
diff --git a/src/game/GridStates.cpp b/src/game/GridStates.cpp
index 5cf5c8b8c11..92df04ef06e 100644
--- a/src/game/GridStates.cpp
+++ b/src/game/GridStates.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/GridStates.h b/src/game/GridStates.h
index 2764d09506c..dd22c482c0a 100644
--- a/src/game/GridStates.h
+++ b/src/game/GridStates.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/Group.cpp b/src/game/Group.cpp
index 829538f8af7..82778346837 100644
--- a/src/game/Group.cpp
+++ b/src/game/Group.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -10,12 +10,12 @@
*
* 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
+ * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Common.h"
@@ -74,6 +74,8 @@ Group::~Group()
for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
for(BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr)
itr->second.save->RemoveGroup(this);
+
+ // Sub group counters clean up
if (m_subGroupsCounts)
delete[] m_subGroupsCounts;
}
@@ -203,6 +205,11 @@ void Group::ConvertToRaid()
if(!isBGGroup()) CharacterDatabase.PExecute("UPDATE groups SET isRaid = 1 WHERE leaderGuid='%u'", GUID_LOPART(m_leaderGuid));
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 = objmgr.GetPlayer(citr->guid))
+ player->UpdateForQuestsGO();
}
bool Group::AddInvite(Player *player)
@@ -288,6 +295,10 @@ bool Group::AddMember(const uint64 &guid, const char* name)
}
player->SetGroupUpdateFlag(GROUP_UPDATE_FULL);
UpdatePlayerOutOfRange(player);
+
+ // quest related GO state dependent from raid memebership
+ if(isRaidGroup())
+ player->UpdateForQuestsGO();
}
return true;
@@ -302,9 +313,12 @@ uint32 Group::RemoveMember(const uint64 &guid, const uint8 &method)
{
bool leaderChanged = _removeMember(guid);
- Player *player = objmgr.GetPlayer( guid ); // FG: TODO: could be removed, its just here for consistency
- if (player)
+ if(Player *player = objmgr.GetPlayer( guid ))
{
+ // quest related GO state dependent from raid membership
+ if(isRaidGroup())
+ player->UpdateForQuestsGO();
+
WorldPacket data;
if(method == 1)
@@ -363,6 +377,11 @@ void Group::Disband(bool hideDestroy)
player->SetGroup(NULL);
+ // quest related GO state dependent from raid membership
+ if(isRaidGroup())
+ player->UpdateForQuestsGO();
+
+
if(!player->GetSession())
continue;
@@ -729,6 +748,8 @@ void Group::CountTheRoll(Rolls::iterator rollI, uint32 NumberOfPlayers)
if(player && player->GetSession())
{
+ player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT, roll->itemid, maxresul);
+
ItemPosCountVec dest;
LootItem *item = &(roll->getLoot()->items[roll->itemSlot]);
uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, roll->itemid, item->count );
@@ -774,6 +795,8 @@ void Group::CountTheRoll(Rolls::iterator rollI, uint32 NumberOfPlayers)
if(player && player->GetSession())
{
+ player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT, roll->itemid, maxresul);
+
ItemPosCountVec dest;
LootItem *item = &(roll->getLoot()->items[roll->itemSlot]);
uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, roll->itemid, item->count );
@@ -835,13 +858,10 @@ void Group::GetDataForXPAtKill(Unit const* victim, uint32& count,uint32& sum_lev
++count;
sum_level += member->getLevel();
- // store maximum member level
if(!member_with_max_level || member_with_max_level->getLevel() < member->getLevel())
member_with_max_level = member;
- uint32 gray_level = Trinity::XP::GetGrayLevel(member->getLevel());
- // if the victim is higher level than the gray level of the currently examined group member,
- // then set not_gray_member_with_max_level if needed.
+ uint32 gray_level = MaNGOS::XP::GetGrayLevel(member->getLevel());
if( victim->getLevel() > gray_level && (!not_gray_member_with_max_level
|| not_gray_member_with_max_level->getLevel() < member->getLevel()))
not_gray_member_with_max_level = member;
@@ -905,7 +925,6 @@ void Group::SendUpdate()
data << (uint64)m_looterGuid; // looter guid
data << (uint8)m_lootThreshold; // loot threshold
data << (uint8)m_difficulty; // Heroic Mod Group
-
}
player->GetSession()->SendPacket( &data );
}
@@ -984,7 +1003,7 @@ bool Group::_addMember(const uint64 &guid, const char* name, bool isAssistant)
}
// We are raid group and no one slot is free
if (!groupFound)
- return false;
+ return false;
}
return _addMember(guid, name, isAssistant, groupid);
@@ -1048,6 +1067,7 @@ bool Group::_removeMember(const uint64 &guid)
if (slot != m_memberSlots.end())
{
SubGroupCounterDecrease(slot->group);
+
m_memberSlots.erase(slot);
}
@@ -1207,6 +1227,7 @@ void Group::ChangeMembersGroup(const uint64 &guid, const uint8 &group)
if(!isRaidGroup())
return;
Player *player = objmgr.GetPlayer(guid);
+
if (!player)
{
uint8 prevSubGroup;
@@ -1218,6 +1239,7 @@ void Group::ChangeMembersGroup(const uint64 &guid, const uint8 &group)
SendUpdate();
}
else
+ // This methods handles itself groupcounter decrease
ChangeMembersGroup(player, group);
}
@@ -1311,7 +1333,7 @@ void Group::UpdateLooterGuid( Creature* creature, bool ifneed )
SendUpdate();
}
-uint32 Group::CanJoinBattleGroundQueue(uint32 bgTypeId, uint32 bgQueueType, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot)
+uint32 Group::CanJoinBattleGroundQueue(BattleGroundTypeId bgTypeId, uint32 bgQueueType, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot)
{
// check for min / max count
uint32 memberscount = GetMembersCount();
@@ -1366,7 +1388,7 @@ uint32 Group::CanJoinBattleGroundQueue(uint32 bgTypeId, uint32 bgQueueType, uint
void Roll::targetObjectBuildLink()
{
// called from link()
- this->getTarget()->addLootValidatorRef(this);
+ getTarget()->addLootValidatorRef(this);
}
void Group::SetDifficulty(uint8 difficulty)
@@ -1474,7 +1496,7 @@ InstanceGroupBind* Group::BindToInstance(InstanceSave *save, bool permanent, boo
InstanceGroupBind& bind = m_boundInstances[save->GetDifficulty()][save->GetMapId()];
if(bind.save)
{
- // when a boss is killed or when copying the player's binds to the group
+ // when a boss is killed or when copying the players's binds to the group
if(permanent != bind.perm || save != bind.save)
if(!load) CharacterDatabase.PExecute("UPDATE group_instance SET instance = '%u', permanent = '%u' WHERE leaderGuid = '%u' AND instance = '%u'", save->GetInstanceId(), permanent, GUID_LOPART(GetLeaderGUID()), bind.save->GetInstanceId());
}
@@ -1535,4 +1557,4 @@ void Group::BroadcastGroupUpdate(void)
DEBUG_LOG("-- Forced group value update for '%s'", pp->GetName());
}
}
-} \ No newline at end of file
+}
diff --git a/src/game/Group.h b/src/game/Group.h
index 9882966e3f6..f3af8deaf7d 100644
--- a/src/game/Group.h
+++ b/src/game/Group.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -66,24 +66,25 @@ enum GroupUpdateFlags
{
GROUP_UPDATE_FLAG_NONE = 0x00000000, // nothing
GROUP_UPDATE_FLAG_STATUS = 0x00000001, // uint16, flags
- GROUP_UPDATE_FLAG_CUR_HP = 0x00000002, // uint16
- GROUP_UPDATE_FLAG_MAX_HP = 0x00000004, // uint16
+ 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 uint16 spellid + uint8 unk
+ 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, // uint16 pet cur health
- GROUP_UPDATE_FLAG_PET_MAX_HP = 0x00004000, // uint16 pet max health
+ 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 uint16 spellid + uint8 unk, pet auras...
+ 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
};
@@ -249,7 +250,7 @@ class TRINITY_DLL_SPEC Group
void ConvertToRaid();
void SetBattlegroundGroup(BattleGround *bg) { m_bgGroup = bg; }
- uint32 CanJoinBattleGroundQueue(uint32 bgTypeId, uint32 bgQueueType, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot);
+ uint32 CanJoinBattleGroundQueue(BattleGroundTypeId bgTypeId, uint32 bgQueueType, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot);
void ChangeMembersGroup(const uint64 &guid, const uint8 &group);
void ChangeMembersGroup(Player *player, const uint8 &group);
diff --git a/src/game/GroupHandler.cpp b/src/game/GroupHandler.cpp
index f875e833c77..574ebd7de75 100644
--- a/src/game/GroupHandler.cpp
+++ b/src/game/GroupHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -162,6 +162,7 @@ void WorldSession::HandleGroupInviteOpcode( WorldPacket & recv_data )
// ok, we do it
WorldPacket data(SMSG_GROUP_INVITE, 10); // guess size
+ data << uint8(1); // ok
data << GetPlayer()->GetName();
player->GetSession()->SendPacket(&data);
@@ -554,8 +555,17 @@ void WorldSession::HandleGroupChangeSubGroupOpcode( WorldPacket & recv_data )
return;
/********************/
+ //Do not allow leader to change group of player in combat
+ Player *movedPlayer=objmgr.GetPlayer(name.c_str());
+ if (movedPlayer->isInCombat())
+ {
+ WorldPacket data(SMSG_GROUP_SWAP_FAILED, (0));
+ SendPacket(&data);
+ return;
+ }
+
// everything's fine, do it
- group->ChangeMembersGroup(objmgr.GetPlayer(name.c_str()), groupNr);
+ group->ChangeMembersGroup(movedPlayer, groupNr);
}
void WorldSession::HandleGroupAssistantOpcode( WorldPacket & recv_data )
@@ -690,10 +700,10 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
}
if (mask & GROUP_UPDATE_FLAG_CUR_HP)
- *data << (uint16) player->GetHealth();
+ *data << (uint32) player->GetHealth();
if (mask & GROUP_UPDATE_FLAG_MAX_HP)
- *data << (uint16) player->GetMaxHealth();
+ *data << (uint32) player->GetMaxHealth();
Powers powerType = player->getPowerType();
if (mask & GROUP_UPDATE_FLAG_POWER_TYPE)
@@ -716,18 +726,15 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
if (mask & GROUP_UPDATE_FLAG_AURAS)
{
- uint64 auramask = player->GetAuraUpdateMask();
+ const uint64& auramask = player->GetAuraUpdateMaskForRaid();
*data << uint64(auramask);
for(uint32 i = 0; i < MAX_AURAS; ++i)
{
if(auramask & (uint64(1) << i))
{
- uint32 updatedAura=player->GetUInt32Value(UNIT_FIELD_AURA + i);
- *data << uint16(updatedAura);
+ AuraSlotEntry * pAura = player->GetVisibleAura(i);
+ *data << uint32(pAura ? pAura->m_spellId : 0);
*data << uint8(1);
- //TODO: find a safe place to do this cleanup
- //if(!updatedAura)
- //player->UnsetAuraUpdateMask(i);
}
}
}
@@ -760,17 +767,17 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
if (mask & GROUP_UPDATE_FLAG_PET_CUR_HP)
{
if(pet)
- *data << (uint16) pet->GetHealth();
+ *data << (uint32) pet->GetHealth();
else
- *data << (uint16) 0;
+ *data << (uint32) 0;
}
if (mask & GROUP_UPDATE_FLAG_PET_MAX_HP)
{
if(pet)
- *data << (uint16) pet->GetMaxHealth();
+ *data << (uint32) pet->GetMaxHealth();
else
- *data << (uint16) 0;
+ *data << (uint32) 0;
}
if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE)
@@ -801,18 +808,15 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
{
if(pet)
{
- uint64 auramask = pet->GetAuraUpdateMask();
+ const uint64& auramask = pet->GetAuraUpdateMaskForRaid();
*data << uint64(auramask);
for(uint32 i = 0; i < MAX_AURAS; ++i)
{
if(auramask & (uint64(1) << i))
{
- uint32 updatedAura=pet->GetUInt32Value(UNIT_FIELD_AURA + i);
- *data << uint16(updatedAura);
+ AuraSlotEntry * pAura = pet->GetVisibleAura(i);
+ *data << uint32(pAura ? pAura->m_spellId : 0);
*data << uint8(1);
- //TODO: find a safe place to do this cleanup
- //if(!updatedAura)
- //pet->UnsetAuraUpdateMask(i);
}
}
}
@@ -834,6 +838,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
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 << (uint32) GROUP_UPDATE_FLAG_STATUS;
data << (uint16) MEMBER_STATUS_OFFLINE;
@@ -844,6 +849,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
Pet *pet = player->GetPet();
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
data.append(player->GetPackGUID());
uint32 mask1 = 0x00040BFF; // common mask, real flags used 0x000040BFF
@@ -853,8 +859,8 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
Powers powerType = player->getPowerType();
data << (uint32) mask1; // group update mask
data << (uint16) MEMBER_STATUS_ONLINE; // member's online status
- data << (uint16) player->GetHealth(); // GROUP_UPDATE_FLAG_CUR_HP
- data << (uint16) player->GetMaxHealth(); // GROUP_UPDATE_FLAG_MAX_HP
+ data << (uint32) player->GetHealth(); // GROUP_UPDATE_FLAG_CUR_HP
+ data << (uint32) player->GetMaxHealth(); // GROUP_UPDATE_FLAG_MAX_HP
data << (uint8) powerType; // GROUP_UPDATE_FLAG_POWER_TYPE
data << (uint16) player->GetPower(powerType); // GROUP_UPDATE_FLAG_CUR_POWER
data << (uint16) player->GetMaxPower(powerType); // GROUP_UPDATE_FLAG_MAX_POWER
@@ -868,11 +874,11 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
data << (uint64) auramask; // placeholder
for(uint8 i = 0; i < MAX_AURAS; ++i)
{
- if(uint32 aura = player->GetUInt32Value(UNIT_FIELD_AURA + i))
+ if(AuraSlotEntry * pAura = player->GetVisibleAura(i))
{
auramask |= (uint64(1) << i);
- data << uint16(aura);
- data << uint8(1);
+ data << (uint32) pAura->m_spellId;
+ data << (uint8) 1;
}
}
data.put<uint64>(maskPos,auramask); // GROUP_UPDATE_FLAG_AURAS
@@ -883,8 +889,8 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
data << (uint64) pet->GetGUID(); // GROUP_UPDATE_FLAG_PET_GUID
data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME
data << (uint16) pet->GetDisplayId(); // GROUP_UPDATE_FLAG_PET_MODEL_ID
- data << (uint16) pet->GetHealth(); // GROUP_UPDATE_FLAG_PET_CUR_HP
- data << (uint16) pet->GetMaxHealth(); // GROUP_UPDATE_FLAG_PET_MAX_HP
+ data << (uint32) pet->GetHealth(); // GROUP_UPDATE_FLAG_PET_CUR_HP
+ data << (uint32) pet->GetMaxHealth(); // GROUP_UPDATE_FLAG_PET_MAX_HP
data << (uint8) petpowertype; // GROUP_UPDATE_FLAG_PET_POWER_TYPE
data << (uint16) pet->GetPower(petpowertype); // GROUP_UPDATE_FLAG_PET_CUR_POWER
data << (uint16) pet->GetMaxPower(petpowertype); // GROUP_UPDATE_FLAG_PET_MAX_POWER
@@ -894,10 +900,10 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
data << (uint64) petauramask; // placeholder
for(uint8 i = 0; i < MAX_AURAS; ++i)
{
- if(uint32 petaura = pet->GetUInt32Value(UNIT_FIELD_AURA + i))
+ if(AuraSlotEntry * pAura = pet->GetVisibleAura(i))
{
petauramask |= (uint64(1) << i);
- data << (uint16) petaura;
+ data << (uint32) pAura->m_spellId;
data << (uint8) 1;
}
}
diff --git a/src/game/GroupRefManager.h b/src/game/GroupRefManager.h
index 1bef31f076f..b17c3394b94 100644
--- a/src/game/GroupRefManager.h
+++ b/src/game/GroupRefManager.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/GroupReference.cpp b/src/game/GroupReference.cpp
index 25ea473309a..e9994a133ca 100644
--- a/src/game/GroupReference.cpp
+++ b/src/game/GroupReference.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/GroupReference.h b/src/game/GroupReference.h
index 66e91bd3a8a..60948435533 100644
--- a/src/game/GroupReference.h
+++ b/src/game/GroupReference.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/GuardAI.cpp b/src/game/GuardAI.cpp
index d3c3d9a7330..4ec794767ea 100644
--- a/src/game/GuardAI.cpp
+++ b/src/game/GuardAI.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/GuardAI.h b/src/game/GuardAI.h
index 30f76dd509a..2f91f359115 100644
--- a/src/game/GuardAI.h
+++ b/src/game/GuardAI.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/Guild.cpp b/src/game/Guild.cpp
index d16274dbf5b..f32cbbeb7fa 100644
--- a/src/game/Guild.cpp
+++ b/src/game/Guild.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -785,6 +785,7 @@ void Guild::Query(WorldSession *session)
data << uint32(BorderStyle);
data << uint32(BorderColor);
data << uint32(BackgroundColor);
+ data << uint32(0); // something new in WotLK
session->SendPacket( &data );
sLog.outDebug( "WORLD: Sent (SMSG_GUILD_QUERY_RESPONSE)" );
@@ -1212,18 +1213,19 @@ void Guild::LoadGuildBankFromDB()
delete result;
- // 0 1 2 3
- result = CharacterDatabase.PQuery("SELECT TabId, SlotId, item_guid, item_entry FROM guild_bank_item WHERE guildid='%u' ORDER BY TabId", Id);
+ // data needs to be at first place for Item::LoadFromDB
+ // 0 1 2 3 4
+ result = CharacterDatabase.PQuery("SELECT data, TabId, SlotId, item_guid, item_entry FROM guild_bank_item JOIN item_instance ON item_guid = guid WHERE guildid='%u' ORDER BY TabId", Id);
if(!result)
return;
do
{
Field *fields = result->Fetch();
- uint8 TabId = fields[0].GetUInt8();
- uint8 SlotId = fields[1].GetUInt8();
- uint32 ItemGuid = fields[2].GetUInt32();
- uint32 ItemEntry = fields[3].GetUInt32();
+ uint8 TabId = fields[1].GetUInt8();
+ uint8 SlotId = fields[2].GetUInt8();
+ uint32 ItemGuid = fields[3].GetUInt32();
+ uint32 ItemEntry = fields[4].GetUInt32();
if (TabId >= purchased_tabs || TabId >= GUILD_BANK_MAX_TABS)
{
@@ -1246,7 +1248,7 @@ void Guild::LoadGuildBankFromDB()
}
Item *pItem = NewItemOrBag(proto);
- if(!pItem->LoadFromDB(ItemGuid, 0))
+ if(!pItem->LoadFromDB(ItemGuid, 0, result))
{
CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE guildid='%u' AND TabId='%u' AND SlotId='%u'", Id, uint32(TabId), uint32(SlotId));
sLog.outError("Item GUID %u not found in item_instance, deleting from Guild Bank!", ItemGuid);
@@ -1602,7 +1604,21 @@ void Guild::DisplayGuildBankLogs(WorldSession *session, uint8 TabId)
{
data << uint8((*itr)->LogEntry);
data << uint64(MAKE_NEW_GUID((*itr)->PlayerGuid,0,HIGHGUID_PLAYER));
- data << uint32((*itr)->ItemOrMoney);
+ if ((*itr)->LogEntry == GUILD_BANK_LOG_DEPOSIT_MONEY ||
+ (*itr)->LogEntry == GUILD_BANK_LOG_WITHDRAW_MONEY ||
+ (*itr)->LogEntry == GUILD_BANK_LOG_REPAIR_MONEY ||
+ (*itr)->LogEntry == GUILD_BANK_LOG_UNK1 ||
+ (*itr)->LogEntry == GUILD_BANK_LOG_UNK2)
+ {
+ data << uint32((*itr)->ItemOrMoney);
+ }
+ else
+ {
+ data << uint32((*itr)->ItemOrMoney);
+ data << uint32((*itr)->ItemStackCount);
+ if ((*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM || (*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM2)
+ data << uint8((*itr)->DestTabId); // moved tab
+ }
data << uint32(time(NULL)-(*itr)->TimeStamp);
}
session->SendPacket(&data);
@@ -1618,10 +1634,21 @@ void Guild::DisplayGuildBankLogs(WorldSession *session, uint8 TabId)
{
data << uint8((*itr)->LogEntry);
data << uint64(MAKE_NEW_GUID((*itr)->PlayerGuid,0,HIGHGUID_PLAYER));
- data << uint32((*itr)->ItemOrMoney);
- data << uint8((*itr)->ItemStackCount);
- if ((*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM || (*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM2)
- data << uint8((*itr)->DestTabId); // moved tab
+ if ((*itr)->LogEntry == GUILD_BANK_LOG_DEPOSIT_MONEY ||
+ (*itr)->LogEntry == GUILD_BANK_LOG_WITHDRAW_MONEY ||
+ (*itr)->LogEntry == GUILD_BANK_LOG_REPAIR_MONEY ||
+ (*itr)->LogEntry == GUILD_BANK_LOG_UNK1 ||
+ (*itr)->LogEntry == GUILD_BANK_LOG_UNK2)
+ {
+ data << uint32((*itr)->ItemOrMoney);
+ }
+ else
+ {
+ data << uint32((*itr)->ItemOrMoney);
+ data << uint32((*itr)->ItemStackCount);
+ if ((*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM || (*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM2)
+ data << uint8((*itr)->DestTabId); // moved tab
+ }
data << uint32(time(NULL)-(*itr)->TimeStamp);
}
session->SendPacket(&data);
@@ -1703,7 +1730,7 @@ void Guild::AppendDisplayGuildBankSlot( WorldPacket& data, GuildBankTab const *t
// SuffixFactor +4
data << (uint32) pItem->GetItemSuffixFactor();
// +12 // ITEM_FIELD_STACK_COUNT
- data << uint8(pItem->GetCount());
+ data << uint32(pItem->GetCount());
data << uint32(0); // +16 // Unknown value
data << uint8(0); // unknown 2.4.2
if (uint32 Enchant0 = pItem->GetEnchantmentId(PERM_ENCHANTMENT_SLOT))
diff --git a/src/game/Guild.h b/src/game/Guild.h
index 683ff980e3a..a1bd6d2e36f 100644
--- a/src/game/Guild.h
+++ b/src/game/Guild.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -56,7 +56,8 @@ enum GuildRankRights
GR_RIGHT_REPAIR_FROM_GUILD = 0x00020000, // unused in 2.4.x?, Remove money withdraw capacity
GR_RIGHT_WITHDRAW_REPAIR = 0x00040000, // withdraw for repair
GR_RIGHT_WITHDRAW_GOLD = 0x00080000, // withdraw gold
- GR_RIGHT_ALL = 0x000FF1FF
+ GR_RIGHT_CREATE_GUILD_EVENT = 0x00100000, // wotlk
+ GR_RIGHT_ALL = 0x001FF1FF
};
enum Typecommand
@@ -156,6 +157,8 @@ enum GuildBankLogEntries
GUILD_BANK_LOG_WITHDRAW_MONEY = 5,
GUILD_BANK_LOG_REPAIR_MONEY = 6,
GUILD_BANK_LOG_MOVE_ITEM2 = 7,
+ GUILD_BANK_LOG_UNK1 = 8,
+ GUILD_BANK_LOG_UNK2 = 9,
};
enum GuildEventLogEntryTypes
@@ -217,12 +220,12 @@ struct GuildBankTab
struct GuildItemPosCount
{
- GuildItemPosCount(uint8 _slot, uint8 _count) : slot(_slot), count(_count) {}
+ GuildItemPosCount(uint8 _slot, uint32 _count) : slot(_slot), count(_count) {}
bool isContainedIn(std::vector<GuildItemPosCount> const& vec) const;
uint8 slot;
- uint8 count;
+ uint32 count;
};
typedef std::vector<GuildItemPosCount> GuildItemPosCountVec;
diff --git a/src/game/GuildHandler.cpp b/src/game/GuildHandler.cpp
index 4711f2d0902..f1a59814d57 100644
--- a/src/game/GuildHandler.cpp
+++ b/src/game/GuildHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -375,7 +375,7 @@ void WorldSession::HandleGuildDemoteOpcode(WorldPacket& recvPacket)
guild->ChangeRank(plGuid, (slot->RankId+1));
// Put record into guildlog
- guild->LogGuildEvent(GUILD_EVENT_LOG_DEMOTE_PLAYER, GetPlayer()->GetGUIDLow(), GUID_LOPART(plGuid), (slot->RankId));
+ guild->LogGuildEvent(GUILD_EVENT_LOG_DEMOTE_PLAYER, GetPlayer()->GetGUIDLow(), GUID_LOPART(plGuid), slot->RankId);
WorldPacket data(SMSG_GUILD_EVENT, (2+30)); // guess size
data << (uint8)GE_DEMOTION;
diff --git a/src/game/HomeMovementGenerator.cpp b/src/game/HomeMovementGenerator.cpp
index 0f5b9b2543b..4fa3ca6e8bd 100644
--- a/src/game/HomeMovementGenerator.cpp
+++ b/src/game/HomeMovementGenerator.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/HomeMovementGenerator.h b/src/game/HomeMovementGenerator.h
index a116027608f..77e78ca23d3 100644
--- a/src/game/HomeMovementGenerator.h
+++ b/src/game/HomeMovementGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/HostilRefManager.cpp b/src/game/HostilRefManager.cpp
index a2928158a2c..aed4c8d02eb 100644
--- a/src/game/HostilRefManager.cpp
+++ b/src/game/HostilRefManager.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/HostilRefManager.h b/src/game/HostilRefManager.h
index 4d049b234c0..8c4ac623ac0 100644
--- a/src/game/HostilRefManager.h
+++ b/src/game/HostilRefManager.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/IdleMovementGenerator.cpp b/src/game/IdleMovementGenerator.cpp
index 6b68dd8eeed..b8910f555d0 100644
--- a/src/game/IdleMovementGenerator.cpp
+++ b/src/game/IdleMovementGenerator.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/IdleMovementGenerator.h b/src/game/IdleMovementGenerator.h
index 8a8aece5458..19618be8e86 100644
--- a/src/game/IdleMovementGenerator.h
+++ b/src/game/IdleMovementGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/InstanceData.cpp b/src/game/InstanceData.cpp
index c605de2c453..79b1f8bcbb3 100644
--- a/src/game/InstanceData.cpp
+++ b/src/game/InstanceData.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/InstanceData.h b/src/game/InstanceData.h
index 8fea525a6e2..146e955f8fe 100644
--- a/src/game/InstanceData.h
+++ b/src/game/InstanceData.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/InstanceSaveMgr.cpp b/src/game/InstanceSaveMgr.cpp
index cb95dac6978..ad827a07bf2 100644
--- a/src/game/InstanceSaveMgr.cpp
+++ b/src/game/InstanceSaveMgr.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -270,7 +270,7 @@ void InstanceSaveManager::CleanupInstances()
// creature_respawn and gameobject_respawn are in another database
// first, obtain total instance set
- std::set< uint32 > InstanceSet;
+ std::set<uint32> InstanceSet;
QueryResult *result = CharacterDatabase.Query("SELECT id FROM instance");
if( result )
{
@@ -322,7 +322,7 @@ void InstanceSaveManager::PackInstances()
// TODO: this can be done a LOT more efficiently
// obtain set of all associations
- std::set< uint32 > InstanceSet;
+ std::set<uint32> InstanceSet;
// all valid ids are in the instance table
// any associations to ids not in this table are assumed to be
@@ -344,7 +344,7 @@ void InstanceSaveManager::PackInstances()
uint32 InstanceNumber = 1;
// we do assume std::set is sorted properly on integer value
- for (std::set< uint32 >::iterator i = InstanceSet.begin(); i != InstanceSet.end(); ++i)
+ for (std::set<uint32>::iterator i = InstanceSet.begin(); i != InstanceSet.end(); ++i)
{
if (*i != InstanceNumber)
{
@@ -361,8 +361,8 @@ void InstanceSaveManager::PackInstances()
bar.step();
}
- sLog.outString();
sLog.outString( ">> Instance numbers remapped, next instance id is %u", InstanceNumber );
+ sLog.outString();
}
void InstanceSaveManager::LoadResetTimes()
@@ -454,7 +454,7 @@ void InstanceSaveManager::LoadResetTimes()
// add the global reset times to the priority queue
for(uint32 i = 0; i < sInstanceTemplate.MaxEntry; i++)
{
- InstanceTemplate* temp = (InstanceTemplate*)objmgr.GetInstanceTemplate(i);
+ InstanceTemplate const* temp = objmgr.GetInstanceTemplate(i);
if(!temp) continue;
// only raid/heroic maps have a global reset time
const MapEntry* entry = sMapStore.LookupEntry(temp->map);
@@ -583,7 +583,7 @@ void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, bool warn, uint32 timeLe
{
// global reset for all instances of the given map
// note: this isn't fast but it's meant to be executed very rarely
- Map *map = (MapInstanced*)MapManager::Instance().GetBaseMap(mapid);
+ Map const *map = MapManager::Instance().GetBaseMap(mapid);
if(!map->Instanceable())
return;
uint64 now = (uint64)time(NULL);
@@ -591,7 +591,7 @@ void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, bool warn, uint32 timeLe
if(!warn)
{
// this is called one minute before the reset time
- InstanceTemplate* temp = (InstanceTemplate*)objmgr.GetInstanceTemplate(mapid);
+ InstanceTemplate const* temp = objmgr.GetInstanceTemplate(mapid);
if(!temp || !temp->reset_delay)
{
sLog.outError("InstanceSaveManager::ResetOrWarnAll: no instance template or reset delay for map %d", mapid);
diff --git a/src/game/InstanceSaveMgr.h b/src/game/InstanceSaveMgr.h
index 7dcf13aede8..f868f2e8094 100644
--- a/src/game/InstanceSaveMgr.h
+++ b/src/game/InstanceSaveMgr.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/game/Item.cpp b/src/game/Item.cpp
index b0c2109a5b5..e8280711143 100644
--- a/src/game/Item.cpp
+++ b/src/game/Item.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -206,6 +206,10 @@ bool ItemCanGoIntoBag(ItemPrototype const *pProto, ItemPrototype const *pBagProt
if(!(pProto->BagFamily & BAG_FAMILY_MASK_LEATHERWORKING_SUPP))
return false;
return true;
+ case ITEM_SUBCLASS_INSCRIPTION_CONTAINER:
+ if(!(pProto->BagFamily & BAG_FAMILY_MASK_INSCRIPTION_SUPP))
+ return false;
+ return true;
default:
return false;
}
@@ -284,7 +288,7 @@ void Item::UpdateDuration(Player* owner, uint32 diff)
}
SetUInt32Value(ITEM_FIELD_DURATION, GetUInt32Value(ITEM_FIELD_DURATION) - diff);
- SetState(ITEM_CHANGED); // save new time in database
+ SetState(ITEM_CHANGED, owner); // save new time in database
}
void Item::SaveToDB()
@@ -450,7 +454,7 @@ uint32 Item::GetSkill()
const static uint32 item_armor_skills[MAX_ITEM_SUBCLASS_ARMOR] =
{
- 0,SKILL_CLOTH,SKILL_LEATHER,SKILL_MAIL,SKILL_PLATE_MAIL,0,SKILL_SHIELD,0,0,0
+ 0,SKILL_CLOTH,SKILL_LEATHER,SKILL_MAIL,SKILL_PLATE_MAIL,0,SKILL_SHIELD,0,0,0,0
};
ItemPrototype const* proto = GetProto();
@@ -765,9 +769,9 @@ void Item::SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint
if((GetEnchantmentId(slot) == id) && (GetEnchantmentDuration(slot) == duration) && (GetEnchantmentCharges(slot) == charges))
return;
- SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET,id);
- SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET,duration);
- SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET,charges);
+ SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET,id);
+ SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET,duration);
+ SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET,charges);
SetState(ITEM_CHANGED);
}
@@ -776,7 +780,7 @@ void Item::SetEnchantmentDuration(EnchantmentSlot slot, uint32 duration)
if(GetEnchantmentDuration(slot) == duration)
return;
- SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET,duration);
+ SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET,duration);
SetState(ITEM_CHANGED);
}
@@ -785,7 +789,7 @@ void Item::SetEnchantmentCharges(EnchantmentSlot slot, uint32 charges)
if(GetEnchantmentCharges(slot) == charges)
return;
- SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET,charges);
+ SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET,charges);
SetState(ITEM_CHANGED);
}
@@ -795,7 +799,7 @@ void Item::ClearEnchantment(EnchantmentSlot slot)
return;
for(uint8 x = 0; x < 3; ++x)
- SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + x, 0);
+ SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + x, 0);
SetState(ITEM_CHANGED);
}
@@ -886,8 +890,8 @@ Item* Item::CreateItem( uint32 item, uint32 count, Player const* player )
ItemPrototype const *pProto = objmgr.GetItemPrototype( item );
if( pProto )
{
- if ( count > pProto->Stackable )
- count = pProto->Stackable;
+ if ( count > pProto->GetMaxStackSize())
+ count = pProto->GetMaxStackSize();
assert(count !=0 && "pProto->Stackable==0 but checked at loading already");
diff --git a/src/game/Item.h b/src/game/Item.h
index 72c09b0c1da..8869f2ac013 100644
--- a/src/game/Item.h
+++ b/src/game/Item.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -148,29 +148,32 @@ enum SellFailure
// -1 from client enchantment slot number
enum EnchantmentSlot
{
- PERM_ENCHANTMENT_SLOT = 0,
- TEMP_ENCHANTMENT_SLOT = 1,
- SOCK_ENCHANTMENT_SLOT = 2,
- SOCK_ENCHANTMENT_SLOT_2 = 3,
- SOCK_ENCHANTMENT_SLOT_3 = 4,
- BONUS_ENCHANTMENT_SLOT = 5,
- MAX_INSPECTED_ENCHANTMENT_SLOT = 6,
-
- PROP_ENCHANTMENT_SLOT_0 = 6, // used with RandomSuffix
- PROP_ENCHANTMENT_SLOT_1 = 7, // used with RandomSuffix
- PROP_ENCHANTMENT_SLOT_2 = 8, // used with RandomSuffix and RandomProperty
- PROP_ENCHANTMENT_SLOT_3 = 9, // used with RandomProperty
- PROP_ENCHANTMENT_SLOT_4 = 10, // used with RandomProperty
- MAX_ENCHANTMENT_SLOT = 11
+ PERM_ENCHANTMENT_SLOT = 0,
+ TEMP_ENCHANTMENT_SLOT = 1,
+ SOCK_ENCHANTMENT_SLOT = 2,
+ SOCK_ENCHANTMENT_SLOT_2 = 3,
+ 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
};
-#define MAX_VISIBLE_ITEM_OFFSET 16 // 16 fields per visible item (creator(2) + enchantments(12) + properties(1) + pad(1))
+#define MAX_VISIBLE_ITEM_OFFSET 18 // 18 fields per visible item (creator(2) + enchantments(13) + properties(1) + seed(1) + pad(1))
+
+#define MAX_GEM_SOCKETS 3 // (BONUS_ENCHANTMENT_SLOT-SOCK_ENCHANTMENT_SLOT)
enum EnchantmentOffset
{
ENCHANTMENT_ID_OFFSET = 0,
ENCHANTMENT_DURATION_OFFSET = 1,
- ENCHANTMENT_CHARGES_OFFSET = 2
+ ENCHANTMENT_CHARGES_OFFSET = 2 // now here not only charges, but something new in wotlk
};
#define MAX_ENCHANTMENT_OFFSET 3
@@ -211,6 +214,7 @@ class TRINITY_DLL_SPEC Item : public Object
void SetBinding(bool val) { ApplyModFlag(ITEM_FIELD_FLAGS,ITEM_FLAGS_BINDED,val); }
bool IsSoulBound() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_BINDED); }
+ bool IsAccountBound() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_BOA); }
bool IsBindedNotWith(uint64 guid) const { return IsSoulBound() && GetOwnerGUID()!= guid; }
bool IsBoundByEnchant() const;
virtual void SaveToDB();
@@ -230,7 +234,7 @@ class TRINITY_DLL_SPEC Item : public Object
uint32 GetCount() const { return GetUInt32Value (ITEM_FIELD_STACK_COUNT); }
void SetCount(uint32 value) { SetUInt32Value (ITEM_FIELD_STACK_COUNT, value); }
- uint32 GetMaxStackCount() const { return GetProto()->Stackable; }
+ uint32 GetMaxStackCount() const { return GetProto()->GetMaxStackSize(); }
uint8 GetGemCountWithID(uint32 GemID) const;
uint8 GetSlot() const {return m_slot;}
@@ -256,9 +260,9 @@ class TRINITY_DLL_SPEC Item : public Object
void SetEnchantmentDuration(EnchantmentSlot slot, uint32 duration);
void SetEnchantmentCharges(EnchantmentSlot slot, uint32 charges);
void ClearEnchantment(EnchantmentSlot slot);
- uint32 GetEnchantmentId(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET);}
- uint32 GetEnchantmentDuration(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET);}
- uint32 GetEnchantmentCharges(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET);}
+ uint32 GetEnchantmentId(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET);}
+ uint32 GetEnchantmentDuration(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET);}
+ uint32 GetEnchantmentCharges(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET);}
void SendTimeUpdate(Player* owner);
void UpdateDuration(Player* owner, uint32 diff);
diff --git a/src/game/ItemEnchantmentMgr.cpp b/src/game/ItemEnchantmentMgr.cpp
index 52a2e5dc1eb..305e3a64ebc 100644
--- a/src/game/ItemEnchantmentMgr.cpp
+++ b/src/game/ItemEnchantmentMgr.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/ItemEnchantmentMgr.h b/src/game/ItemEnchantmentMgr.h
index 97053c1ec36..0feed4319d5 100644
--- a/src/game/ItemEnchantmentMgr.h
+++ b/src/game/ItemEnchantmentMgr.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/ItemHandler.cpp b/src/game/ItemHandler.cpp
index 085c9553a30..3b3a23acfce 100644
--- a/src/game/ItemHandler.cpp
+++ b/src/game/ItemHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -324,7 +324,7 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data )
data << pProto->ItemId;
data << pProto->Class;
data << pProto->SubClass;
- data << uint32(-1); // new 2.0.3, not exist in wdb cache?
+ data << int32(pProto->Unk0); // new 2.0.3, not exist in wdb cache?
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);
@@ -346,14 +346,17 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data )
data << pProto->RequiredCityRank;
data << pProto->RequiredReputationFaction;
data << pProto->RequiredReputationRank;
- data << pProto->MaxCount;
- data << pProto->Stackable;
+ data << int32(pProto->MaxCount);
+ data << int32(pProto->Stackable);
data << pProto->ContainerSlots;
- for(int i = 0; i < 10; i++)
+ data << pProto->StatsCount; // item stats count
+ for(int 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 < 5; i++)
{
data << pProto->Damage[i].DamageMin;
@@ -417,7 +420,7 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data )
data << pProto->PageMaterial;
data << pProto->StartQuest;
data << pProto->LockID;
- data << pProto->Material;
+ data << int32(pProto->Material);
data << pProto->Sheath;
data << pProto->RandomProperty;
data << pProto->RandomSuffix;
@@ -437,7 +440,8 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data )
data << pProto->GemProperties;
data << pProto->RequiredDisenchantSkill;
data << pProto->ArmorDamageModifier;
- data << uint32(0); // added in 2.4.2.8209, duration (seconds)
+ data << pProto->Duration; // added in 2.4.2.8209, duration (seconds)
+ data << pProto->ItemLimitCategory; // WotLK, ItemLimitCategory
SendPacket( &data );
}
else
@@ -738,7 +742,7 @@ void WorldSession::SendListInventory( uint64 vendorguid )
float discountMod = _player->GetReputationPriceDiscount(pCreature);
- for(int i = 0; i < numitems; i++ )
+ for(int i = 0; i < numitems; ++i )
{
if(VendorItem const* crItem = vItems->GetItem(i))
{
@@ -845,6 +849,7 @@ void WorldSession::HandleBuyBankSlotOpcode(WorldPacket& /*recvPacket*/)
if (_player->GetMoney() < price)
return;
+ _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT, slot);
_player->SetByteValue(PLAYER_BYTES_2, 2, slot);
_player->ModifyMoney(-int32(price));
}
@@ -1106,57 +1111,80 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recv_data)
{
sLog.outDebug("WORLD: CMSG_SOCKET_GEMS");
- CHECK_PACKET_SIZE(recv_data,8*4);
+ CHECK_PACKET_SIZE(recv_data,8+8*MAX_GEM_SOCKETS);
- uint64 guids[4];
- uint32 GemEnchants[3], OldEnchants[3];
- Item *Gems[3];
- bool SocketBonusActivated, SocketBonusToBeActivated;
+ uint64 item_guid;
+ uint64 gem_guids[MAX_GEM_SOCKETS];
- for(int i = 0; i < 4; i++)
- recv_data >> guids[i];
-
- if(!guids[0])
+ recv_data >> item_guid;
+ if(!item_guid)
return;
+ for(int i = 0; i < MAX_GEM_SOCKETS; ++i)
+ recv_data >> gem_guids[i];
+
//cheat -> tried to socket same gem multiple times
- if((guids[1] && (guids[1] == guids[2] || guids[1] == guids[3])) || (guids[2] && (guids[2] == guids[3])))
+ if ((gem_guids[0] && (gem_guids[0] == gem_guids[1] || gem_guids[0] == gem_guids[2])) ||
+ (gem_guids[1] && (gem_guids[1] == gem_guids[2])))
return;
- Item *itemTarget = _player->GetItemByGuid(guids[0]);
+ Item *itemTarget = _player->GetItemByGuid(item_guid);
if(!itemTarget) //missing item to socket
return;
+ ItemPrototype const* itemProto = itemTarget->GetProto();
+ if(!itemProto)
+ return;
+
//this slot is excepted when applying / removing meta gem bonus
uint8 slot = itemTarget->IsEquipped() ? itemTarget->GetSlot() : NULL_SLOT;
- for(int i = 0; i < 3; i++)
- Gems[i] = guids[i + 1] ? _player->GetItemByGuid(guids[i + 1]) : NULL;
+ Item *Gems[MAX_GEM_SOCKETS];
+ for(int i = 0; i < MAX_GEM_SOCKETS; ++i)
+ Gems[i] = gem_guids[i] ? _player->GetItemByGuid(gem_guids[i]) : NULL;
- GemPropertiesEntry const *GemProps[3];
- for(int i = 0; i < 3; ++i) //get geminfo from dbc storage
- {
+ GemPropertiesEntry const *GemProps[MAX_GEM_SOCKETS];
+ for(int i = 0; i < MAX_GEM_SOCKETS; ++i) //get geminfo from dbc storage
GemProps[i] = (Gems[i]) ? sGemPropertiesStore.LookupEntry(Gems[i]->GetProto()->GemProperties) : NULL;
- }
- for(int i = 0; i < 3; ++i) //check for hack maybe
+ for(int i = 0; i < MAX_GEM_SOCKETS; ++i) //check for hack maybe
{
- // tried to put gem in socket where no socket exists / tried to put normal gem in meta socket
+ if (!GemProps[i])
+ continue;
+
+ // tried to put gem in socket where no socket exists (take care about prismatic sockets)
+ if (!itemProto->Socket[i].Color)
+ {
+ // no prismatic socket
+ if(!itemTarget->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT))
+ return;
+
+ // not first not-colored (not normaly used) socket
+ if(i!=0 && !itemProto->Socket[i-1].Color && (i+1 >= MAX_GEM_SOCKETS || itemProto->Socket[i+1].Color))
+ return;
+
+ // ok, this is first not colored socket for item with prismatic socket
+ }
+
+ // tried to put normal gem in meta socket
+ if (itemProto->Socket[i].Color == SOCKET_COLOR_META && GemProps[i]->color != SOCKET_COLOR_META)
+ return;
+
// tried to put meta gem in normal socket
- if( GemProps[i] && ( !itemTarget->GetProto()->Socket[i].Color ||
- itemTarget->GetProto()->Socket[i].Color == SOCKET_COLOR_META && GemProps[i]->color != SOCKET_COLOR_META ||
- itemTarget->GetProto()->Socket[i].Color != SOCKET_COLOR_META && GemProps[i]->color == SOCKET_COLOR_META ) )
+ if (itemProto->Socket[i].Color != SOCKET_COLOR_META && GemProps[i]->color == SOCKET_COLOR_META)
return;
}
- for(int i = 0; i < 3; ++i) //get new and old enchantments
+ uint32 GemEnchants[MAX_GEM_SOCKETS];
+ uint32 OldEnchants[MAX_GEM_SOCKETS];
+ for(int i = 0; i < MAX_GEM_SOCKETS; ++i) //get new and old enchantments
{
GemEnchants[i] = (GemProps[i]) ? GemProps[i]->spellitemenchantement : 0;
OldEnchants[i] = itemTarget->GetEnchantmentId(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+i));
}
// check unique-equipped conditions
- for(int i = 0; i < 3; ++i)
+ for(int i = 0; i < MAX_GEM_SOCKETS; ++i)
{
if (Gems[i] && (Gems[i]->GetProto()->Flags & ITEM_FLAGS_UNIQUE_EQUIPPED))
{
@@ -1171,7 +1199,7 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recv_data)
}
// continue check for case when attempt add 2 similar unique equipped gems in one item.
- for (int j = 0; j < 3; ++j)
+ for (int j = 0; j < MAX_GEM_SOCKETS; ++j)
{
if ((i != j) && (Gems[j]) && (Gems[i]->GetProto()->ItemId == Gems[j]->GetProto()->ItemId))
{
@@ -1179,7 +1207,7 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recv_data)
return;
}
}
- for (int j = 0; j < 3; ++j)
+ for (int j = 0; j < MAX_GEM_SOCKETS; ++j)
{
if (OldEnchants[j])
{
@@ -1197,29 +1225,29 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recv_data)
}
}
- SocketBonusActivated = itemTarget->GemsFitSockets(); //save state of socketbonus
+ bool SocketBonusActivated = itemTarget->GemsFitSockets(); //save state of socketbonus
_player->ToggleMetaGemsActive(slot, false); //turn off all metagems (except for the target item)
//if a meta gem is being equipped, all information has to be written to the item before testing if the conditions for the gem are met
//remove ALL enchants
- for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot)
+ for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot)
_player->ApplyEnchantment(itemTarget,EnchantmentSlot(enchant_slot),false);
- for(int i = 0; i < 3; ++i)
+ for(int i = 0; i < MAX_GEM_SOCKETS; ++i)
{
if(GemEnchants[i])
{
itemTarget->SetEnchantment(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+i), GemEnchants[i],0,0);
- if(Item* guidItem = _player->GetItemByGuid(guids[i + 1]))
+ if(Item* guidItem = _player->GetItemByGuid(gem_guids[i]))
_player->DestroyItem(guidItem->GetBagSlot(), guidItem->GetSlot(), true );
}
}
- for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot)
+ for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot)
_player->ApplyEnchantment(itemTarget,EnchantmentSlot(enchant_slot),true);
- SocketBonusToBeActivated = itemTarget->GemsFitSockets();//current socketbonus state
+ bool SocketBonusToBeActivated = itemTarget->GemsFitSockets();//current socketbonus state
if(SocketBonusActivated ^ SocketBonusToBeActivated) //if there was a change...
{
_player->ApplyEnchantment(itemTarget,BONUS_ENCHANTMENT_SLOT,false);
diff --git a/src/game/ItemPrototype.h b/src/game/ItemPrototype.h
index 1ca412d246a..c23c0d5978c 100644
--- a/src/game/ItemPrototype.h
+++ b/src/game/ItemPrototype.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -57,10 +57,18 @@ enum ItemModType
ITEM_MOD_CRIT_TAKEN_RATING = 34,
ITEM_MOD_RESILIENCE_RATING = 35,
ITEM_MOD_HASTE_RATING = 36,
- ITEM_MOD_EXPERTISE_RATING = 37
+ ITEM_MOD_EXPERTISE_RATING = 37,
+ ITEM_MOD_ATTACK_POWER = 38,
+ ITEM_MOD_RANGED_ATTACK_POWER = 39,
+ ITEM_MOD_FERAL_ATTACK_POWER = 40,
+ ITEM_MOD_SPELL_HEALING_DONE = 41,
+ ITEM_MOD_SPELL_DAMAGE_DONE = 42,
+ ITEM_MOD_MANA_REGENERATION = 43,
+ ITEM_MOD_ARMOR_PENETRATION_RATING = 44,
+ ITEM_MOD_SPELL_POWER = 45
};
-#define MAX_ITEM_MOD 38
+#define MAX_ITEM_MOD 46
enum ItemSpelltriggerType
{
@@ -68,6 +76,12 @@ enum ItemSpelltriggerType
ITEM_SPELLTRIGGER_ON_EQUIP = 1,
ITEM_SPELLTRIGGER_CHANCE_ON_HIT = 2,
ITEM_SPELLTRIGGER_SOULSTONE = 4,
+ /*
+ * ItemSpelltriggerType 5 might have changed on 2.4.3/3.0.3: Such auras
+ * will be applied on item pickup and removed on item loss - maybe on the
+ * other hand the item is destroyed if the aura is removed ("removed on
+ * death" of spell 57348 makes me think so)
+ */
ITEM_SPELLTRIGGER_ON_NO_DELAY_USE = 5, // no equip cooldown
ITEM_SPELLTRIGGER_LEARN_SPELL_ID = 6 // used in item_template.spell_2 with spell_id with SPELL_GENERIC_LEARN in spell_1
};
@@ -96,6 +110,7 @@ enum ITEM_FLAGS
ITEM_FLAGS_WRAPPER = 0x00000200, // used or not used wrapper
ITEM_FLAGS_PARTY_LOOT = 0x00000800, // determines if item is party loot or not
ITEM_FLAGS_CHARTER = 0x00002000, // arena/guild charter
+ ITEM_FLAGS_PROSPECTABLE = 0x00040000,
ITEM_FLAGS_UNIQUE_EQUIPPED = 0x00080000,
ITEM_FLAGS_USEABLE_IN_ARENA = 0x00200000,
ITEM_FLAGS_THROWABLE = 0x00400000, // not used in game for check trow possibility, only for item in game tooltip
@@ -185,10 +200,11 @@ enum ItemClass
ITEM_CLASS_QUEST = 12,
ITEM_CLASS_KEY = 13,
ITEM_CLASS_PERMANENT = 14,
- ITEM_CLASS_JUNK = 15
+ ITEM_CLASS_MISC = 15,
+ ITEM_CLASS_GLYPH = 16
};
-#define MAX_ITEM_CLASS 16
+#define MAX_ITEM_CLASS 17
enum ItemSubclassConsumable
{
@@ -214,10 +230,11 @@ enum ItemSubclassContainer
ITEM_SUBCLASS_ENGINEERING_CONTAINER = 4,
ITEM_SUBCLASS_GEM_CONTAINER = 5,
ITEM_SUBCLASS_MINING_CONTAINER = 6,
- ITEM_SUBCLASS_LEATHERWORKING_CONTAINER = 7
+ ITEM_SUBCLASS_LEATHERWORKING_CONTAINER = 7,
+ ITEM_SUBCLASS_INSCRIPTION_CONTAINER = 8
};
-#define MAX_ITEM_SUBCLASS_CONTAINER 8
+#define MAX_ITEM_SUBCLASS_CONTAINER 9
enum ItemSubclassWeapon
{
@@ -272,10 +289,11 @@ enum ItemSubclassArmor
ITEM_SUBCLASS_ARMOR_SHIELD = 6,
ITEM_SUBCLASS_ARMOR_LIBRAM = 7,
ITEM_SUBCLASS_ARMOR_IDOL = 8,
- ITEM_SUBCLASS_ARMOR_TOTEM = 9
+ ITEM_SUBCLASS_ARMOR_TOTEM = 9,
+ ITEM_SUBCLASS_ARMOR_SIGIL = 10
};
-#define MAX_ITEM_SUBCLASS_ARMOR 10
+#define MAX_ITEM_SUBCLASS_ARMOR 11
enum ItemSubclassReagent
{
@@ -310,10 +328,12 @@ enum ItemSubclassTradeGoods
ITEM_SUBCLASS_ELEMENTAL = 10,
ITEM_SUBCLASS_TRADE_GOODS_OTHER = 11,
ITEM_SUBCLASS_ENCHANTING = 12,
- ITEM_SUBCLASS_MATERIAL = 13 // Added in 2.4.2
+ ITEM_SUBCLASS_MATERIAL = 13,
+ ITEM_SUBCLASS_ARMOR_ENCHANTMENT = 14,
+ ITEM_SUBCLASS_WEAPON_ENCHANTMENT = 15
};
-#define MAX_ITEM_SUBCLASS_TRADE_GOODS 14
+#define MAX_ITEM_SUBCLASS_TRADE_GOODS 16
enum ItemSubclassGeneric
{
@@ -423,7 +443,8 @@ const uint32 MaxItemSubclassValues[MAX_ITEM_CLASS] =
MAX_ITEM_SUBCLASS_QUEST,
MAX_ITEM_SUBCLASS_KEY,
MAX_ITEM_SUBCLASS_PERMANENT,
- MAX_ITEM_SUBCLASS_JUNK
+ MAX_ITEM_SUBCLASS_JUNK,
+ MAX_ITEM_SUBCLASS_GLYPH
};
inline uint8 ItemSubClassToDurabilityMultiplierId(uint32 ItemClass, uint32 ItemSubClass)
@@ -477,7 +498,7 @@ struct ItemPrototype
uint32 ItemId;
uint32 Class; // id from ItemClass.dbc
uint32 SubClass; // id from ItemSubClass.dbc
- uint32 Unk0;
+ int32 Unk0;
char* Name1;
uint32 DisplayInfoID; // id from ItemDisplayInfo.dbc
uint32 Quality;
@@ -497,10 +518,13 @@ struct ItemPrototype
uint32 RequiredCityRank;
uint32 RequiredReputationFaction; // id from Faction.dbc
uint32 RequiredReputationRank;
- uint32 MaxCount;
- uint32 Stackable;
+ 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[10];
+ uint32 ScalingStatDistribution; // id from ScalingStatDistribution.dbc
+ uint32 ScalingStatValue; // mask for selecting column in ScalingStatValues.dbc
_Damage Damage[5];
uint32 Armor;
uint32 HolyRes;
@@ -520,7 +544,7 @@ struct ItemPrototype
uint32 PageMaterial;
uint32 StartQuest; // id from QuestCache.wdb
uint32 LockID;
- uint32 Material; // id from Material.dbc
+ int32 Material; // id from Material.dbc
uint32 Sheath;
uint32 RandomProperty; // id from ItemRandomProperties.dbc
uint32 RandomSuffix; // id from ItemRandomSuffix.dbc
@@ -536,12 +560,13 @@ struct ItemPrototype
uint32 GemProperties; // id from GemProperties.dbc
uint32 RequiredDisenchantSkill;
float ArmorDamageModifier;
+ int32 Duration; // negative = realtime, positive = ingame time
+ uint32 ItemLimitCategory; // id from ItemLimitCategory.dbc
uint32 ScriptId;
uint32 DisenchantID;
uint32 FoodType;
uint32 MinMoneyLoot;
uint32 MaxMoneyLoot;
- int32 Duration; // negative = realtime, positive = ingame time
// helpers
bool CanChangeEquipStateInCombat() const
@@ -563,6 +588,71 @@ struct ItemPrototype
return false;
}
+
+ uint32 GetScalingStatValuesColumn() const
+ {
+ if(ScalingStatValue & 0x00000001) // stat mod
+ return 0;
+ if(ScalingStatValue & 0x00000002) // stat mod
+ return 1;
+ if(ScalingStatValue & 0x00000004) // stat mod
+ return 2;
+ if(ScalingStatValue & 0x00000008) // stat mod
+ return 3;
+ if(ScalingStatValue & 0x00000010) // stat mod
+ return 4;
+ if(ScalingStatValue & 0x00000020) // armor mod
+ return 5;
+ if(ScalingStatValue & 0x00000040) // armor mod
+ return 6;
+ if(ScalingStatValue & 0x00000080) // armor mod
+ return 7;
+ if(ScalingStatValue & 0x00000100) // armor mod
+ return 8;
+ if(ScalingStatValue & 0x00000200) // damage mod
+ return 9;
+ if(ScalingStatValue & 0x00000400) // damage mod
+ return 10;
+ if(ScalingStatValue & 0x00000800) // damage mod
+ return 11;
+ if(ScalingStatValue & 0x00001000) // damage mod
+ return 12;
+ if(ScalingStatValue & 0x00002000) // damage mod
+ return 13;
+ if(ScalingStatValue & 0x00004000) // damage mod
+ return 14;
+ if(ScalingStatValue & 0x00008000) // spell power
+ return 15;
+ if(ScalingStatValue & 0x00020000) // feral AP
+ return 16;
+
+ return 0;
+ }
+
+ uint32 GetMaxStackSize() const { return Stackable > 0 ? uint32(Stackable) : uint32(0x7FFFFFFF-1); }
+
+ float getDPS() const
+ {
+ if (Delay == 0)
+ return 0;
+ float temp = 0;
+ for (int i=0;i<5;++i)
+ temp+=Damage[i].DamageMin + Damage[i].DamageMax;
+ return temp*500/Delay;
+ }
+
+ int32 getFeralBonus() const
+ {
+ // 0x02A5F3 - is mask for Melee weapon from ItemSubClassMask.dbc
+ if (Class == ITEM_CLASS_WEAPON && (1<<SubClass)&0x02A5F3)
+ {
+ int32 bonus = int32(getDPS()*14.0f) - 767;
+ if (bonus < 0)
+ return 0;
+ return bonus;
+ }
+ return 0;
+ }
};
struct ItemLocale
diff --git a/src/game/LFGHandler.cpp b/src/game/LFGHandler.cpp
index a3379c4d79b..182e89a42c5 100644
--- a/src/game/LFGHandler.cpp
+++ b/src/game/LFGHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/Language.h b/src/game/Language.h
index 590c21e715b..72b30b1448f 100644
--- a/src/game/Language.h
+++ b/src/game/Language.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -170,7 +170,9 @@ enum TrinityStrings
LANG_SOUND_NOT_EXIST = 170,
LANG_TELEPORTED_TO_BY_CONSOLE = 171,
LANG_CONSOLE_COMMAND = 172,
- // Room for more level 1 173-199 not used
+ LANG_YOU_CHANGE_RUNIC_POWER = 173,
+ LANG_YOURS_RUNIC_POWER_CHANGED = 174,
+ // Room for more level 1 175-199 not used
// level 2 chat
LANG_NO_SELECTION = 200,
@@ -322,6 +324,8 @@ enum TrinityStrings
LANG_CREATURE_NOT_FOLLOW_YOU_NOW = 342,
LANG_CREATURE_NON_TAMEABLE = 343,
LANG_YOU_ALREADY_HAVE_PET = 344,
+ LANG_CUSTOMIZE_PLAYER = 345,
+ LANG_CUSTOMIZE_PLAYER_GUID = 346,
// Room for more level 2 345-399 not used
// level 3 chat
@@ -636,12 +640,44 @@ enum TrinityStrings
LANG_BG_QUEUE_ANNOUNCE_SELF = 711,
LANG_BG_QUEUE_ANNOUNCE_WORLD = 712,
-
-
LANG_YOUR_ARENA_LEVEL_REQ_ERROR = 713,
-// LANG_HIS_ARENA_LEVEL_REQ_ERROR = 714, an opcode exists for this
+// = 714, not used
LANG_YOUR_BG_LEVEL_REQ_ERROR = 715,
+
// LANG_YOUR_ARENA_TEAM_FULL = 716, an opcode exists for this
+ LANG_BG_STARTED_ANNOUNCE_WORLD = 717,
+ LANG_ARENA_QUEUE_ANNOUNCE_WORLD_JOIN= 718,
+ LANG_ARENA_QUEUE_ANNOUNCE_WORLD_EXIT= 719,
+
+ LANG_BG_GROUP_TOO_LARGE = 720, // "Your group is too large for this battleground. Please regroup to join."
+ LANG_ARENA_GROUP_TOO_LARGE = 721, // "Your group is too large for this arena. Please regroup to join."
+ LANG_ARENA_YOUR_TEAM_ONLY = 722, // "Your group has members not in your arena team. Please regroup to join."
+ LANG_ARENA_NOT_ENOUGH_PLAYERS = 723, // "Your group does not have enough players to join this match."
+ LANG_ARENA_GOLD_WINS = 724, // "The Gold Team wins!"
+ LANG_ARENA_GREEN_WINS = 725, // "The Green Team wins!"
+ LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING = 726, // The battleground will end soon, because there aren't enough players. Get more ppl or win already!
+ LANG_BG_GROUP_OFFLINE_MEMBER = 727, // "Your group has an offline member. Please remove him before joining."
+ LANG_BG_GROUP_MIXED_FACTION = 728, // "Your group has players from the opposing faction. You can't join the battleground as a group."
+ LANG_BG_GROUP_MIXED_LEVELS = 729, // "Your group has players from different battleground brakets. You can't join as group."
+ LANG_BG_GROUP_MEMBER_ALREADY_IN_QUEUE = 730, // "Someone in your party is already in this battleground queue. (S)he must leave it before joining as group."
+ LANG_BG_GROUP_MEMBER_DESERTER = 731, // "Someone in your party is Deserter. You can't join as group."
+ LANG_BG_GROUP_MEMBER_NO_FREE_QUEUE_SLOTS = 732, // "Someone in your party is already in three battleground queues. You cannot join as group."
+
+ LANG_CANNOT_TELE_TO_BG = 733, // "You cannot teleport to a battleground or arena map."
+ LANG_CANNOT_SUMMON_TO_BG = 734, // "You cannot summon players to a battleground or arena map."
+ LANG_CANNOT_GO_TO_BG_GM = 735, // "You must be in GM mode to teleport to a player in a battleground."
+ LANG_CANNOT_GO_TO_BG_FROM_BG = 736, // "You cannot teleport to a battleground from another battleground. Please leave the current battleground first."
+ LANG_DEBUG_ARENA_ON = 737,
+ 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,
+ // Room for batleground/arena strings 747-799 not used
LANG_BG_AV_ALLY = 717,
LANG_BG_AV_HORDE = 718,
@@ -687,25 +723,6 @@ enum TrinityStrings
LANG_AUTO_ANN = 786,
LANG_ANNOUNCE_COLOR = 787,
- LANG_BG_GROUP_TOO_LARGE = 1122, // "Your group is too large for this battleground. Please regroup to join."
- LANG_ARENA_GROUP_TOO_LARGE = 1123, // "Your group is too large for this arena. Please regroup to join."
- LANG_ARENA_YOUR_TEAM_ONLY = 1124, // "Your group has members not in your arena team. Please regroup to join."
- LANG_ARENA_NOT_ENOUGH_PLAYERS = 1125, // "Your group does not have enough players to join this match."
- LANG_ARENA_GOLD_WINS = 1126, // "The Gold Team wins!"
- LANG_ARENA_GREEN_WINS = 1127, // "The Green Team wins!"
- LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING = 1128, // The battleground will end soon, because there aren't enough players. Get more ppl or win already!
- LANG_BG_GROUP_OFFLINE_MEMBER = 1129, // "Your group has an offline member. Please remove him before joining."
- LANG_BG_GROUP_MIXED_FACTION = 1130, // "Your group has players from the opposing faction. You can't join the battleground as a group."
- LANG_BG_GROUP_MIXED_LEVELS = 1131, // "Your group has players from different battleground brakets. You can't join as group."
- LANG_BG_GROUP_MEMBER_ALREADY_IN_QUEUE = 1132, // "Someone in your party is already in this battleground queue. (S)he must leave it before joining as group."
- LANG_BG_GROUP_MEMBER_DESERTER = 1133, // "Someone in your party is Deserter. You can't join as group."
- LANG_BG_GROUP_MEMBER_NO_FREE_QUEUE_SLOTS = 1134, // "Someone in your party is already in three battleground queues. You cannot join as group."
-
- LANG_CANNOT_TELE_TO_BG = 1135, // "You cannot teleport to a battleground or arena map."
- LANG_CANNOT_SUMMON_TO_BG = 1136, // "You cannot summon players to a battleground or arena map."
- LANG_CANNOT_GO_TO_BG_GM = 1137, // "You must be in GM mode to teleport to a player in a battleground."
- LANG_CANNOT_GO_TO_BG_FROM_BG = 1138, // "You cannot teleport to a battleground from another battleground. Please leave the current battleground first."
-
// in game strings
LANG_PET_INVALID_NAME = 800,
LANG_NOT_ENOUGH_GOLD = 801,
@@ -757,6 +774,29 @@ enum TrinityStrings
LANG_MUST_MALE_OR_FEMALE = 1119,
LANG_YOU_CHANGE_GENDER = 1120,
LANG_YOUR_GENDER_CHANGED = 1121,
+ LANG_SKILL_VALUES = 1122,
+ // Room for more level 3 1123-1199 not used
+
+ /*LANG_BG_GROUP_TOO_LARGE = 1122, // "Your group is too large for this battleground. Please regroup to join."
+ LANG_ARENA_GROUP_TOO_LARGE = 1123, // "Your group is too large for this arena. Please regroup to join."
+ LANG_ARENA_YOUR_TEAM_ONLY = 1124, // "Your group has members not in your arena team. Please regroup to join."
+ LANG_ARENA_NOT_ENOUGH_PLAYERS = 1125, // "Your group does not have enough players to join this match."
+ LANG_ARENA_GOLD_WINS = 1126, // "The Gold Team wins!"
+ LANG_ARENA_GREEN_WINS = 1127, // "The Green Team wins!"
+ LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING = 1128, // The battleground will end soon, because there aren't enough players. Get more ppl or win already!
+ LANG_BG_GROUP_OFFLINE_MEMBER = 1129, // "Your group has an offline member. Please remove him before joining."
+ LANG_BG_GROUP_MIXED_FACTION = 1130, // "Your group has players from the opposing faction. You can't join the battleground as a group."
+ LANG_BG_GROUP_MIXED_LEVELS = 1131, // "Your group has players from different battleground brakets. You can't join as group."
+ LANG_BG_GROUP_MEMBER_ALREADY_IN_QUEUE = 1132, // "Someone in your party is already in this battleground queue. (S)he must leave it before joining as group."
+ LANG_BG_GROUP_MEMBER_DESERTER = 1133, // "Someone in your party is Deserter. You can't join as group."
+ LANG_BG_GROUP_MEMBER_NO_FREE_QUEUE_SLOTS = 1134, // "Someone in your party is already in three battleground queues. You cannot join as group."
+
+ LANG_CANNOT_TELE_TO_BG = 1135, // "You cannot teleport to a battleground or arena map."
+ LANG_CANNOT_SUMMON_TO_BG = 1136, // "You cannot summon players to a battleground or arena map."
+ LANG_CANNOT_GO_TO_BG_GM = 1137, // "You must be in GM mode to teleport to a player in a battleground."
+ LANG_CANNOT_GO_TO_BG_FROM_BG = 1138, // "You cannot teleport to a battleground from another battleground. Please leave the current battleground first."*/
+
+ // FREE IDS 1200-9999
// Ticket Strings 2000-2029
LANG_COMMAND_TICKETNEW = 2000,
diff --git a/src/game/Level0.cpp b/src/game/Level0.cpp
index bd40ee431ac..d02671c724e 100644
--- a/src/game/Level0.cpp
+++ b/src/game/Level0.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -172,7 +172,7 @@ bool ChatHandler::HandleGMListIngameCommand(const char* /*args*/)
first = false;
}
- SendSysMessage(itr->second->GetName());
+ SendSysMessage(GetNameLink(itr->second).c_str());
}
}
diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp
index 5ee72a786d9..8bf4e52a2d4 100644
--- a/src/game/Level1.cpp
+++ b/src/game/Level1.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -115,6 +115,10 @@ bool ChatHandler::HandleNpcWhisperCommand(const char* args)
uint64 receiver_guid= atol(receiver_str);
+ // check online security
+ if (HasLowerSecurity(objmgr.GetPlayer(receiver_guid), 0))
+ return false;
+
pCreature->Whisper(text,receiver_guid);
return true;
@@ -125,8 +129,7 @@ bool ChatHandler::HandleNameAnnounceCommand(const char* args)
WorldPacket data;
if(!*args)
return false;
- //char str[1024];
- //sprintf(str, GetTrinityString(LANG_ANNOUNCE_COLOR), m_session->GetPlayer()->GetName(), args);
+
sWorld.SendWorldText(LANG_ANNOUNCE_COLOR, m_session->GetPlayer()->GetName(), args);
return true;
}
@@ -650,14 +653,16 @@ bool ChatHandler::HandleVisibleCommand(const char* args)
return false;
}
+
+
bool ChatHandler::HandleGPSCommand(const char* args)
{
WorldObject *obj = NULL;
if (*args)
{
- std::string name = args;
- if(normalizePlayerName(name))
- obj = objmgr.GetPlayer(name.c_str());
+ uint64 guid = extractGuidFromLink((char*)args);
+ if(guid)
+ obj = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*m_session->GetPlayer(),guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
if(!obj)
{
@@ -708,18 +713,20 @@ bool ChatHandler::HandleGPSCommand(const char* args)
obj->GetMapId(), (mapEntry ? mapEntry->name[m_session->GetSessionDbcLocale()] : "<unknown>" ),
zone_id, (zoneEntry ? zoneEntry->area_name[m_session->GetSessionDbcLocale()] : "<unknown>" ),
area_id, (areaEntry ? areaEntry->area_name[m_session->GetSessionDbcLocale()] : "<unknown>" ),
+ obj->GetPhaseMask(),
obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), obj->GetOrientation(),
cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), obj->GetInstanceId(),
zone_x, zone_y, ground_z, floor_z, have_map, have_vmap );
sLog.outDebug("Player %s GPS call for %s '%s' (%s: %u):",
- GetName(),
+ m_session ? GetNameLink().c_str() : GetMangosString(LANG_CONSOLE_COMMAND),
(obj->GetTypeId() == TYPEID_PLAYER ? "player" : "creature"), obj->GetName(),
(obj->GetTypeId() == TYPEID_PLAYER ? "GUID" : "Entry"), (obj->GetTypeId() == TYPEID_PLAYER ? obj->GetGUIDLow(): obj->GetEntry()) );
sLog.outDebug(GetTrinityString(LANG_MAP_POSITION),
obj->GetMapId(), (mapEntry ? mapEntry->name[sWorld.GetDefaultDbcLocale()] : "<unknown>" ),
zone_id, (zoneEntry ? zoneEntry->area_name[sWorld.GetDefaultDbcLocale()] : "<unknown>" ),
area_id, (areaEntry ? areaEntry->area_name[sWorld.GetDefaultDbcLocale()] : "<unknown>" ),
+ obj->GetPhaseMask(),
obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), obj->GetOrientation(),
cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), obj->GetInstanceId(),
zone_x, zone_y, ground_z, floor_z, have_map, have_vmap );
@@ -733,9 +740,8 @@ bool ChatHandler::HandleNamegoCommand(const char* args)
if(!*args)
return false;
- std::string name = args;
-
- if(!normalizePlayerName(name))
+ std::string name = extractPlayerNameFromLink((char*)args);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -745,9 +751,14 @@ bool ChatHandler::HandleNamegoCommand(const char* args)
Player *chr = objmgr.GetPlayer(name.c_str());
if (chr)
{
+ std::string nameLink = playerLink(name);
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
if(chr->IsBeingTeleported()==true)
{
- PSendSysMessage(LANG_IS_TELEPORTED, chr->GetName());
+ PSendSysMessage(LANG_IS_TELEPORTED, nameLink.c_str());
SetSentErrorMessage(true);
return false;
}
@@ -756,10 +767,25 @@ bool ChatHandler::HandleNamegoCommand(const char* args)
if(pMap->IsBattleGroundOrArena())
{
- // cannot summon to bg
- PSendSysMessage(LANG_CANNOT_SUMMON_TO_BG,chr->GetName());
- SetSentErrorMessage(true);
- return false;
+ // only allow if gm mode is on
+ if (!chr->isGameMaster())
+ {
+ PSendSysMessage(LANG_CANNOT_GO_TO_BG_GM,chr->GetName());
+ SetSentErrorMessage(true);
+ return false;
+ }
+ // if both players are in different bgs
+ else if (chr->GetBattleGroundId() && m_session->GetPlayer()->GetBattleGroundId() != chr->GetBattleGroundId())
+ {
+ PSendSysMessage(LANG_CANNOT_GO_TO_BG_FROM_BG,chr->GetName());
+ SetSentErrorMessage(true);
+ return false;
+ }
+ // all's well, set bg id
+ // when porting out from the bg, it will be reset to 0
+ chr->SetBattleGroundId(m_session->GetPlayer()->GetBattleGroundId());
+ // remember current position as entry point for return at bg end teleportation
+ chr->SetBattleGroundEntryPoint(chr->GetMapId(),chr->GetPositionX(),chr->GetPositionY(),chr->GetPositionZ(),chr->GetOrientation());
}
else if(pMap->IsDungeon())
{
@@ -767,7 +793,7 @@ bool ChatHandler::HandleNamegoCommand(const char* args)
if( cMap->Instanceable() && cMap->GetInstanceId() != pMap->GetInstanceId() )
{
// cannot summon from instance to instance
- PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST,chr->GetName());
+ PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST,nameLink.c_str());
SetSentErrorMessage(true);
return false;
}
@@ -778,15 +804,15 @@ bool ChatHandler::HandleNamegoCommand(const char* args)
(m_session->GetPlayer()->GetGroup()->GetLeaderGUID() != m_session->GetPlayer()->GetGUID()) )
// the last check is a bit excessive, but let it be, just in case
{
- PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST,chr->GetName());
+ PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST,nameLink.c_str());
SetSentErrorMessage(true);
return false;
}
}
- PSendSysMessage(LANG_SUMMONING, chr->GetName(),"");
+ PSendSysMessage(LANG_SUMMONING, nameLink.c_str(),"");
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_SUMMONED_BY, GetName());
+ ChatHandler(chr).PSendSysMessage(LANG_SUMMONED_BY, nameLink.c_str());
// stop flight if need
if(chr->isInFlight())
@@ -805,7 +831,13 @@ bool ChatHandler::HandleNamegoCommand(const char* args)
}
else if (uint64 guid = objmgr.GetPlayerGUIDByName(name))
{
- PSendSysMessage(LANG_SUMMONING, name.c_str(),GetTrinityString(LANG_OFFLINE));
+ // check offline security
+ if (HasLowerSecurity(NULL, guid))
+ return false;
+
+ std::string nameLink = playerLink(name);
+
+ PSendSysMessage(LANG_SUMMONING, nameLink.c_str(),GetMangosString(LANG_OFFLINE));
// in point where GM stay
Player::SavePositionInDB(m_session->GetPlayer()->GetMapId(),
@@ -833,9 +865,8 @@ bool ChatHandler::HandleGonameCommand(const char* args)
Player* _player = m_session->GetPlayer();
- std::string name = args;
-
- if(!normalizePlayerName(name))
+ std::string name = extractPlayerNameFromLink((char*)args);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -845,28 +876,36 @@ bool ChatHandler::HandleGonameCommand(const char* args)
Player *chr = objmgr.GetPlayer(name.c_str());
if (chr)
{
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ std::string chrNameLink = playerLink(name);
+
Map* cMap = chr->GetMap();
if(cMap->IsBattleGroundOrArena())
{
// only allow if gm mode is on
if (!_player->isGameMaster())
{
- PSendSysMessage(LANG_CANNOT_GO_TO_BG_GM,chr->GetName());
+ PSendSysMessage(LANG_CANNOT_GO_TO_BG_GM,chrNameLink.c_str());
SetSentErrorMessage(true);
return false;
}
- // if already in a bg, don't let port to other
- else if (_player->GetBattleGroundId())
+ // if both players are in different bgs
+ else if (_player->GetBattleGroundId() && _player->GetBattleGroundId() != chr->GetBattleGroundId())
{
- PSendSysMessage(LANG_CANNOT_GO_TO_BG_FROM_BG,chr->GetName());
+ PSendSysMessage(LANG_CANNOT_GO_TO_BG_FROM_BG,chrNameLink.c_str());
SetSentErrorMessage(true);
return false;
}
// all's well, set bg id
// when porting out from the bg, it will be reset to 0
_player->SetBattleGroundId(chr->GetBattleGroundId());
+ // remember current position as entry point for return at bg end teleportation
+ _player->SetBattleGroundEntryPoint(_player->GetMapId(),_player->GetPositionX(),_player->GetPositionY(),_player->GetPositionZ(),_player->GetOrientation());
}
- else if(cMap->IsDungeon())
+ else if(cMap->IsDungeon() && cMap->Instanceable())
{
Map* pMap = MapManager::Instance().GetMap(_player->GetMapId(),_player);
@@ -878,7 +917,7 @@ bool ChatHandler::HandleGonameCommand(const char* args)
// we are in group, we can go only if we are in the player group
if (_player->GetGroup() != chr->GetGroup())
{
- PSendSysMessage(LANG_CANNOT_GO_TO_INST_PARTY,chr->GetName());
+ PSendSysMessage(LANG_CANNOT_GO_TO_INST_PARTY,chrNameLink.c_str());
SetSentErrorMessage(true);
return false;
}
@@ -888,7 +927,7 @@ bool ChatHandler::HandleGonameCommand(const char* args)
// we are not in group, let's verify our GM mode
if (!_player->isGameMaster())
{
- PSendSysMessage(LANG_CANNOT_GO_TO_INST_GM,chr->GetName());
+ PSendSysMessage(LANG_CANNOT_GO_TO_INST_GM,chrNameLink.c_str());
SetSentErrorMessage(true);
return false;
}
@@ -912,10 +951,9 @@ bool ChatHandler::HandleGonameCommand(const char* args)
_player->SetDifficulty(chr->GetDifficulty());
}
- PSendSysMessage(LANG_APPEARING_AT, chr->GetName());
-
+ PSendSysMessage(LANG_APPEARING_AT, chrNameLink.c_str());
if (_player->IsVisibleGloballyFor(chr))
- ChatHandler(chr).PSendSysMessage(LANG_APPEARING_TO, _player->GetName());
+ ChatHandler(chr).PSendSysMessage(LANG_APPEARING_TO, GetNameLink().c_str());
// stop flight if need
if(_player->isInFlight())
@@ -938,7 +976,13 @@ bool ChatHandler::HandleGonameCommand(const char* args)
if (uint64 guid = objmgr.GetPlayerGUIDByName(name))
{
- PSendSysMessage(LANG_APPEARING_AT, name.c_str());
+ // check offline security
+ if (HasLowerSecurity(NULL, guid))
+ return false;
+
+ std::string nameLink = playerLink(name);
+
+ PSendSysMessage(LANG_APPEARING_AT, nameLink.c_str());
// to point where player stay (if loaded)
float x,y,z,o;
@@ -977,12 +1021,15 @@ bool ChatHandler::HandleRecallCommand(const char* args)
chr = getSelectedPlayer();
if(!chr)
chr = m_session->GetPlayer();
+
+ // check online security
+ else if (HasLowerSecurity(chr, 0))
+ return false;
}
else
{
- std::string name = args;
-
- if(!normalizePlayerName(name))
+ std::string name = extractPlayerNameFromLink((char*)args);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -997,11 +1044,15 @@ bool ChatHandler::HandleRecallCommand(const char* args)
SetSentErrorMessage(true);
return false;
}
+
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
}
if(chr->IsBeingTeleported())
{
- PSendSysMessage(LANG_IS_TELEPORTED, chr->GetName());
+ PSendSysMessage(LANG_IS_TELEPORTED, GetNameLink(chr).c_str());
SetSentErrorMessage(true);
return false;
}
@@ -1035,6 +1086,10 @@ bool ChatHandler::HandleModifyKnownTitlesCommand(const char* args)
return false;
}
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
uint64 titles2 = titles;
for(int i=1; i < sCharTitlesStore.GetNumRows(); ++i)
@@ -1084,9 +1139,13 @@ bool ChatHandler::HandleModifyHPCommand(const char* args)
return false;
}
- PSendSysMessage(LANG_YOU_CHANGE_HP, chr->GetName(), hp, hpm);
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ PSendSysMessage(LANG_YOU_CHANGE_HP, GetNameLink(chr).c_str(), hp, hpm);
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_HP_CHANGED, GetName(), hp, hpm);
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_HP_CHANGED, GetNameLink().c_str(), hp, hpm);
chr->SetMaxHealth( hpm );
chr->SetHealth( hp );
@@ -1128,9 +1187,13 @@ bool ChatHandler::HandleModifyManaCommand(const char* args)
return false;
}
- PSendSysMessage(LANG_YOU_CHANGE_MANA, chr->GetName(), mana, manam);
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ PSendSysMessage(LANG_YOU_CHANGE_MANA, GetNameLink(chr).c_str(), mana, manam);
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_MANA_CHANGED, GetName(), mana, manam);
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_MANA_CHANGED, GetNameLink().c_str(), mana, manam);
chr->SetMaxPower(POWER_MANA,manam );
chr->SetPower(POWER_MANA, mana );
@@ -1173,9 +1236,13 @@ bool ChatHandler::HandleModifyEnergyCommand(const char* args)
return false;
}
- PSendSysMessage(LANG_YOU_CHANGE_ENERGY, chr->GetName(), energy/10, energym/10);
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ PSendSysMessage(LANG_YOU_CHANGE_ENERGY, GetNameLink(chr).c_str(), energy/10, energym/10);
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_ENERGY_CHANGED, GetName(), energy/10, energym/10);
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_ENERGY_CHANGED, GetNameLink().c_str(), energy/10, energym/10);
chr->SetMaxPower(POWER_ENERGY,energym );
chr->SetPower(POWER_ENERGY, energy );
@@ -1220,9 +1287,13 @@ bool ChatHandler::HandleModifyRageCommand(const char* args)
return false;
}
- PSendSysMessage(LANG_YOU_CHANGE_RAGE, chr->GetName(), rage/10, ragem/10);
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ PSendSysMessage(LANG_YOU_CHANGE_RAGE, GetNameLink(chr).c_str(), rage/10, ragem/10);
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_RAGE_CHANGED, GetName(), rage/10, ragem/10);
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_RAGE_CHANGED, GetNameLink().c_str(), rage/10, ragem/10);
chr->SetMaxPower(POWER_RAGE,ragem );
chr->SetPower(POWER_RAGE, rage );
@@ -1230,6 +1301,40 @@ bool ChatHandler::HandleModifyRageCommand(const char* args)
return true;
}
+// Edit Player Runic Power
+bool ChatHandler::HandleModifyRunicPowerCommand(const char* args)
+{
+ if(!*args)
+ return false;
+
+ int32 rune = atoi((char*)args)*10;
+ int32 runem = atoi((char*)args)*10;
+
+ if (rune <= 0 || runem <= 0 || runem < rune)
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Player *chr = getSelectedPlayer();
+ if (chr == NULL)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ PSendSysMessage(LANG_YOU_CHANGE_RUNIC_POWER, GetNameLink(chr).c_str(), rune/10, runem/10);
+ if (needReportToTarget(chr))
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_RUNIC_POWER_CHANGED, GetNameLink().c_str(), rune/10, runem/10);
+
+ chr->SetMaxPower(POWER_RUNIC_POWER,runem );
+ chr->SetPower(POWER_RUNIC_POWER, rune );
+
+ return true;
+}
+
//Edit Player Faction
bool ChatHandler::HandleModifyFactionCommand(const char* args)
{
@@ -1344,9 +1449,13 @@ bool ChatHandler::HandleModifySpellCommand(const char* args)
return false;
}
- PSendSysMessage(LANG_YOU_CHANGE_SPELLFLATID, spellflatid, val, mark, chr->GetName());
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ PSendSysMessage(LANG_YOU_CHANGE_SPELLFLATID, spellflatid, val, mark, GetNameLink(chr).c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_SPELLFLATID_CHANGED, GetName(), spellflatid, val, mark);
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_SPELLFLATID_CHANGED, GetNameLink().c_str(), spellflatid, val, mark);
WorldPacket data(SMSG_SET_FLAT_SPELL_MODIFIER, (1+1+2+2));
data << uint8(spellflatid);
@@ -1374,6 +1483,11 @@ bool ChatHandler::HandleModifyTalentCommand (const char* args)
SetSentErrorMessage(true);
return false;
}
+
+ // check online security
+ if (HasLowerSecurity(player, 0))
+ return false;
+
player->SetFreeTalentPoints(tp);
return true;
}
@@ -1398,21 +1512,25 @@ bool ChatHandler::HandleTaxiCheatCommand(const char* args)
chr=m_session->GetPlayer();
}
+ // check online security
+ else if (HasLowerSecurity(chr, 0))
+ return false;
+
if (argstr == "on")
{
chr->SetTaxiCheater(true);
- PSendSysMessage(LANG_YOU_GIVE_TAXIS, chr->GetName());
+ PSendSysMessage(LANG_YOU_GIVE_TAXIS, GetNameLink(chr).c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_TAXIS_ADDED, GetName());
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_TAXIS_ADDED, GetNameLink().c_str());
return true;
}
if (argstr == "off")
{
chr->SetTaxiCheater(false);
- PSendSysMessage(LANG_YOU_REMOVE_TAXIS, chr->GetName());
+ PSendSysMessage(LANG_YOU_REMOVE_TAXIS, GetNameLink(chr).c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_TAXIS_REMOVED, GetName());
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_TAXIS_REMOVED, GetNameLink().c_str());
return true;
}
@@ -1445,16 +1563,22 @@ bool ChatHandler::HandleModifyASpeedCommand(const char* args)
return false;
}
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ std::string chrNameLink = GetNameLink(chr);
+
if(chr->isInFlight())
{
- PSendSysMessage(LANG_CHAR_IN_FLIGHT,chr->GetName());
+ PSendSysMessage(LANG_CHAR_IN_FLIGHT,chrNameLink.c_str());
SetSentErrorMessage(true);
return false;
}
- PSendSysMessage(LANG_YOU_CHANGE_ASPEED, ASpeed, chr->GetName());
+ PSendSysMessage(LANG_YOU_CHANGE_ASPEED, ASpeed, chrNameLink.c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_ASPEED_CHANGED, GetName(), ASpeed);
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_ASPEED_CHANGED, GetNameLink().c_str(), ASpeed);
chr->SetSpeed(MOVE_WALK, ASpeed,true);
chr->SetSpeed(MOVE_RUN, ASpeed,true);
@@ -1487,16 +1611,22 @@ bool ChatHandler::HandleModifySpeedCommand(const char* args)
return false;
}
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ std::string chrNameLink = GetNameLink(chr);
+
if(chr->isInFlight())
{
- PSendSysMessage(LANG_CHAR_IN_FLIGHT,chr->GetName());
+ PSendSysMessage(LANG_CHAR_IN_FLIGHT,chrNameLink.c_str());
SetSentErrorMessage(true);
return false;
}
- PSendSysMessage(LANG_YOU_CHANGE_SPEED, Speed, chr->GetName());
+ PSendSysMessage(LANG_YOU_CHANGE_SPEED, Speed, chrNameLink.c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_SPEED_CHANGED, GetName(), Speed);
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_SPEED_CHANGED, GetNameLink().c_str(), Speed);
chr->SetSpeed(MOVE_RUN,Speed,true);
@@ -1526,16 +1656,22 @@ bool ChatHandler::HandleModifySwimCommand(const char* args)
return false;
}
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ std::string chrNameLink = GetNameLink(chr);
+
if(chr->isInFlight())
{
- PSendSysMessage(LANG_CHAR_IN_FLIGHT,chr->GetName());
+ PSendSysMessage(LANG_CHAR_IN_FLIGHT,chrNameLink.c_str());
SetSentErrorMessage(true);
return false;
}
- PSendSysMessage(LANG_YOU_CHANGE_SWIM_SPEED, Swim, chr->GetName());
+ PSendSysMessage(LANG_YOU_CHANGE_SWIM_SPEED, Swim, chrNameLink.c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_SWIM_SPEED_CHANGED, GetName(), Swim);
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_SWIM_SPEED_CHANGED, GetNameLink().c_str(), Swim);
chr->SetSpeed(MOVE_SWIM,Swim,true);
@@ -1565,16 +1701,22 @@ bool ChatHandler::HandleModifyBWalkCommand(const char* args)
return false;
}
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ std::string chrNameLink = GetNameLink(chr);
+
if(chr->isInFlight())
{
- PSendSysMessage(LANG_CHAR_IN_FLIGHT,chr->GetName());
+ PSendSysMessage(LANG_CHAR_IN_FLIGHT,chrNameLink.c_str());
SetSentErrorMessage(true);
return false;
}
- PSendSysMessage(LANG_YOU_CHANGE_BACK_SPEED, BSpeed, chr->GetName());
+ PSendSysMessage(LANG_YOU_CHANGE_BACK_SPEED, BSpeed, chrNameLink.c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_BACK_SPEED_CHANGED, GetName(), BSpeed);
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_BACK_SPEED_CHANGED, GetNameLink().c_str(), BSpeed);
chr->SetSpeed(MOVE_RUN_BACK,BSpeed,true);
@@ -1604,9 +1746,13 @@ bool ChatHandler::HandleModifyFlyCommand(const char* args)
return false;
}
- PSendSysMessage(LANG_YOU_CHANGE_FLY_SPEED, FSpeed, chr->GetName());
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ PSendSysMessage(LANG_YOU_CHANGE_FLY_SPEED, FSpeed, GetNameLink(chr).c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_FLY_SPEED_CHANGED, GetName(), FSpeed);
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_FLY_SPEED_CHANGED, GetNameLink().c_str(), FSpeed);
chr->SetSpeed(MOVE_FLIGHT,FSpeed,true);
@@ -1635,9 +1781,13 @@ bool ChatHandler::HandleModifyScaleCommand(const char* args)
return false;
}
- PSendSysMessage(LANG_YOU_CHANGE_SIZE, Scale, chr->GetName());
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ PSendSysMessage(LANG_YOU_CHANGE_SIZE, Scale, GetNameLink(chr).c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_SIZE_CHANGED, GetName(), Scale);
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_SIZE_CHANGED, GetNameLink().c_str(), Scale);
chr->SetFloatValue(OBJECT_FIELD_SCALE_X, Scale);
@@ -1878,9 +2028,13 @@ bool ChatHandler::HandleModifyMountCommand(const char* args)
return false;
}
- PSendSysMessage(LANG_YOU_GIVE_MOUNT, chr->GetName());
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ PSendSysMessage(LANG_YOU_GIVE_MOUNT, GetNameLink(chr).c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_MOUNT_GIVED, GetName());
+ ChatHandler(chr).PSendSysMessage(LANG_MOUNT_GIVED, GetNameLink().c_str());
chr->SetUInt32Value( UNIT_FIELD_FLAGS , 0x001000 );
chr->Mount(mId);
@@ -1915,6 +2069,10 @@ bool ChatHandler::HandleModifyMoneyCommand(const char* args)
return false;
}
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
int32 addmoney = atoi((char*)args);
uint32 moneyuser = chr->GetMoney();
@@ -1926,25 +2084,25 @@ bool ChatHandler::HandleModifyMoneyCommand(const char* args)
sLog.outDetail(GetTrinityString(LANG_CURRENT_MONEY), moneyuser, addmoney, newmoney);
if(newmoney <= 0 )
{
- PSendSysMessage(LANG_YOU_TAKE_ALL_MONEY, chr->GetName());
+ PSendSysMessage(LANG_YOU_TAKE_ALL_MONEY, GetNameLink(chr).c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_ALL_MONEY_GONE, GetName());
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_ALL_MONEY_GONE, GetNameLink().c_str());
chr->SetMoney(0);
}
else
{
- PSendSysMessage(LANG_YOU_TAKE_MONEY, abs(addmoney), chr->GetName());
+ PSendSysMessage(LANG_YOU_TAKE_MONEY, abs(addmoney), GetNameLink(chr).c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_MONEY_TAKEN, GetName(), abs(addmoney));
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_MONEY_TAKEN, GetNameLink().c_str(), abs(addmoney));
chr->SetMoney( newmoney );
}
}
else
{
- PSendSysMessage(LANG_YOU_GIVE_MONEY, addmoney, chr->GetName());
+ PSendSysMessage(LANG_YOU_GIVE_MONEY, addmoney, GetNameLink(chr).c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_MONEY_GIVEN, GetName(), addmoney);
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_MONEY_GIVEN, GetNameLink().c_str(), addmoney);
chr->ModifyMoney( addmoney );
}
@@ -1953,20 +2111,24 @@ bool ChatHandler::HandleModifyMoneyCommand(const char* args)
return true;
}
-//Edit Player field
+//Edit Unit field
bool ChatHandler::HandleModifyBitCommand(const char* args)
{
if( !*args )
return false;
- Player *chr = getSelectedPlayer();
- if (chr == NULL)
+ Unit *unit = getSelectedUnit();
+ if (!unit)
{
SendSysMessage(LANG_NO_CHAR_SELECTED);
SetSentErrorMessage(true);
return false;
}
+ // check online security
+ if (unit->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player *)unit, 0))
+ return false;
+
char* pField = strtok((char*)args, " ");
if (!pField)
return false;
@@ -1978,13 +2140,12 @@ bool ChatHandler::HandleModifyBitCommand(const char* args)
uint16 field = atoi(pField);
uint32 bit = atoi(pBit);
- if (field < 1 || field >= PLAYER_END)
+ if (field < OBJECT_END || field >= unit->GetValuesCount())
{
SendSysMessage(LANG_BAD_VALUE);
SetSentErrorMessage(true);
return false;
}
-
if (bit < 1 || bit > 32)
{
SendSysMessage(LANG_BAD_VALUE);
@@ -1992,17 +2153,16 @@ bool ChatHandler::HandleModifyBitCommand(const char* args)
return false;
}
- if ( chr->HasFlag( field, (1<<(bit-1)) ) )
+ if ( unit->HasFlag( field, (1<<(bit-1)) ) )
{
- chr->RemoveFlag( field, (1<<(bit-1)) );
+ unit->RemoveFlag( field, (1<<(bit-1)) );
PSendSysMessage(LANG_REMOVE_BIT, bit, field);
}
else
{
- chr->SetFlag( field, (1<<(bit-1)) );
+ unit->SetFlag( field, (1<<(bit-1)) );
PSendSysMessage(LANG_SET_BIT, bit, field);
}
-
return true;
}
@@ -2019,11 +2179,15 @@ bool ChatHandler::HandleModifyHonorCommand (const char* args)
return false;
}
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
int32 amount = (uint32)atoi(args);
target->ModifyHonorPoints(amount);
- PSendSysMessage(LANG_COMMAND_MODIFY_HONOR, target->GetName(), target->GetHonorPoints());
+ PSendSysMessage(LANG_COMMAND_MODIFY_HONOR, GetNameLink(target).c_str(), target->GetHonorPoints());
return true;
}
@@ -2126,8 +2290,10 @@ bool ChatHandler::HandleLookupAreaCommand(const char* args)
}
}
}
+
if (counter == 0) // if counter == 0 then we found nth
SendSysMessage (LANG_COMMAND_NOAREAFOUND);
+
return true;
}
@@ -2254,9 +2420,13 @@ bool ChatHandler::HandleSendMailCommand(const char* args)
// format: name "subject text" "mail text"
- char* pName = strtok((char*)args, " ");
- if(!pName)
+ std::string name = extractPlayerNameFromLink((char*)args);
+ if(name.empty())
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
return false;
+ }
char* tail1 = strtok(NULL, "");
if(!tail1)
@@ -2294,18 +2464,10 @@ bool ChatHandler::HandleSendMailCommand(const char* args)
if (!msgText)
return false;
- // pName, msgSubject, msgText isn't NUL after prev. check
- std::string name = pName;
+ // msgSubject, msgText isn't NUL after prev. check
std::string subject = msgSubject;
std::string text = msgText;
- if(!normalizePlayerName(name))
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name);
if(!receiver_guid)
{
@@ -2314,7 +2476,6 @@ bool ChatHandler::HandleSendMailCommand(const char* args)
return false;
}
- uint32 mailId = objmgr.GenerateMailID();
// from console show not existed sender
uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
@@ -2326,7 +2487,8 @@ bool ChatHandler::HandleSendMailCommand(const char* args)
WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, NULL, 0, 0, MAIL_CHECK_MASK_NONE);
- PSendSysMessage(LANG_MAIL_SENT, name.c_str());
+ std::string nameLink = playerLink(name);
+ PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
return true;
}
@@ -2336,14 +2498,8 @@ bool ChatHandler::HandleNameTeleCommand(const char * args)
if(!*args)
return false;
- char* pName = strtok((char*)args, " ");
-
- if(!pName)
- return false;
-
- std::string name = pName;
-
- if(!normalizePlayerName(name))
+ std::string name = extractPlayerNameFromLink((char*)args);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -2374,17 +2530,22 @@ bool ChatHandler::HandleNameTeleCommand(const char * args)
Player *chr = objmgr.GetPlayer(name.c_str());
if (chr)
{
+ // check online security
+ if (HasLowerSecurity(chr, 0))
+ return false;
+
+ std::string chrNameLink = playerLink(name);
if(chr->IsBeingTeleported()==true)
{
- PSendSysMessage(LANG_IS_TELEPORTED, chr->GetName());
+ PSendSysMessage(LANG_IS_TELEPORTED, chrNameLink.c_str());
SetSentErrorMessage(true);
return false;
}
- PSendSysMessage(LANG_TELEPORTING_TO, chr->GetName(),"", tele->name.c_str());
+ PSendSysMessage(LANG_TELEPORTING_TO, chrNameLink.c_str(),"", tele->name.c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_TELEPORTED_TO_BY, GetName());
+ ChatHandler(chr).PSendSysMessage(LANG_TELEPORTED_TO_BY, GetNameLink().c_str());
// stop flight if need
if(chr->isInFlight())
@@ -2398,10 +2559,17 @@ bool ChatHandler::HandleNameTeleCommand(const char * args)
chr->TeleportTo(tele->mapId,tele->position_x,tele->position_y,tele->position_z,tele->orientation);
}
- else if (uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str()))
+ else if (uint64 guid = objmgr.GetPlayerGUIDByName(name))
{
- PSendSysMessage(LANG_TELEPORTING_TO, name.c_str(), GetTrinityString(LANG_OFFLINE), tele->name.c_str());
- Player::SavePositionInDB(tele->mapId,tele->position_x,tele->position_y,tele->position_z,tele->orientation,MapManager::Instance().GetZoneId(tele->mapId,tele->position_x,tele->position_y),guid);
+ // check offline security
+ if (HasLowerSecurity(NULL, guid))
+ return false;
+
+ std::string nameLink = playerLink(name);
+
+ PSendSysMessage(LANG_TELEPORTING_TO, nameLink.c_str(), GetMangosString(LANG_OFFLINE), tele->name.c_str());
+ Player::SavePositionInDB(tele->mapId,tele->position_x,tele->position_y,tele->position_z,tele->orientation,
+ MapManager::Instance().GetZoneId(tele->mapId,tele->position_x,tele->position_y,tele->position_z),guid);
}
else
PSendSysMessage(LANG_NO_PLAYER, name.c_str());
@@ -2423,6 +2591,10 @@ bool ChatHandler::HandleGroupTeleCommand(const char * args)
return false;
}
+ // check online security
+ if (HasLowerSecurity(player, 0))
+ return false;
+
// id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r
GameTele const* tele = extractGameTeleFromLink((char*)args);
if(!tele)
@@ -2439,10 +2611,13 @@ bool ChatHandler::HandleGroupTeleCommand(const char * args)
SetSentErrorMessage(true);
return false;
}
+
+ std::string nameLink = GetNameLink(player);
+
Group *grp = player->GetGroup();
if(!grp)
{
- PSendSysMessage(LANG_NOT_IN_GROUP,player->GetName());
+ PSendSysMessage(LANG_NOT_IN_GROUP,nameLink.c_str());
SetSentErrorMessage(true);
return false;
}
@@ -2454,15 +2629,21 @@ bool ChatHandler::HandleGroupTeleCommand(const char * args)
if(!pl || !pl->GetSession() )
continue;
+ // check online security
+ if (HasLowerSecurity(pl, 0))
+ return false;
+
+ std::string plNameLink = GetNameLink(pl);
+
if(pl->IsBeingTeleported())
{
- PSendSysMessage(LANG_IS_TELEPORTED, pl->GetName());
+ PSendSysMessage(LANG_IS_TELEPORTED, plNameLink.c_str());
continue;
}
- PSendSysMessage(LANG_TELEPORTING_TO, pl->GetName(),"", tele->name.c_str());
+ PSendSysMessage(LANG_TELEPORTING_TO, plNameLink.c_str(),"", tele->name.c_str());
if (needReportToTarget(pl))
- ChatHandler(pl).PSendSysMessage(LANG_TELEPORTED_TO_BY, GetName());
+ ChatHandler(pl).PSendSysMessage(LANG_TELEPORTED_TO_BY, nameLink.c_str());
// stop flight if need
if(pl->isInFlight())
@@ -2486,9 +2667,8 @@ bool ChatHandler::HandleGroupgoCommand(const char* args)
if(!*args)
return false;
- std::string name = args;
-
- if(!normalizePlayerName(name))
+ std::string name = extractPlayerNameFromLink((char*)args);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -2503,16 +2683,22 @@ bool ChatHandler::HandleGroupgoCommand(const char* args)
return false;
}
+ // check online security
+ if (HasLowerSecurity(player, 0))
+ return false;
+
Group *grp = player->GetGroup();
+ std::string nameLink = playerLink(name);
+
if(!grp)
{
- PSendSysMessage(LANG_NOT_IN_GROUP,player->GetName());
+ PSendSysMessage(LANG_NOT_IN_GROUP,nameLink.c_str());
SetSentErrorMessage(true);
return false;
}
- Map* gmMap = MapManager::Instance().GetMap(m_session->GetPlayer()->GetMapId(),m_session->GetPlayer());
+ Map* gmMap = m_session->GetPlayer()->GetMap();
bool to_instance = gmMap->Instanceable();
// we are in instance, and can summon only player in our group with us as lead
@@ -2533,29 +2719,35 @@ bool ChatHandler::HandleGroupgoCommand(const char* args)
if(!pl || pl==m_session->GetPlayer() || !pl->GetSession() )
continue;
+ // check online security
+ if (HasLowerSecurity(pl, 0))
+ return false;
+
+ std::string plNameLink = playerLink(name);
+
if(pl->IsBeingTeleported()==true)
{
- PSendSysMessage(LANG_IS_TELEPORTED, pl->GetName());
+ PSendSysMessage(LANG_IS_TELEPORTED, plNameLink.c_str());
SetSentErrorMessage(true);
return false;
}
if (to_instance)
{
- Map* plMap = MapManager::Instance().GetMap(pl->GetMapId(),pl);
+ Map* plMap = pl->GetMap();
if ( plMap->Instanceable() && plMap->GetInstanceId() != gmMap->GetInstanceId() )
{
// cannot summon from instance to instance
- PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST,pl->GetName());
+ PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST,plNameLink.c_str());
SetSentErrorMessage(true);
return false;
}
}
- PSendSysMessage(LANG_SUMMONING, pl->GetName(),"");
+ PSendSysMessage(LANG_SUMMONING, plNameLink.c_str(),"");
if (needReportToTarget(pl))
- ChatHandler(pl).PSendSysMessage(LANG_SUMMONED_BY, GetName());
+ ChatHandler(pl).PSendSysMessage(LANG_SUMMONED_BY, nameLink.c_str());
// stop flight if need
if(pl->isInFlight())
diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp
index 2b996cfd0fb..8d560783d89 100644
--- a/src/game/Level2.cpp
+++ b/src/game/Level2.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -10,12 +10,12 @@
*
* 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
+ * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Common.h"
@@ -36,6 +36,7 @@
#include "GameEvent.h"
#include "SpellMgr.h"
#include "AccountMgr.h"
+//#include "GMTicketMgr.h"
#include "WaypointManager.h"
#include "Util.h"
#include <cctype>
@@ -58,11 +59,13 @@ bool ChatHandler::HandleMuteCommand(const char* args)
if (!*args)
return false;
- char *charname = strtok((char*)args, " ");
- if (!charname)
+ std::string name = extractPlayerNameFromLink((char*)args);
+ if(name.empty())
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
return false;
-
- std::string cname = charname;
+ }
char *timetonotspeak = strtok(NULL, " ");
if(!timetonotspeak)
@@ -70,14 +73,7 @@ bool ChatHandler::HandleMuteCommand(const char* args)
uint32 notspeaktime = (uint32) atoi(timetonotspeak);
- if(!normalizePlayerName(cname))
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- uint64 guid = objmgr.GetPlayerGUIDByName(cname.c_str());
+ uint64 guid = objmgr.GetPlayerGUIDByName(name);
if(!guid)
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
@@ -87,27 +83,11 @@ bool ChatHandler::HandleMuteCommand(const char* args)
Player *chr = objmgr.GetPlayer(guid);
- // check security
- uint32 account_id = 0;
- uint32 security = 0;
-
- if (chr)
- {
- account_id = chr->GetSession()->GetAccountId();
- security = chr->GetSession()->GetSecurity();
- }
- else
- {
- account_id = objmgr.GetPlayerAccountIdByGUID(guid);
- security = accmgr.GetSecurity(account_id);
- }
-
- if(m_session && security >= m_session->GetSecurity())
- {
- SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
- SetSentErrorMessage(true);
+ // must have strong lesser security level
+ if(HasLowerSecurity (chr,guid,true))
return false;
- }
+
+ uint32 account_id = chr ? chr->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(guid);
time_t mutetime = time(NULL) + notspeaktime*60;
@@ -119,7 +99,9 @@ bool ChatHandler::HandleMuteCommand(const char* args)
if(chr)
ChatHandler(chr).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notspeaktime);
- PSendSysMessage(LANG_YOU_DISABLE_CHAT, cname.c_str(), notspeaktime);
+ std::string nameLink = playerLink(name);
+
+ PSendSysMessage(LANG_YOU_DISABLE_CHAT, nameLink.c_str(), notspeaktime);
return true;
}
@@ -130,20 +112,15 @@ bool ChatHandler::HandleUnmuteCommand(const char* args)
if (!*args)
return false;
- char *charname = strtok((char*)args, " ");
- if (!charname)
- return false;
-
- std::string cname = charname;
-
- if(!normalizePlayerName(cname))
+ std::string name = extractPlayerNameFromLink((char*)args);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
- uint64 guid = objmgr.GetPlayerGUIDByName(cname.c_str());
+ uint64 guid = objmgr.GetPlayerGUIDByName(name);
if(!guid)
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
@@ -153,27 +130,11 @@ bool ChatHandler::HandleUnmuteCommand(const char* args)
Player *chr = objmgr.GetPlayer(guid);
- // check security
- uint32 account_id = 0;
- uint32 security = 0;
-
- if (chr)
- {
- account_id = chr->GetSession()->GetAccountId();
- security = chr->GetSession()->GetSecurity();
- }
- else
- {
- account_id = objmgr.GetPlayerAccountIdByGUID(guid);
- security = accmgr.GetSecurity(account_id);
- }
-
- if(m_session && security >= m_session->GetSecurity())
- {
- SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
- SetSentErrorMessage(true);
+ // must have strong lesser security level
+ if(HasLowerSecurity (chr,guid,true))
return false;
- }
+
+ uint32 account_id = chr ? chr->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(guid);
if (chr)
{
@@ -192,7 +153,9 @@ bool ChatHandler::HandleUnmuteCommand(const char* args)
if(chr)
ChatHandler(chr).PSendSysMessage(LANG_YOUR_CHAT_ENABLED);
- PSendSysMessage(LANG_YOU_ENABLE_CHAT, cname.c_str());
+ std::string nameLink = playerLink(name);
+
+ PSendSysMessage(LANG_YOU_ENABLE_CHAT, nameLink.c_str());
return true;
}
@@ -588,6 +551,7 @@ bool ChatHandler::HandleLookupFactionCommand(const char* args)
repState = &repItr->second;
}
+
int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();
std::string name = factionEntry->name[loc];
if(name.empty())
@@ -668,6 +632,10 @@ bool ChatHandler::HandleModifyRepCommand(const char * args)
return false;
}
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
char* factionTxt = extractKeyFromLink((char*)args,"Hfaction");
if(!factionTxt)
return false;
@@ -745,11 +713,11 @@ bool ChatHandler::HandleModifyRepCommand(const char * args)
}
target->SetFactionReputation(factionEntry,amount);
- PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name[m_session->GetSessionDbcLocale()], factionId, target->GetName(), target->GetReputation(factionId));
+ PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name[m_session->GetSessionDbcLocale()], factionId, GetNameLink(target).c_str(), target->GetReputation(factionId));
return true;
}
-bool ChatHandler::HandleNameCommand(const char* args)
+bool ChatHandler::HandleNameCommand(const char* /*args*/)
{
/* Temp. disabled
if(!*args)
@@ -882,8 +850,8 @@ bool ChatHandler::HandleNpcAddCommand(const char* args)
{
if(!*args)
return false;
- char* charID = strtok((char*)args, " ");
- if (!charID)
+ char* charID = extractKeyFromLink((char*)args,"Hcreature_entry");
+ if(!charID)
return false;
char* team = strtok(NULL, " ");
@@ -901,7 +869,7 @@ bool ChatHandler::HandleNpcAddCommand(const char* args)
Map *map = chr->GetMap();
Creature* pCreature = new Creature;
- if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, (uint32)teamval))
+ if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, (uint32)teamval))
{
delete pCreature;
return false;
@@ -916,7 +884,7 @@ bool ChatHandler::HandleNpcAddCommand(const char* args)
return false;
}
- pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
+ pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
uint32 db_guid = pCreature->GetDBTableGUIDLow();
@@ -949,7 +917,7 @@ bool ChatHandler::HandleNpcDeleteCommand(const char* args)
else
unit = getSelectedCreature();
- if(!unit || unit->isPet() || unit->isTotem())
+ if(!unit || unit->isPet() || unit->isTotem() || unit->isVehicle())
{
SendSysMessage(LANG_SELECT_CREATURE);
SetSentErrorMessage(true);
@@ -1056,14 +1024,14 @@ bool ChatHandler::HandleTurnObjectCommand(const char* args)
float rot2 = sin(o/2);
float rot3 = cos(o/2);
- Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj);
+ Map* map = obj->GetMap();
map->Remove(obj,false);
obj->Relocate(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), o);
obj->SetFloatValue(GAMEOBJECT_FACING, o);
- obj->SetFloatValue(GAMEOBJECT_ROTATION+2, rot2);
- obj->SetFloatValue(GAMEOBJECT_ROTATION+3, rot3);
+ obj->SetFloatValue(GAMEOBJECT_PARENTROTATION+2, rot2);
+ obj->SetFloatValue(GAMEOBJECT_PARENTROTATION+3, rot3);
map->Add(obj);
@@ -1140,7 +1108,7 @@ bool ChatHandler::HandleNpcMoveCommand(const char* args)
const_cast<CreatureData*>(data)->posZ = z;
const_cast<CreatureData*>(data)->orientation = o;
}
- MapManager::Instance().GetMap(pCreature->GetMapId(),pCreature)->CreatureRelocation(pCreature,x, y, z,o);
+ pCreature->GetMap()->CreatureRelocation(pCreature,x, y, z,o);
pCreature->GetMotionMaster()->Initialize();
if(pCreature->isAlive()) // dead creature will reset movement generator at respawn
{
@@ -1187,7 +1155,7 @@ bool ChatHandler::HandleMoveObjectCommand(const char* args)
{
Player *chr = m_session->GetPlayer();
- Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj);
+ Map* map = obj->GetMap();
map->Remove(obj,false);
obj->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), obj->GetOrientation());
@@ -1213,7 +1181,7 @@ bool ChatHandler::HandleMoveObjectCommand(const char* args)
return false;
}
- Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj);
+ Map* map = obj->GetMap();
map->Remove(obj,false);
obj->Relocate(x, y, z, obj->GetOrientation());
@@ -1239,6 +1207,11 @@ bool ChatHandler::HandleDeMorphCommand(const char* /*args*/)
if(!target)
target = m_session->GetPlayer();
+
+ // check online security
+ else if (target->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player*)target, 0))
+ return false;
+
target->DeMorph();
return true;
@@ -1314,7 +1287,6 @@ bool ChatHandler::HandleDelVendorItemCommand(const char* args)
}
uint32 itemId = atol(pitem);
-
if(!objmgr.RemoveVendorItem(vendor->GetEntry(),itemId))
{
PSendSysMessage(LANG_ITEM_NOT_IN_LIST,itemId);
@@ -1629,6 +1601,10 @@ bool ChatHandler::HandleMorphCommand(const char* args)
if(!target)
target = m_session->GetPlayer();
+ // check online security
+ else if (target->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player*)target, 0))
+ return false;
+
target->SetDisplayId(display_id);
return true;
@@ -1688,7 +1664,7 @@ bool ChatHandler::HandleKickPlayerCommand(const char *args)
kicker = m_session->GetPlayer()->GetName();
if(!kickName)
- {
+ {
Player* player = getSelectedPlayer();
if(!player)
{
@@ -1704,14 +1680,16 @@ bool ChatHandler::HandleKickPlayerCommand(const char *args)
return false;
}
+ // check online security
+ if (HasLowerSecurity(player, 0))
+ return false;
+
if(sWorld.getConfig(CONFIG_SHOW_KICK_IN_WORLD) == 1)
{
-
sWorld.SendWorldText(LANG_COMMAND_KICKMESSAGE, player->GetName(), kicker.c_str(), reason.c_str());
}
else
{
-
PSendSysMessage(LANG_COMMAND_KICKMESSAGE, player->GetName(), kicker.c_str(), reason.c_str());
}
@@ -1719,8 +1697,8 @@ bool ChatHandler::HandleKickPlayerCommand(const char *args)
}
else
{
- std::string name = kickName;
- if(!normalizePlayerName(name))
+ std::string name = extractPlayerNameFromLink((char*)kickName);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -1742,34 +1720,56 @@ bool ChatHandler::HandleKickPlayerCommand(const char *args)
return false;
}
- if(m_session && player->GetSession()->GetSecurity() > m_session->GetSecurity())
+ if(HasLowerSecurity(player, 0))
{
SendSysMessage(LANG_YOURS_SECURITY_IS_LOW); //maybe replacement string for this later on
SetSentErrorMessage(true);
return false;
}
- if(sWorld.KickPlayer(name.c_str()))
+ std::string nameLink = playerLink(name);
+
+ if(sWorld.KickPlayer(name))
{
if(sWorld.getConfig(CONFIG_SHOW_KICK_IN_WORLD) == 1)
{
-
- sWorld.SendWorldText(LANG_COMMAND_KICKMESSAGE, name.c_str(), kicker.c_str(), reason.c_str());
+ sWorld.SendWorldText(LANG_COMMAND_KICKMESSAGE, nameLink.c_str(), kicker.c_str(), reason.c_str());
}
else
{
- PSendSysMessage(LANG_COMMAND_KICKMESSAGE, name.c_str(), kicker.c_str(), reason.c_str());
+ PSendSysMessage(LANG_COMMAND_KICKMESSAGE,nameLink.c_str());
}
}
else
{
- PSendSysMessage(LANG_COMMAND_KICKNOTFOUNDPLAYER, name.c_str());
+ PSendSysMessage(LANG_COMMAND_KICKNOTFOUNDPLAYER,nameLink.c_str());
return false;
}
}
return true;
}
+//set temporary phase mask for player
+bool ChatHandler::HandleModifyPhaseCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint32 phasemask = (uint32)atoi((char*)args);
+
+ Unit *target = getSelectedUnit();
+ if(!target)
+ target = m_session->GetPlayer();
+
+ // check online security
+ else if (target->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player*)target, 0))
+ return false;
+
+ target->SetPhaseMask(phasemask,true);
+
+ return true;
+}
+
//show info of player
bool ChatHandler::HandlePInfoCommand(const char* args)
{
@@ -1783,12 +1783,8 @@ bool ChatHandler::HandlePInfoCommand(const char* args)
if (px)
{
- name = px;
-
+ name = extractPlayerNameFromLink(px);
if(name.empty())
- return false;
-
- if(!normalizePlayerName(name))
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -1829,6 +1825,10 @@ bool ChatHandler::HandlePInfoCommand(const char* args)
// get additional information from Player object
if(target)
{
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
targetGUID = target->GetGUID();
name = target->GetName(); // re-read for case getSelectedPlayer() target
accId = target->GetSession()->GetAccountId();
@@ -1840,6 +1840,11 @@ bool ChatHandler::HandlePInfoCommand(const char* args)
// get additional information from DB
else
{
+ // check offline security
+ if (HasLowerSecurity(NULL, targetGUID))
+ return false;
+
+ // 0
QueryResult *result = CharacterDatabase.PQuery("SELECT totaltime FROM characters WHERE guid = '%u'", GUID_LOPART(targetGUID));
if (!result)
{
@@ -1890,7 +1895,9 @@ bool ChatHandler::HandlePInfoCommand(const char* args)
delete result;
}
- PSendSysMessage(LANG_PINFO_ACCOUNT, (target?"":GetTrinityString(LANG_OFFLINE)), name.c_str(), GUID_LOPART(targetGUID), username.c_str(), accId, security, last_ip.c_str(), last_login.c_str(), latency);
+ std::string nameLink = playerLink(name);
+
+ PSendSysMessage(LANG_PINFO_ACCOUNT, (target?"":GetMangosString(LANG_OFFLINE)), nameLink.c_str(), GUID_LOPART(targetGUID), username.c_str(), accId, security, last_ip.c_str(), last_login.c_str(), latency);
std::string timeStr = secsToTimeString(total_player_time,true,true);
uint32 gold = money /GOLD;
@@ -1940,6 +1947,191 @@ bool ChatHandler::HandlePInfoCommand(const char* args)
return true;
}
+/*//show tickets
+void ChatHandler::ShowTicket(uint64 guid, char const* text, char const* time)
+{
+ std::string name;
+ if(!objmgr.GetPlayerNameByGUID(guid,name))
+ name = GetTrinityString(LANG_UNKNOWN);
+
+ std::string nameLink = playerLink(name);
+
+ PSendSysMessage(LANG_COMMAND_TICKETVIEW, nameLink.c_str(),time,text);
+}
+
+//ticket commands
+bool ChatHandler::HandleTicketCommand(const char* args)
+{
+ char* px = strtok((char*)args, " ");
+
+ // ticket<end>
+ if (!px)
+ {
+ if(!m_session)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ size_t count = ticketmgr.GetTicketCount();
+
+ bool accept = m_session->GetPlayer()->isAcceptTickets();
+
+ PSendSysMessage(LANG_COMMAND_TICKETCOUNT, count, accept ? GetTrinityString(LANG_ON) : GetTrinityString(LANG_OFF));
+ return true;
+ }
+
+ // ticket on
+ if(strncmp(px,"on",3) == 0)
+ {
+ if(!m_session)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ m_session->GetPlayer()->SetAcceptTicket(true);
+ SendSysMessage(LANG_COMMAND_TICKETON);
+ return true;
+ }
+
+ // ticket off
+ if(strncmp(px,"off",4) == 0)
+ {
+ if(!m_session)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ m_session->GetPlayer()->SetAcceptTicket(false);
+ SendSysMessage(LANG_COMMAND_TICKETOFF);
+ return true;
+ }
+
+ // ticket #num
+ int num = atoi(px);
+ if(num > 0)
+ {
+ QueryResult *result = CharacterDatabase.PQuery("SELECT guid,ticket_text,ticket_lastchange FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_, num-1);
+
+ if(!result)
+ {
+ PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Field* fields = result->Fetch();
+
+ uint32 guid = fields[0].GetUInt32();
+ char const* text = fields[1].GetString();
+ char const* time = fields[2].GetString();
+
+ ShowTicket(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER),text,time);
+ delete result;
+ return true;
+ }
+
+ std::string name = extractPlayerNameFromLink(px);
+ if(name.empty())
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint64 guid = objmgr.GetPlayerGUIDByName(name);
+
+ if(!guid)
+ return false;
+
+ // ticket $char_name
+ GMTicket* ticket = ticketmgr.GetGMTicket(GUID_LOPART(guid));
+ if(!ticket)
+ return false;
+
+ std::string time = TimeToTimestampStr(ticket->GetLastUpdate());
+
+ ShowTicket(guid, ticket->GetText(), time.c_str());
+
+ return true;
+}
+
+//dell all tickets
+bool ChatHandler::HandleDelTicketCommand(const char *args)
+{
+ char* px = strtok((char*)args, " ");
+ if (!px)
+ return false;
+
+ // delticket all
+ if(strncmp(px,"all",4) == 0)
+ {
+ ticketmgr.DeleteAll();
+ SendSysMessage(LANG_COMMAND_ALLTICKETDELETED);
+ return true;
+ }
+
+ int num = (uint32)atoi(px);
+
+ // delticket #num
+ if(num > 0)
+ {
+ QueryResult* result = CharacterDatabase.PQuery("SELECT guid FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_,num-1);
+ if(!result)
+ {
+ PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
+ SetSentErrorMessage(true);
+ return false;
+ }
+ Field* fields = result->Fetch();
+ uint32 guid = fields[0].GetUInt32();
+ delete result;
+
+ ticketmgr.Delete(guid);
+
+ //notify player
+ if(Player* pl = objmgr.GetPlayer(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER)))
+ {
+ pl->GetSession()->SendGMTicketGetTicket(0x0A, 0);
+ PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL, GetNameLink(pl).c_str());
+ }
+ else
+ PSendSysMessage(LANG_COMMAND_TICKETDEL);
+
+ return true;
+ }
+
+ std::string name = extractPlayerNameFromLink(px);
+ if(name.empty())
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint64 guid = objmgr.GetPlayerGUIDByName(name);
+
+ if(!guid)
+ return false;
+
+ // delticket $char_name
+ ticketmgr.Delete(GUID_LOPART(guid));
+
+ // notify players about ticket deleting
+ if(Player* sender = objmgr.GetPlayer(guid))
+ sender->GetSession()->SendGMTicketGetTicket(0x0A,0);
+
+ std::string nameLink = playerLink(name);
+
+ PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL,nameLink.c_str());
+ return true;
+}*/
+
//set spawn dist of creature
bool ChatHandler::HandleNpcSpawnDistCommand(const char* args)
{
@@ -2569,7 +2761,7 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)
wpCreature->AddObjectToRemoveList();
// re-create
Creature* wpCreature2 = new Creature;
- if (!wpCreature2->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, VISUAL_WAYPOINT, 0))
+ if (!wpCreature2->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, 0))
{
PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
delete wpCreature2;
@@ -2584,7 +2776,7 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)
return false;
}
- wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
+ wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
// To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
wpCreature2->LoadFromDB(wpCreature2->GetDBTableGUIDLow(), map);
map->Add(wpCreature2);
@@ -2618,7 +2810,6 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)
}
PSendSysMessage(LANG_WAYPOINT_CHANGED_NO, show_str);
-
return true;
}
@@ -2800,7 +2991,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
float o = chr->GetOrientation();
Creature* wpCreature = new Creature;
- if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, 0))
+ if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0))
{
PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
delete wpCreature;
@@ -2822,7 +3013,8 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
// set "wpguid" column to the visual waypoint
WorldDatabase.PExecuteLog("UPDATE waypoint_data SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature->GetGUIDLow(), pathid, point);
- wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
+ wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
+ // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(),map);
map->Add(wpCreature);
@@ -2863,7 +3055,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
Map *map = chr->GetMap();
Creature* pCreature = new Creature;
- if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT),map, id, 0))
+ if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT),map, chr->GetPhaseMaskForSpawn(), id, 0))
{
PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
delete pCreature;
@@ -2881,7 +3073,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
return false;
}
- pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
+ pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
map->Add(pCreature);
@@ -2928,7 +3120,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
Map *map = chr->GetMap();
Creature* pCreature = new Creature;
- if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, 0))
+ if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0))
{
PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id);
delete pCreature;
@@ -2946,7 +3138,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
return false;
}
- pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
+ pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
map->Add(pCreature);
@@ -3028,9 +3220,8 @@ bool ChatHandler::HandleRenameCommand(const char* args)
if(px)
{
- oldname = px;
-
- if(!normalizePlayerName(oldname))
+ oldname = extractPlayerNameFromLink(px);
+ if(oldname.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -3057,19 +3248,83 @@ bool ChatHandler::HandleRenameCommand(const char* args)
if(target)
{
- PSendSysMessage(LANG_RENAME_PLAYER, target->GetName());
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
+ PSendSysMessage(LANG_RENAME_PLAYER, GetNameLink(target).c_str());
target->SetAtLoginFlag(AT_LOGIN_RENAME);
CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", target->GetGUIDLow());
}
else
{
- PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldname.c_str(), GUID_LOPART(targetGUID));
+ // check offline security
+ if (HasLowerSecurity(NULL, targetGUID))
+ return false;
+
+ std::string oldNameLink = playerLink(oldname);
+
+ PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGUID));
CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(targetGUID));
}
return true;
}
+// customize characters
+bool ChatHandler::HandleCustomizeCommand(const char* args)
+{
+ Player* target = NULL;
+ uint64 targetGUID = 0;
+ std::string oldname;
+
+ char* px = strtok((char*)args, " ");
+
+ if(px)
+ {
+ oldname = extractPlayerNameFromLink(px);
+ if(oldname.empty())
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ target = objmgr.GetPlayer(oldname.c_str());
+
+ if (!target)
+ targetGUID = objmgr.GetPlayerGUIDByName(oldname);
+ }
+
+ if(!target && !targetGUID)
+ {
+ target = getSelectedPlayer();
+ }
+
+ if(!target && !targetGUID)
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ if(target)
+ {
+ PSendSysMessage(LANG_CUSTOMIZE_PLAYER, GetNameLink(target).c_str());
+ target->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE);
+ CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", target->GetGUIDLow());
+ }
+ else
+ {
+ std::string oldNameLink = playerLink(oldname);
+
+ PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGUID));
+ CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", GUID_LOPART(targetGUID));
+ }
+
+ return true;
+}
+
//spawn go
bool ChatHandler::HandleGameObjectCommand(const char* args)
{
@@ -3108,7 +3363,7 @@ bool ChatHandler::HandleGameObjectCommand(const char* args)
GameObject* pGameObj = new GameObject;
uint32 db_lowGUID = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT);
- if(!pGameObj->Create(db_lowGUID, goI->id, map, x, y, z, o, 0, 0, rot2, rot3, 0, 1))
+ if(!pGameObj->Create(db_lowGUID, goI->id, map, chr->GetPhaseMaskForSpawn(), x, y, z, o, 0, 0, rot2, rot3, 0, 1))
{
delete pGameObj;
return false;
@@ -3122,7 +3377,7 @@ bool ChatHandler::HandleGameObjectCommand(const char* args)
}
// fill the gameobject data and save to the db
- pGameObj->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
+ pGameObj->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()),chr->GetPhaseMaskForSpawn());
// this will generate a new guid if the object is in an instance
if(!pGameObj->LoadFromDB(db_lowGUID, map))
@@ -3178,6 +3433,10 @@ bool ChatHandler::HandleAddHonorCommand(const char* args)
return false;
}
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
uint32 amount = (uint32)atoi(args);
target->RewardHonor(NULL, 1, amount);
return true;
@@ -3193,6 +3452,10 @@ bool ChatHandler::HandleHonorAddKillCommand(const char* /*args*/)
return false;
}
+ // check online security
+ if (target->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player*)target, 0))
+ return false;
+
m_session->GetPlayer()->RewardHonor(target, 1);
return true;
}
@@ -3207,6 +3470,10 @@ bool ChatHandler::HandleUpdateHonorFieldsCommand(const char* /*args*/)
return false;
}
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
target->UpdateHonorFields();
return true;
}
@@ -3423,9 +3690,8 @@ bool ChatHandler::HandleCombatStopCommand(const char* args)
if(*args)
{
- std::string playername = args;
-
- if(!normalizePlayerName(playername))
+ std::string playername = extractPlayerNameFromLink((char*)args);
+ if(playername.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -3449,6 +3715,10 @@ bool ChatHandler::HandleCombatStopCommand(const char* args)
player = m_session->GetPlayer();
}
+ // check online security
+ if (HasLowerSecurity(player, 0))
+ return false;
+
player->CombatStop();
player->getHostilRefManager().deleteReferences();
return true;
@@ -3487,7 +3757,7 @@ bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/)
if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
continue;
- m_session->GetPlayer()->learnSpell(skillLine->spellId);
+ m_session->GetPlayer()->learnSpell(skillLine->spellId,false);
}
}
}
@@ -3560,7 +3830,7 @@ bool ChatHandler::HandleLearnAllRecipesCommand(const char* args)
continue;
if( !target->HasSpell(spellInfo->Id) )
- m_session->GetPlayer()->learnSpell(skillLine->spellId);
+ m_session->GetPlayer()->learnSpell(skillLine->spellId,false);
}
uint16 maxLevel = target->GetPureMaxSkillValue(skillInfo->id);
@@ -3688,12 +3958,50 @@ bool ChatHandler::HandleRepairitemsCommand(const char* /*args*/)
return false;
}
+ // check online security
+ if (HasLowerSecurity(target, 0))
+ return false;
+
// Repair items
target->DurabilityRepairAll(false, 0, false);
- PSendSysMessage(LANG_YOU_REPAIR_ITEMS, target->GetName());
+ PSendSysMessage(LANG_YOU_REPAIR_ITEMS, GetNameLink(target).c_str());
if(needReportToTarget(target))
- ChatHandler(target).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED, GetName());
+ ChatHandler(target).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED, GetNameLink().c_str());
+ return true;
+}
+
+bool ChatHandler::HandleWaterwalkCommand(const char* args)
+{
+ if(!*args)
+ return false;
+
+ Player *player = getSelectedPlayer();
+
+ if(!player)
+ {
+ PSendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ // check online security
+ if (HasLowerSecurity(player, 0))
+ return false;
+
+ if (strncmp(args, "on", 3) == 0)
+ player->SetMovement(MOVE_WATER_WALK); // ON
+ else if (strncmp(args, "off", 4) == 0)
+ player->SetMovement(MOVE_LAND_WALK); // OFF
+ else
+ {
+ SendSysMessage(LANG_USE_BOL);
+ return false;
+ }
+
+ PSendSysMessage(LANG_YOU_SET_WATERWALK, args, GetNameLink(player).c_str());
+ if(needReportToTarget(player))
+ ChatHandler(player).PSendSysMessage(LANG_YOUR_WATERWALK_SET, args, GetNameLink().c_str());
return true;
}
@@ -3753,6 +4061,72 @@ bool ChatHandler::HandleNpcUnFollowCommand(const char* /*args*/)
return true;
}
+bool ChatHandler::HandleNpcTameCommand(const char* /*args*/)
+{
+ Creature *creatureTarget = getSelectedCreature ();
+ if (!creatureTarget || creatureTarget->isPet ())
+ {
+ PSendSysMessage (LANG_SELECT_CREATURE);
+ SetSentErrorMessage (true);
+ return false;
+ }
+
+ Player *player = m_session->GetPlayer ();
+
+ if(player->GetPetGUID ())
+ {
+ SendSysMessage (LANG_YOU_ALREADY_HAVE_PET);
+ SetSentErrorMessage (true);
+ return false;
+ }
+
+ CreatureInfo const* cInfo = creatureTarget->GetCreatureInfo();
+
+ if (!cInfo->isTameable ())
+ {
+ PSendSysMessage (LANG_CREATURE_NON_TAMEABLE,cInfo->Entry);
+ SetSentErrorMessage (true);
+ return false;
+ }
+
+ // Everything looks OK, create new pet
+ Pet* pet = player->CreateTamedPetFrom (creatureTarget);
+ if (!pet)
+ {
+ PSendSysMessage (LANG_CREATURE_NON_TAMEABLE,cInfo->Entry);
+ SetSentErrorMessage (true);
+ return false;
+ }
+
+ // place pet before player
+ float x,y,z;
+ player->GetClosePoint (x,y,z,creatureTarget->GetObjectSize (),CONTACT_DISTANCE);
+ pet->Relocate (x,y,z,M_PI-player->GetOrientation ());
+
+ // set pet to defensive mode by default (some classes can't control controlled pets in fact).
+ pet->GetCharmInfo()->SetReactState(REACT_DEFENSIVE);
+
+ // calculate proper level
+ uint32 level = (creatureTarget->getLevel() < (player->getLevel() - 5)) ? (player->getLevel() - 5) : creatureTarget->getLevel();
+
+ // prepare visual effect for levelup
+ pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
+
+ // add to world
+ pet->GetMap()->Add((Creature*)pet);
+
+ // visual effect for levelup
+ pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
+
+ // caster have pet now
+ player->SetPet(pet);
+
+ pet->SavePetToDB(PET_SAVE_AS_CURRENT);
+ player->PetSpellInitialize();
+
+ return true;
+}
+
bool ChatHandler::HandleCreatePetCommand(const char* args)
{
Player *player = m_session->GetPlayer();
@@ -3912,7 +4286,7 @@ bool ChatHandler::HandlePetTpCommand(const char *args)
uint32 tp = atol(args);
- pet->SetTP(tp);
+ //pet->SetTP(tp);
PSendSysMessage("Pet's tp changed to %u", tp);
return true;
@@ -4053,3 +4427,71 @@ bool ChatHandler::HandleNpcAddFormationCommand(const char* args)
return true;
}
+
+//change phasemask of creature or pet
+bool ChatHandler::HandleNpcSetPhaseCommand(const char* args)
+{
+ if (!*args)
+ return false;
+
+ uint32 phasemask = (uint32) atoi((char*)args);
+ if ( phasemask == 0 )
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ Creature* pCreature = getSelectedCreature();
+ if(!pCreature)
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ pCreature->SetPhaseMask(phasemask,true);
+
+ if(!pCreature->isPet())
+ pCreature->SaveToDB();
+
+ return true;
+}
+
+//set pahsemask for selected object
+bool ChatHandler::HandleGOPhaseCommand(const char* args)
+{
+ // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
+ char* cId = extractKeyFromLink((char*)args,"Hgameobject");
+ if(!cId)
+ return false;
+
+ uint32 lowguid = atoi(cId);
+ if(!lowguid)
+ return false;
+
+ GameObject* obj = NULL;
+ // by DB guid
+ if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
+ obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
+
+ if(!obj)
+ {
+ PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* phaseStr = strtok (NULL, " ");
+ uint32 phasemask = phaseStr? atoi(phaseStr) : 0;
+ if ( phasemask == 0 )
+ {
+ SendSysMessage(LANG_BAD_VALUE);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ obj->SetPhaseMask(phasemask,true);
+ obj->SaveToDB();
+ return true;
+}
diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp
index a36571d20a4..03979dc63e9 100644
--- a/src/game/Level3.cpp
+++ b/src/game/Level3.cpp
@@ -1,7 +1,7 @@
/*
-* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
-* Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+* Copyright (C) 2008-2009 Trinity <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
@@ -56,12 +56,12 @@
bool ChatHandler::HandleAHBotOptionsCommand(const char* args)
{
- uint32 ahMapID = 0;
+ AuctionLocation ahMapID = AUCTION_NEUTRAL;
char * opt = strtok((char*)args, " ");
char * ahMapIdStr = strtok(NULL, " ");
if (ahMapIdStr)
{
- ahMapID = (uint32) strtoul(ahMapIdStr, NULL, 0);
+ ahMapID = (AuctionLocation) strtoul(ahMapIdStr, NULL, 0);
}
if (!opt)
{
@@ -427,17 +427,8 @@ bool ChatHandler::HandleAHBotOptionsCommand(const char* args)
}
//reload commands
-bool ChatHandler::HandleReloadCommand(const char* arg)
-{
- // this is error catcher for wrong table name in .reload commands
- PSendSysMessage("Db table with name starting from '%s' not found and can't be reloaded.",arg);
- SetSentErrorMessage(true);
- return false;
-}
-
bool ChatHandler::HandleReloadAllCommand(const char*)
{
- HandleReloadAreaTriggerTeleportCommand("");
HandleReloadSkillFishingBaseLevelCommand("");
HandleReloadAllAreaCommand("");
@@ -522,6 +513,7 @@ bool ChatHandler::HandleReloadAllSpellCommand(const char*)
HandleReloadSpellElixirCommand("a");
HandleReloadSpellLearnSpellCommand("a");
HandleReloadSpellProcEventCommand("a");
+ HandleReloadSpellBonusesCommand("a");
HandleReloadSpellScriptTargetCommand("a");
HandleReloadSpellTargetPositionCommand("a");
HandleReloadSpellThreatsCommand("a");
@@ -624,6 +616,11 @@ bool ChatHandler::HandleReloadQuestTemplateCommand(const char*)
sLog.outString( "Re-Loading Quest Templates..." );
objmgr.LoadQuests();
SendGlobalGMSysMessage("DB table `quest_template` (quest definitions) reloaded.");
+
+ /// dependent also from `gameobject` but this table not reloaded anyway
+ sLog.outString( "Re-Loading GameObjects for quests..." );
+ objmgr.LoadGameObjectForQuests();
+ SendGlobalGMSysMessage("Data GameObjects for quests reloaded.");
return true;
}
@@ -672,6 +669,15 @@ bool ChatHandler::HandleReloadLootTemplatesItemCommand(const char*)
return true;
}
+bool ChatHandler::HandleReloadLootTemplatesMillingCommand(const char*)
+{
+ sLog.outString( "Re-Loading Loot Tables... (`milling_loot_template`)" );
+ LoadLootTemplates_Milling();
+ LootTemplates_Milling.CheckLootRefs();
+ SendGlobalSysMessage("DB table `milling_loot_template` reloaded.");
+ return true;
+}
+
bool ChatHandler::HandleReloadLootTemplatesPickpocketingCommand(const char*)
{
sLog.outString( "Re-Loading Loot Tables... (`pickpocketing_loot_template`)" );
@@ -716,6 +722,15 @@ bool ChatHandler::HandleReloadLootTemplatesSkinningCommand(const char*)
return true;
}
+bool ChatHandler::HandleReloadLootTemplatesSpellCommand(const char*)
+{
+ sLog.outString( "Re-Loading Loot Tables... (`spell_loot_template`)" );
+ LoadLootTemplates_Spell();
+ LootTemplates_Spell.CheckLootRefs();
+ SendGlobalSysMessage("DB table `spell_loot_template` reloaded.");
+ return true;
+}
+
bool ChatHandler::HandleReloadTrinityStringCommand(const char*)
{
sLog.outString( "Re-Loading trinity_string Table!" );
@@ -828,6 +843,14 @@ bool ChatHandler::HandleReloadSpellProcEventCommand(const char*)
return true;
}
+bool ChatHandler::HandleReloadSpellBonusesCommand(const char*)
+{
+ sLog.outString( "Re-Loading Spell Bonus Data..." );
+ spellmgr.LoadSpellBonusess();
+ SendGlobalSysMessage("DB table `spell_bonus_data` (spell damage/healing coefficients) reloaded.");
+ return true;
+}
+
bool ChatHandler::HandleReloadSpellScriptTargetCommand(const char*)
{
sLog.outString( "Re-Loading SpellsScriptTarget..." );
@@ -1213,19 +1236,10 @@ bool ChatHandler::HandleAccountSetPasswordCommand(const char* args)
return false;
}
- uint32 targetSecurity = accmgr.GetSecurity(targetAccountId);
-
- /// m_session==NULL only for console
- uint32 plSecurity = m_session ? m_session->GetSecurity() : SEC_CONSOLE;
-
/// can set password only for target with less security
/// This is also reject self apply in fact
- if (targetSecurity >= plSecurity)
- {
- SendSysMessage (LANG_YOURS_SECURITY_IS_LOW);
- SetSentErrorMessage (true);
+ if(HasLowerSecurityAccount (NULL,targetAccountId,true))
return false;
- }
if (strcmp(szPassword1,szPassword2))
{
@@ -1303,7 +1317,6 @@ bool ChatHandler::HandleSetSkillCommand(const char* args)
char *max_p = strtok (NULL, " ");
int32 skill = atoi(skill_p);
-
if (skill <= 0)
{
PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
@@ -1329,9 +1342,11 @@ bool ChatHandler::HandleSetSkillCommand(const char* args)
return false;
}
+ std::string tNameLink = GetNameLink(target);
+
if(!target->GetSkillValue(skill))
{
- PSendSysMessage(LANG_SET_SKILL_ERROR, target->GetName(), skill, sl->name[0]);
+ PSendSysMessage(LANG_SET_SKILL_ERROR, tNameLink.c_str(), skill, sl->name[0]);
SetSentErrorMessage(true);
return false;
}
@@ -1342,7 +1357,7 @@ bool ChatHandler::HandleSetSkillCommand(const char* args)
return false;
target->SetSkill(skill, level, max);
- PSendSysMessage(LANG_SET_SKILL, skill, sl->name[0], target->GetName(), level, max);
+ PSendSysMessage(LANG_SET_SKILL, skill, sl->name[0], tNameLink.c_str(), level, max);
return true;
}
@@ -1353,27 +1368,12 @@ bool ChatHandler::HandleUnLearnCommand(const char* args)
return false;
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
- uint32 min_id = extractSpellIdFromLink((char*)args);
- if(!min_id)
+ uint32 spell_id = extractSpellIdFromLink((char*)args);
+ if(!spell_id)
return false;
- // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
- char* tail = strtok(NULL,"");
-
- uint32 max_id = extractSpellIdFromLink(tail);
-
- if (!max_id)
- {
- // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
- max_id = min_id+1;
- }
- else
- {
- if (max_id < min_id)
- std::swap(min_id,max_id);
-
- max_id=max_id+1;
- }
+ char const* allStr = strtok(NULL," ");
+ bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false;
Player* target = getSelectedPlayer();
if(!target)
@@ -1383,13 +1383,13 @@ bool ChatHandler::HandleUnLearnCommand(const char* args)
return false;
}
- for(uint32 spell=min_id;spell<max_id;spell++)
- {
- if (target->HasSpell(spell))
- target->removeSpell(spell);
- else
- SendSysMessage(LANG_FORGET_SPELL);
- }
+ if(allRanks)
+ spell_id = spellmgr.GetFirstSpellInChain (spell_id);
+
+ if (target->HasSpell(spell_id))
+ target->removeSpell(spell_id,false,!allRanks);
+ else
+ SendSysMessage(LANG_FORGET_SPELL);
return true;
}
@@ -1404,10 +1404,12 @@ bool ChatHandler::HandleCooldownCommand(const char* args)
return false;
}
+ std::string tNameLink = GetNameLink(target);
+
if (!*args)
{
target->RemoveAllSpellCooldown();
- PSendSysMessage(LANG_REMOVEALL_COOLDOWN, target->GetName());
+ PSendSysMessage(LANG_REMOVEALL_COOLDOWN, tNameLink.c_str());
}
else
{
@@ -1418,7 +1420,7 @@ bool ChatHandler::HandleCooldownCommand(const char* args)
if(!sSpellStore.LookupEntry(spell_id))
{
- PSendSysMessage(LANG_UNKNOWN_SPELL, target==m_session->GetPlayer() ? GetTrinityString(LANG_YOU) : target->GetName());
+ PSendSysMessage(LANG_UNKNOWN_SPELL, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : tNameLink.c_str());
SetSentErrorMessage(true);
return false;
}
@@ -1428,8 +1430,8 @@ bool ChatHandler::HandleCooldownCommand(const char* args)
data << uint64(target->GetGUID());
target->GetSession()->SendPacket(&data);
target->RemoveSpellCooldown(spell_id);
- PSendSysMessage(LANG_REMOVE_COOLDOWN, spell_id, target==m_session->GetPlayer() ? GetTrinityString(LANG_YOU) : target->GetName());
- }
+ PSendSysMessage(LANG_REMOVE_COOLDOWN, spell_id, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : tNameLink.c_str());
+ }
return true;
}
@@ -2054,7 +2056,7 @@ bool ChatHandler::HandleLearnAllCommand(const char* /*args*/)
continue;
}
- m_session->GetPlayer()->learnSpell(spell);
+ m_session->GetPlayer()->learnSpell(spell,false);
}
SendSysMessage(LANG_COMMAND_LEARN_MANY_SPELLS);
@@ -2094,7 +2096,7 @@ bool ChatHandler::HandleLearnAllGMCommand(const char* /*args*/)
continue;
}
- m_session->GetPlayer()->learnSpell(spell);
+ m_session->GetPlayer()->learnSpell(spell,false);
}
SendSysMessage(LANG_LEARNING_GM_SKILLS);
@@ -2121,6 +2123,10 @@ bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)
if(!spellInfo)
continue;
+ // skip server-side/triggered spells
+ if(spellInfo->spellLevel==0)
+ continue;
+
// skip wrong class/race skills
if(!m_session->GetPlayer()->IsSpellFitByClassAndRace(spellInfo->Id))
continue;
@@ -2129,8 +2135,6 @@ bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)
if( spellInfo->SpellFamilyName != family)
continue;
- //TODO: skip triggered spells
-
// skip spells with first rank learned as talent (and all talents then also)
uint32 first_rank = spellmgr.GetFirstSpellInChain(spellInfo->Id);
if(GetTalentSpellCost(first_rank) > 0 )
@@ -2140,27 +2144,13 @@ bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)
if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
continue;
- m_session->GetPlayer()->learnSpell(i);
+ m_session->GetPlayer()->learnSpell(i,false);
}
SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS);
return true;
}
-static void learnAllHighRanks(Player* player, uint32 spellid)
-{
- SpellChainNode const* node;
- do
- {
- node = spellmgr.GetSpellChainNode(spellid);
- player->learnSpell(spellid);
- if (!node)
- break;
- spellid=node->next;
- }
- while (node->next);
-}
-
bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
{
Player* player = m_session->GetPlayer();
@@ -2198,11 +2188,8 @@ bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
continue;
- // learn highest rank of talent
- player->learnSpell(spellid);
-
- // and learn all non-talent spell ranks (recursive by tree)
- learnAllHighRanks(player,spellid);
+ // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree)
+ player->learnSpellHighRank(spellid);
}
SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS);
@@ -2213,7 +2200,7 @@ bool ChatHandler::HandleLearnAllLangCommand(const char* /*args*/)
{
// skipping UNIVERSAL language (0)
for(int i = 1; i < LANGUAGES_COUNT; ++i)
- m_session->GetPlayer()->learnSpell(lang_description[i].spell_id);
+ m_session->GetPlayer()->learnSpell(lang_description[i].spell_id,false);
SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG);
return true;
@@ -2221,13 +2208,11 @@ bool ChatHandler::HandleLearnAllLangCommand(const char* /*args*/)
bool ChatHandler::HandleLearnAllDefaultCommand(const char* args)
{
- char* pName = strtok((char*)args, "");
Player *player = NULL;
- if (pName)
+ if (*args)
{
- std::string name = pName;
-
- if(!normalizePlayerName(name))
+ std::string name = extractPlayerNameFromLink((char*)args);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -2249,7 +2234,7 @@ bool ChatHandler::HandleLearnAllDefaultCommand(const char* args)
player->learnDefaultSpells();
player->learnQuestRewardedSpells();
- PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST,player->GetName());
+ PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST,GetNameLink(player).c_str());
return true;
}
@@ -2269,25 +2254,31 @@ bool ChatHandler::HandleLearnCommand(const char* args)
if(!spell || !sSpellStore.LookupEntry(spell))
return false;
- if (targetPlayer->HasSpell(spell))
+ char const* allStr = strtok(NULL," ");
+ bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false;
+
+ SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
+ if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
{
- if(targetPlayer == m_session->GetPlayer())
- SendSysMessage(LANG_YOU_KNOWN_SPELL);
- else
- PSendSysMessage(LANG_TARGET_KNOWN_SPELL,targetPlayer->GetName());
+ PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
SetSentErrorMessage(true);
return false;
}
- SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
- if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
+ if (!allRanks && targetPlayer->HasSpell(spell))
{
- PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell);
+ if(targetPlayer == m_session->GetPlayer())
+ SendSysMessage(LANG_YOU_KNOWN_SPELL);
+ else
+ PSendSysMessage(LANG_TARGET_KNOWN_SPELL,GetNameLink(targetPlayer).c_str());
SetSentErrorMessage(true);
return false;
}
- targetPlayer->learnSpell(spell);
+ if(allRanks)
+ targetPlayer->learnSpellHighRank(spell);
+ else
+ targetPlayer->learnSpell(spell,false);
return true;
}
@@ -2357,7 +2348,7 @@ bool ChatHandler::HandleAddItemCommand(const char* args)
if (count < 0)
{
plTarget->DestroyItemCount(itemId, -count, true, false);
- PSendSysMessage(LANG_REMOVEITEM, itemId, -count, plTarget->GetName());
+ PSendSysMessage(LANG_REMOVEITEM, itemId, -count, GetNameLink(plTarget).c_str());
return true;
}
@@ -3097,15 +3088,25 @@ bool ChatHandler::HandleLookupSkillCommand(const char* args)
if(loc < MAX_LOCALE)
{
+ char valStr[50] = "";
char const* knownStr = "";
if(target && target->HasSkill(id))
+ {
knownStr = 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 = GetTrinityString(LANG_SKILL_VALUES);
+ snprintf(valStr,50,valFormat,curValue,maxValue,permValue,tempValue);
+ }
// send skill in "id - [namedlink locale]" format
if (m_session)
- PSendSysMessage(LANG_SKILL_LIST_CHAT,id,id,name.c_str(),localeNames[loc],knownStr);
+ PSendSysMessage(LANG_SKILL_LIST_CHAT,id,id,name.c_str(),localeNames[loc],knownStr,valStr);
else
- PSendSysMessage(LANG_SKILL_LIST_CONSOLE,id,name.c_str(),localeNames[loc],knownStr);
+ PSendSysMessage(LANG_SKILL_LIST_CONSOLE,id,name.c_str(),localeNames[loc],knownStr,valStr);
++counter;
}
@@ -3172,7 +3173,7 @@ bool ChatHandler::HandleLookupSpellCommand(const char* args)
bool talent = (talentCost > 0);
bool passive = IsPassiveSpell(id);
- bool active = target && (target->HasAura(id,0) || target->HasAura(id,1) || target->HasAura(id,2));
+ bool active = target && target->HasAura(id);
// unit32 used to prevent interpreting uint8 as char at output
// find rank of learned spell for learning spell, or talent rank
@@ -3519,11 +3520,11 @@ bool ChatHandler::HandleGuildInviteCommand(const char *args)
if (!targetGuild)
return false;
- std::string plName = par1;
- if (!normalizePlayerName (plName))
+ std::string plName = extractPlayerNameFromLink(par1);
+ if(plName.empty())
{
- SendSysMessage (LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage (true);
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
return false;
}
@@ -3531,7 +3532,7 @@ bool ChatHandler::HandleGuildInviteCommand(const char *args)
if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ()))
plGuid = targetPlayer->GetGUID ();
else
- plGuid = objmgr.GetPlayerGUIDByName (plName.c_str ());
+ plGuid = objmgr.GetPlayerGUIDByName (plName);
if (!plGuid)
false;
@@ -3552,11 +3553,11 @@ bool ChatHandler::HandleGuildUninviteCommand(const char *args)
if(!par1)
return false;
- std::string plName = par1;
- if (!normalizePlayerName (plName))
+ std::string plName = extractPlayerNameFromLink(par1);
+ if(plName.empty())
{
- SendSysMessage (LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage (true);
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
return false;
}
@@ -3569,7 +3570,7 @@ bool ChatHandler::HandleGuildUninviteCommand(const char *args)
}
else
{
- plGuid = objmgr.GetPlayerGUIDByName (plName.c_str ());
+ plGuid = objmgr.GetPlayerGUIDByName (plName);
glId = Player::GetGuildIdFromDB (plGuid);
}
@@ -3594,14 +3595,16 @@ bool ChatHandler::HandleGuildRankCommand(const char *args)
char* par2 = strtok (NULL, " ");
if (!par1 || !par2)
return false;
- std::string plName = par1;
- if (!normalizePlayerName (plName))
+
+ std::string plName = extractPlayerNameFromLink(par1);
+ if(plName.empty())
{
- SendSysMessage (LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage (true);
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
return false;
}
+
uint64 plGuid = 0;
uint32 glId = 0;
if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ()))
@@ -3611,7 +3614,7 @@ bool ChatHandler::HandleGuildRankCommand(const char *args)
}
else
{
- plGuid = objmgr.GetPlayerGUIDByName (plName.c_str ());
+ plGuid = objmgr.GetPlayerGUIDByName (plName);
glId = Player::GetGuildIdFromDB (plGuid);
}
@@ -3749,6 +3752,12 @@ bool ChatHandler::HandleDieCommand(const char* /*args*/)
return false;
}
+ if(target->GetTypeId()==TYPEID_PLAYER)
+ {
+ if(HasLowerSecurity((Player*)target,0,false))
+ return false;
+ }
+
if( target->isAlive() )
{
//m_session->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
@@ -3800,7 +3809,7 @@ bool ChatHandler::HandleDamageCommand(const char * args)
SpellSchoolMask schoolmask = SpellSchoolMask(1 << school);
if ( schoolmask & SPELL_SCHOOL_MASK_NORMAL )
- damage = m_session->GetPlayer()->CalcArmorReducedDamage(target, damage);
+ damage = m_session->GetPlayer()->CalcArmorReducedDamage(target, damage, NULL, BASE_ATTACK);
char* spellStr = strtok((char*)NULL, " ");
@@ -3850,7 +3859,7 @@ bool ChatHandler::HandleModifyArenaCommand(const char * args)
target->ModifyArenaPoints(amount);
- PSendSysMessage(LANG_COMMAND_MODIFY_ARENA, target->GetName(), target->GetArenaPoints());
+ PSendSysMessage(LANG_COMMAND_MODIFY_ARENA, GetNameLink(target).c_str(), target->GetArenaPoints());
return true;
}
@@ -3861,8 +3870,8 @@ bool ChatHandler::HandleReviveCommand(const char* args)
if (*args)
{
- std::string name = args;
- if(!normalizePlayerName(name))
+ std::string name = extractPlayerNameFromLink((char*)args);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -3889,10 +3898,6 @@ bool ChatHandler::HandleReviveCommand(const char* args)
bool ChatHandler::HandleAuraCommand(const char* args)
{
- char* px = strtok((char*)args, " ");
- if (!px)
- return false;
-
Unit *target = getSelectedUnit();
if(!target)
{
@@ -3901,7 +3906,9 @@ bool ChatHandler::HandleAuraCommand(const char* args)
return false;
}
- uint32 spellID = (uint32)atoi(px);
+ // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
+ uint32 spellID = extractSpellIdFromLink((char*)args);
+
SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellID );
if(spellInfo)
{
@@ -3925,10 +3932,6 @@ bool ChatHandler::HandleAuraCommand(const char* args)
bool ChatHandler::HandleUnAuraCommand(const char* args)
{
- char* px = strtok((char*)args, " ");
- if (!px)
- return false;
-
Unit *target = getSelectedUnit();
if(!target)
{
@@ -3944,7 +3947,11 @@ bool ChatHandler::HandleUnAuraCommand(const char* args)
return true;
}
- uint32 spellID = (uint32)atoi(px);
+ // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
+ uint32 spellID = extractSpellIdFromLink((char*)args);
+ if(!spellID)
+ return false;
+
target->RemoveAurasDueToSpell(spellID);
return true;
@@ -4148,15 +4155,15 @@ bool ChatHandler::HandleExploreCheatCommand(const char* args)
if (flag != 0)
{
- PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, chr->GetName());
+ PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, GetNameLink(chr).c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL,GetName());
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL,GetNameLink().c_str());
}
else
{
- PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, chr->GetName());
+ PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, GetNameLink(chr).c_str());
if (needReportToTarget(chr))
- ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING,GetName());
+ ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING,GetNameLink().c_str());
}
for (uint8 i=0; i<128; i++)
@@ -4193,36 +4200,6 @@ bool ChatHandler::HandleHoverCommand(const char* args)
return true;
}
-bool ChatHandler::HandleWaterwalkCommand(const char* args)
-{
- if(!args)
- return false;
-
- Player *player = getSelectedPlayer();
- if(!player)
- {
- PSendSysMessage(LANG_NO_CHAR_SELECTED);
- SetSentErrorMessage(true);
- return false;
- }
-
- if (strncmp(args, "on", 3) == 0)
- player->SetMovement(MOVE_WATER_WALK); // ON
- else if (strncmp(args, "off", 4) == 0)
- player->SetMovement(MOVE_LAND_WALK); // OFF
- else
- {
- SendSysMessage(LANG_USE_BOL);
- return false;
- }
-
- PSendSysMessage(LANG_YOU_SET_WATERWALK, args, player->GetName());
- if(needReportToTarget(player))
- ChatHandler(player).PSendSysMessage(LANG_YOUR_WATERWALK_SET, args, GetName());
- return true;
-
-}
-
bool ChatHandler::HandleLevelUpCommand(const char* args)
{
char* px = strtok((char*)args, " ");
@@ -4254,8 +4231,8 @@ bool ChatHandler::HandleLevelUpCommand(const char* args)
if(pname) // player by name
{
- name = pname;
- if(!normalizePlayerName(name))
+ name = extractPlayerNameFromLink(pname);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -4285,7 +4262,7 @@ bool ChatHandler::HandleLevelUpCommand(const char* args)
return false;
}
- name = chr->GetName();
+ name = GetNameLink(chr);
}
assert(chr || chr_guid);
@@ -4323,7 +4300,10 @@ bool ChatHandler::HandleLevelUpCommand(const char* args)
}
if(m_session->GetPlayer() != chr) // including chr==NULL
- PSendSysMessage(LANG_YOU_CHANGE_LVL,name.c_str(),newlevel);
+ {
+ std::string nameLink = playerLink(name);
+ PSendSysMessage(LANG_YOU_CHANGE_LVL,nameLink.c_str(),newlevel);
+ }
return true;
}
@@ -4332,8 +4312,6 @@ bool ChatHandler::HandleShowAreaCommand(const char* args)
if (!*args)
return false;
- int area = atoi((char*)args);
-
Player *chr = getSelectedPlayer();
if (chr == NULL)
{
@@ -4342,10 +4320,11 @@ bool ChatHandler::HandleShowAreaCommand(const char* args)
return false;
}
+ int area = GetAreaFlagByAreaID(atoi((char*)args));
int offset = area / 32;
uint32 val = (uint32)(1 << (area % 32));
- if(offset >= 128)
+ if(area<0 || offset >= 128)
{
SendSysMessage(LANG_BAD_VALUE);
SetSentErrorMessage(true);
@@ -4364,8 +4343,6 @@ bool ChatHandler::HandleHideAreaCommand(const char* args)
if (!*args)
return false;
- int area = atoi((char*)args);
-
Player *chr = getSelectedPlayer();
if (chr == NULL)
{
@@ -4374,10 +4351,11 @@ bool ChatHandler::HandleHideAreaCommand(const char* args)
return false;
}
+ int area = GetAreaFlagByAreaID(atoi((char*)args));
int offset = area / 32;
uint32 val = (uint32)(1 << (area % 32));
- if(offset >= 128)
+ if(area<0 || offset >= 128)
{
SendSysMessage(LANG_BAD_VALUE);
SetSentErrorMessage(true);
@@ -4723,11 +4701,28 @@ bool ChatHandler::HandleListAurasCommand (const char * /*args*/)
for (Unit::AuraMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr)
{
bool talent = GetTalentSpellCost(itr->second->GetId()) > 0;
- PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
- itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
- itr->second->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()],
- (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
- IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
+
+ char const* name = itr->second->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()];
+
+ if (m_session)
+ {
+ std::ostringstream ss_name;
+ ss_name << "|cffffffff|Hspell:" << itr->second->GetId() << "|h[" << name << "]|h|r";
+
+ PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
+ itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
+ ss_name.str().c_str(),
+ (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
+ IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
+ }
+ else
+ {
+ PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
+ itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
+ name,
+ (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
+ IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
+ }
}
for (int i = 0; i < TOTAL_AURAS; i++)
{
@@ -4737,11 +4732,65 @@ bool ChatHandler::HandleListAurasCommand (const char * /*args*/)
for (Unit::AuraList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr)
{
bool talent = GetTalentSpellCost((*itr)->GetId()) > 0;
- PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
- (*itr)->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()],((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
- IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
+
+ char const* name = (*itr)->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()];
+
+ if (m_session)
+ {
+ std::ostringstream ss_name;
+ ss_name << "|cffffffff|Hspell:" << (*itr)->GetId() << "|h[" << name << "]|h|r";
+
+ PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
+ ss_name.str().c_str(),((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
+ IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
+ }
+ else
+ {
+ PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
+ name,((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
+ IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
+ }
+ }
+ }
+ return true;
+}
+
+bool ChatHandler::HandleResetAchievementsCommand (const char * args)
+{
+ char* pName = strtok((char*)args, "");
+ Player *player = NULL;
+ uint64 guid = 0;
+ if (pName)
+ {
+ std::string name = extractPlayerNameFromLink(pName);
+ if(name.empty())
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
+ return false;
}
+
+ guid = objmgr.GetPlayerGUIDByName(name);
+ player = objmgr.GetPlayer(guid);
}
+ else
+ {
+ player = getSelectedPlayer();
+ if(player)
+ guid = player->GetGUID();
+ }
+
+ if(!player && !guid)
+ {
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ return true;
+ }
+
+ if(player)
+ player->GetAchievementMgr().Reset();
+ else if(guid)
+ AchievementMgr::DeleteFromDB(GUID_LOPART(guid));
+
return true;
}
@@ -4751,15 +4800,15 @@ bool ChatHandler::HandleResetHonorCommand (const char * args)
Player *player = NULL;
if (pName)
{
- std::string name = pName;
- if(!normalizePlayerName(name))
+ std::string name = extractPlayerNameFromLink(pName);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
- uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str());
+ uint64 guid = objmgr.GetPlayerGUIDByName(name);
player = objmgr.GetPlayer(guid);
}
else
@@ -4794,19 +4843,6 @@ static bool HandleResetStatsOrLevelHelper(Player* player)
uint8 powertype = cEntry->powerType;
- uint32 unitfield;
- if(powertype == POWER_RAGE)
- unitfield = 0x1100EE00;
- else if(powertype == POWER_ENERGY)
- unitfield = 0x00000000;
- else if(powertype == POWER_MANA)
- unitfield = 0x0000EE00;
- else
- {
- sLog.outError("Invalid default powertype %u for player (class %u)",powertype,player->getClass());
- return false;
- }
-
// reset m_form if no aura
if(!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT))
player->m_form = FORM_NONE;
@@ -4836,9 +4872,7 @@ static bool HandleResetStatsOrLevelHelper(Player* player)
}
}
- // set UNIT_FIELD_BYTES_1 to init state but preserve m_form value
- player->SetUInt32Value(UNIT_FIELD_BYTES_1, unitfield);
- player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY | UNIT_BYTE2_FLAG_UNK5 );
+ player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP );
player->SetByteValue(UNIT_FIELD_BYTES_2, 3, player->m_form);
player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
@@ -4856,15 +4890,15 @@ bool ChatHandler::HandleResetLevelCommand(const char * args)
Player *player = NULL;
if (pName)
{
- std::string name = pName;
- if(!normalizePlayerName(name))
+ std::string name = extractPlayerNameFromLink(pName);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
- uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str());
+ uint64 guid = objmgr.GetPlayerGUIDByName(name);
player = objmgr.GetPlayer(guid);
}
else
@@ -4880,17 +4914,26 @@ bool ChatHandler::HandleResetLevelCommand(const char * args)
if(!HandleResetStatsOrLevelHelper(player))
return false;
- player->SetLevel(1);
+ // set starting level
+ uint32 start_level = player->getClass() != CLASS_DEATH_KNIGHT
+ ? sWorld.getConfig(CONFIG_START_PLAYER_LEVEL)
+ : sWorld.getConfig(CONFIG_START_HEROIC_PLAYER_LEVEL);
+
+ player->SetLevel(start_level);
+ player->InitRunes();
player->InitStatsForLevel(true);
player->InitTaxiNodesForLevel();
+ player->InitGlyphsForLevel();
player->InitTalentForLevel();
player->SetUInt32Value(PLAYER_XP,0);
// reset level to summoned pet
Pet* pet = player->GetPet();
if(pet && pet->getPetType()==SUMMON_PET)
+ {
pet->InitStatsForLevel(1);
-
+ pet->InitTalentForLevel();
+ }
return true;
}
@@ -4900,15 +4943,15 @@ bool ChatHandler::HandleResetStatsCommand(const char * args)
Player *player = NULL;
if (pName)
{
- std::string name = pName;
- if(!normalizePlayerName(name))
+ std::string name = extractPlayerNameFromLink(pName);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
- uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str());
+ uint64 guid = objmgr.GetPlayerGUIDByName(name);
player = objmgr.GetPlayer(guid);
}
else
@@ -4924,8 +4967,10 @@ bool ChatHandler::HandleResetStatsCommand(const char * args)
if(!HandleResetStatsOrLevelHelper(player))
return false;
+ player->InitRunes();
player->InitStatsForLevel(true);
player->InitTaxiNodesForLevel();
+ player->InitGlyphsForLevel();
player->InitTalentForLevel();
return true;
@@ -4938,9 +4983,8 @@ bool ChatHandler::HandleResetSpellsCommand(const char * args)
uint64 playerGUID = 0;
if (pName)
{
- std::string name = pName;
-
- if(!normalizePlayerName(name))
+ std::string name = extractPlayerNameFromLink(pName);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -4949,7 +4993,7 @@ bool ChatHandler::HandleResetSpellsCommand(const char * args)
player = objmgr.GetPlayer(name.c_str());
if(!player)
- playerGUID = objmgr.GetPlayerGUIDByName(name.c_str());
+ playerGUID = objmgr.GetPlayerGUIDByName(name);
}
else
player = getSelectedPlayer();
@@ -4966,9 +5010,8 @@ bool ChatHandler::HandleResetSpellsCommand(const char * args)
player->resetSpells();
ChatHandler(player).SendSysMessage(LANG_RESET_SPELLS);
-
if(m_session->GetPlayer()!=player)
- PSendSysMessage(LANG_RESET_SPELLS_ONLINE,player->GetName());
+ PSendSysMessage(LANG_RESET_SPELLS_ONLINE,GetNameLink(player).c_str());
}
else
{
@@ -4986,8 +5029,8 @@ bool ChatHandler::HandleResetTalentsCommand(const char * args)
uint64 playerGUID = 0;
if (pName)
{
- std::string name = pName;
- if(!normalizePlayerName(name))
+ std::string name = extractPlayerNameFromLink(pName);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -4996,34 +5039,47 @@ bool ChatHandler::HandleResetTalentsCommand(const char * args)
player = objmgr.GetPlayer(name.c_str());
if(!player)
- playerGUID = objmgr.GetPlayerGUIDByName(name.c_str());
+ playerGUID = objmgr.GetPlayerGUIDByName(name);
}
else
player = getSelectedPlayer();
- if(!player && !playerGUID)
- {
- SendSysMessage(LANG_NO_CHAR_SELECTED);
- SetSentErrorMessage(true);
- return false;
- }
-
if(player)
{
player->resetTalents(true);
ChatHandler(player).SendSysMessage(LANG_RESET_TALENTS);
-
if(m_session->GetPlayer()!=player)
- PSendSysMessage(LANG_RESET_TALENTS_ONLINE,player->GetName());
+ PSendSysMessage(LANG_RESET_TALENTS_ONLINE,GetNameLink(player).c_str());
+
+ return true;
}
- else
+ else if (playerGUID)
{
CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_TALENTS), GUID_LOPART(playerGUID) );
- PSendSysMessage(LANG_RESET_TALENTS_OFFLINE,pName);
+ std::string nameLink = playerLink(pName);
+ PSendSysMessage(LANG_RESET_TALENTS_OFFLINE,nameLink.c_str());
+ return true;
+ }
+ // Try reset talenents as Hunter Pet
+ Creature* creature = getSelectedCreature();
+ if (creature && creature->isPet() && ((Pet *)creature)->getPetType() == HUNTER_PET)
+ {
+ ((Pet *)creature)->resetTalents(true);
+ Unit *owner = creature->GetOwner();
+ if (owner && owner->GetTypeId() == TYPEID_PLAYER)
+ {
+ player = (Player *)owner;
+ ChatHandler(player).SendSysMessage(LANG_RESET_TALENTS);
+ if(m_session->GetPlayer()!=player)
+ PSendSysMessage(LANG_RESET_TALENTS_ONLINE,GetNameLink(player).c_str());
+ }
+ return true;
}
- return true;
+ SendSysMessage(LANG_NO_CHAR_SELECTED);
+ SetSentErrorMessage(true);
+ return false;
}
bool ChatHandler::HandleResetAllCommand(const char * args)
@@ -5580,12 +5636,8 @@ bool ChatHandler::HandleBanInfoCharacterCommand(const char* args)
if(!args)
return false;
- char* cname = strtok ((char*)args, "");
- if(!cname)
- return false;
-
- std::string name = cname;
- if(!normalizePlayerName(name))
+ std::string name = extractPlayerNameFromLink((char*)args);
+ if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
@@ -5897,8 +5949,8 @@ bool ChatHandler::HandleRespawnCommand(const char* /*args*/)
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
- Trinity::RespawnDo u_do;
- Trinity::WorldObjectWorker<Trinity::RespawnDo> worker(u_do);
+ MaNGOS::RespawnDo u_do;
+ MaNGOS::WorldObjectWorker<MaNGOS::RespawnDo> worker(pl,u_do);
TypeContainerVisitor<Trinity::WorldObjectWorker<Trinity::RespawnDo>, GridTypeMapContainer > obj_worker(worker);
CellLock<GridReadGuard> cell_lock(cell, p);
@@ -5912,9 +5964,9 @@ bool ChatHandler::HandleFlyModeCommand(const char* args)
if(!args)
return false;
- Unit *unit = getSelectedUnit();
- if (!unit || (unit->GetTypeId() != TYPEID_PLAYER))
- unit = m_session->GetPlayer();
+ Player *target = getSelectedPlayer();
+ if (!target)
+ target = m_session->GetPlayer();
WorldPacket data(12);
if (strncmp(args, "on", 3) == 0)
@@ -5926,10 +5978,10 @@ bool ChatHandler::HandleFlyModeCommand(const char* args)
SendSysMessage(LANG_USE_BOL);
return false;
}
- data.append(unit->GetPackGUID());
+ data.append(target->GetPackGUID());
data << uint32(0); // unknown
- unit->SendMessageToSet(&data, true);
- PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, unit->GetName(), args);
+ target->SendMessageToSet(&data, true);
+ PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, GetNameLink(target).c_str(), args);
return true;
}
@@ -6085,12 +6137,11 @@ bool ChatHandler::HandleWritePDumpCommand(const char *args)
guid = atoi(p2);
else
{
- std::string name = p2;
-
- if (!normalizePlayerName (name))
+ std::string name = extractPlayerNameFromLink(p2);
+ if(name.empty())
{
- SendSysMessage (LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage (true);
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
return false;
}
@@ -6682,8 +6733,15 @@ bool ChatHandler::HandleAccountSetAddonCommand(const char* args)
SetSentErrorMessage(true);
return false;
}
+
}
+ // Let set addon state only for lesser (strong) security level
+ // or to self account
+ if (m_session && m_session->GetAccountId () != account_id &&
+ HasLowerSecurityAccount (NULL,account_id,true))
+ return false;
+
int lev=atoi(szExp); //get int anyway (0 if error)
if(lev < 0)
return false;
@@ -6702,9 +6760,13 @@ bool ChatHandler::HandleSendItemsCommand(const char* args)
// format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12]
- char* pName = strtok((char*)args, " ");
- if(!pName)
+ std::string name = extractPlayerNameFromLink((char*)args);
+ if(name.empty())
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
return false;
+ }
char* tail1 = strtok(NULL, "");
if(!tail1)
@@ -6742,8 +6804,7 @@ bool ChatHandler::HandleSendItemsCommand(const char* args)
if (!msgText)
return false;
- // pName, msgSubject, msgText isn't NUL after prev. check
- std::string name = pName;
+ // msgSubject, msgText isn't NUL after prev. check
std::string subject = msgSubject;
std::string text = msgText;
@@ -6778,17 +6839,17 @@ bool ChatHandler::HandleSendItemsCommand(const char* args)
}
uint32 item_count = itemCountStr ? atoi(itemCountStr) : 1;
- if(item_count < 1 || item_proto->MaxCount && item_count > item_proto->MaxCount)
+ if(item_count < 1 || item_proto->MaxCount > 0 && item_count > uint32(item_proto->MaxCount))
{
PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, item_count,item_id);
SetSentErrorMessage(true);
return false;
}
- while(item_count > item_proto->Stackable)
+ while(item_count > item_proto->GetMaxStackSize())
{
- items.push_back(ItemPair(item_id,item_proto->Stackable));
- item_count -= item_proto->Stackable;
+ items.push_back(ItemPair(item_id,item_proto->GetMaxStackSize()));
+ item_count -= item_proto->GetMaxStackSize();
}
items.push_back(ItemPair(item_id,item_count));
@@ -6801,13 +6862,6 @@ bool ChatHandler::HandleSendItemsCommand(const char* args)
}
}
- if(!normalizePlayerName(name))
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name);
if(!receiver_guid)
{
@@ -6839,7 +6893,8 @@ bool ChatHandler::HandleSendItemsCommand(const char* args)
WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
- PSendSysMessage(LANG_MAIL_SENT, name.c_str());
+ std::string nameLink = playerLink(name);
+ PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
return true;
}
@@ -6851,9 +6906,13 @@ bool ChatHandler::HandleSendMoneyCommand(const char* args)
/// format: name "subject text" "mail text" money
- char* pName = strtok((char*)args, " ");
- if (!pName)
+ std::string name = extractPlayerNameFromLink((char*)args);
+ if(name.empty())
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
return false;
+ }
char* tail1 = strtok(NULL, "");
if (!tail1)
@@ -6896,18 +6955,10 @@ bool ChatHandler::HandleSendMoneyCommand(const char* args)
if (money <= 0)
return false;
- // pName, msgSubject, msgText isn't NUL after prev. check
- std::string name = pName;
+ // msgSubject, msgText isn't NUL after prev. check
std::string subject = msgSubject;
std::string text = msgText;
- if (!normalizePlayerName(name))
- {
- SendSysMessage(LANG_PLAYER_NOT_FOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name);
if (!receiver_guid)
{
@@ -6929,7 +6980,8 @@ bool ChatHandler::HandleSendMoneyCommand(const char* args)
WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, NULL, money, 0, MAIL_CHECK_MASK_NONE);
- PSendSysMessage(LANG_MAIL_SENT, name.c_str());
+ std::string nameLink = playerLink(name);
+ PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
return true;
}
@@ -6937,15 +6989,16 @@ bool ChatHandler::HandleSendMoneyCommand(const char* args)
bool ChatHandler::HandleSendMessageCommand(const char* args)
{
///- Get the command line arguments
- char* name_str = strtok((char*)args, " ");
- char* msg_str = strtok(NULL, "");
-
- if(!name_str || !msg_str)
+ std::string name = extractPlayerNameFromLink((char*)args);
+ if(name.empty())
+ {
+ SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ SetSentErrorMessage(true);
return false;
+ }
- std::string name = name_str;
-
- if(!normalizePlayerName(name))
+ char* msg_str = strtok(NULL, "");
+ if(!msg_str)
return false;
///- Find the player and check that he is not logging out.
@@ -6970,7 +7023,8 @@ bool ChatHandler::HandleSendMessageCommand(const char* args)
rPlayer->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r");
//Confirmation message
- PSendSysMessage(LANG_SENDMESSAGE,name.c_str(),msg_str);
+ std::string nameLink = playerLink(name);
+ PSendSysMessage(LANG_SENDMESSAGE,nameLink.c_str(),msg_str);
return true;
}
@@ -6994,30 +7048,27 @@ bool ChatHandler::HandleModifyGenderCommand(const char *args)
return false;
}
+ PlayerInfo const* info = objmgr.GetPlayerInfo(player->getRace(), player->getClass());
+ if(!info)
+ return false;
+
char const* gender_str = (char*)args;
int gender_len = strlen(gender_str);
- uint32 displayId = player->GetNativeDisplayId();
- char const* gender_full = NULL;
- uint32 new_displayId = displayId;
Gender gender;
- if(!strncmp(gender_str,"male",gender_len)) // MALE
+ if(!strncmp(gender_str, "male", gender_len)) // MALE
{
if(player->getGender() == GENDER_MALE)
return true;
- gender_full = "male";
- new_displayId = player->getRace() == RACE_BLOODELF ? displayId+1 : displayId-1;
gender = GENDER_MALE;
}
- else if (!strncmp(gender_str,"female",gender_len)) // FEMALE
+ else if (!strncmp(gender_str, "female", gender_len)) // FEMALE
{
if(player->getGender() == GENDER_FEMALE)
return true;
- gender_full = "female";
- new_displayId = player->getRace() == RACE_BLOODELF ? displayId-1 : displayId+1;
gender = GENDER_FEMALE;
}
else
@@ -7029,14 +7080,19 @@ bool ChatHandler::HandleModifyGenderCommand(const char *args)
// Set gender
player->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender);
+ player->SetByteValue(PLAYER_BYTES_3, 0, gender);
// Change display ID
- player->SetDisplayId(new_displayId);
- player->SetNativeDisplayId(new_displayId);
+ player->SetDisplayId(gender ? info->displayId_f : info->displayId_m);
+ player->SetNativeDisplayId(gender ? info->displayId_f : info->displayId_m);
+
+ char const* gender_full = gender ? "female" : "male";
+
+ PSendSysMessage(LANG_YOU_CHANGE_GENDER, GetNameLink(player).c_str(), gender_full);
- PSendSysMessage(LANG_YOU_CHANGE_GENDER, player->GetName(),gender_full);
if (needReportToTarget(player))
- ChatHandler(player).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full,GetName());
+ ChatHandler(player).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full, GetNameLink().c_str());
+
return true;
}
diff --git a/src/game/LootHandler.cpp b/src/game/LootHandler.cpp
index a4a8a7a1f01..438b3922cb6 100644
--- a/src/game/LootHandler.cpp
+++ b/src/game/LootHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -154,6 +154,7 @@ void WorldSession::HandleAutostoreLootItemOpcode( WorldPacket & recv_data )
--loot->unlootedCount;
player->SendNewItem(newitem, uint32(item->count), false, false, true);
+ player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item->itemid, item->count);
}
else
player->SendEquipError( msg, NULL, NULL );
@@ -326,7 +327,7 @@ void WorldSession::DoLootRelease( uint64 lguid )
int32 ReqValue = 175;
LockEntry const *lockInfo = sLockStore.LookupEntry(go->GetGOInfo()->chest.lockId);
if(lockInfo)
- ReqValue = lockInfo->requiredminingskill;
+ ReqValue = lockInfo->Skill[0];
float skill = float(player->GetSkillValue(SKILL_MINING))/(ReqValue+25);
double chance = pow(0.8*chance_rate,4*(1/double(max_amount))*double(uses));
if(roll_chance_f(100*chance+skill))
@@ -383,14 +384,22 @@ void WorldSession::DoLootRelease( uint64 lguid )
Item *pItem = player->GetItemByGuid(lguid );
if(!pItem)
return;
- if( (pItem->GetProto()->BagFamily & BAG_FAMILY_MASK_MINING_SUPP) &&
- pItem->GetProto()->Class == ITEM_CLASS_TRADE_GOODS &&
- pItem->GetCount() >= 5)
+
+ ItemPrototype const* proto = pItem->GetProto();
+
+ // destroy only 5 items from stack in case prospecting and milling
+ if( (proto->BagFamily & (BAG_FAMILY_MASK_MINING_SUPP|BAG_FAMILY_MASK_HERBS)) &&
+ proto->Class == ITEM_CLASS_TRADE_GOODS)
{
pItem->m_lootGenerated = false;
pItem->loot.clear();
- uint32 count = 5;
+ uint32 count = pItem->GetCount();
+
+ // >=5 checked in spell code, but will work for cheating cases also with removing from another stacks.
+ if(count > 5)
+ count = 5;
+
player->DestroyItemCount(pItem, count, true);
}
else
@@ -495,6 +504,7 @@ void WorldSession::HandleLootMasterGiveOpcode( WorldPacket & recv_data )
// not move item from loot to target inventory
Item * newitem = target->StoreNewItem( dest, item.itemid, true, item.randomPropertyId );
target->SendNewItem(newitem, uint32(item.count), false, false, true );
+ target->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item.itemid, item.count);
// mark as looted
item.count=0;
diff --git a/src/game/LootMgr.cpp b/src/game/LootMgr.cpp
index 9271c14ed13..af310b452fe 100644
--- a/src/game/LootMgr.cpp
+++ b/src/game/LootMgr.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -25,6 +25,7 @@
#include "World.h"
#include "Util.h"
#include "SharedDefines.h"
+#include "SpellMgr.h"
static Rates const qualityToRate[MAX_ITEM_QUALITY] = {
RATE_DROP_ITEM_POOR, // ITEM_QUALITY_POOR
@@ -36,16 +37,18 @@ static Rates const qualityToRate[MAX_ITEM_QUALITY] = {
RATE_DROP_ITEM_ARTIFACT, // ITEM_QUALITY_ARTIFACT
};
-LootStore LootTemplates_Creature( "creature_loot_template", "creature entry");
-LootStore LootTemplates_Disenchant( "disenchant_loot_template", "item disenchant id");
-LootStore LootTemplates_Fishing( "fishing_loot_template", "area id");
-LootStore LootTemplates_Gameobject( "gameobject_loot_template", "gameobject entry");
-LootStore LootTemplates_Item( "item_loot_template", "item entry");
-LootStore LootTemplates_Pickpocketing("pickpocketing_loot_template","creature pickpocket lootid");
-LootStore LootTemplates_Prospecting( "prospecting_loot_template", "item entry");
-LootStore LootTemplates_QuestMail( "quest_mail_loot_template", "quest id");
-LootStore LootTemplates_Reference( "reference_loot_template", "reference id");
-LootStore LootTemplates_Skinning( "skinning_loot_template", "creature skinning id");
+LootStore LootTemplates_Creature( "creature_loot_template", "creature entry", true);
+LootStore LootTemplates_Disenchant( "disenchant_loot_template", "item disenchant id", true);
+LootStore LootTemplates_Fishing( "fishing_loot_template", "area id", true);
+LootStore LootTemplates_Gameobject( "gameobject_loot_template", "gameobject entry", true);
+LootStore LootTemplates_Item( "item_loot_template", "item entry", true);
+LootStore LootTemplates_Milling( "milling_loot_template", "item entry (herb)", true);
+LootStore LootTemplates_Pickpocketing("pickpocketing_loot_template","creature pickpocket lootid", true);
+LootStore LootTemplates_Prospecting( "prospecting_loot_template", "item entry (ore)", true);
+LootStore LootTemplates_QuestMail( "quest_mail_loot_template", "quest id (with mail template)",false);
+LootStore LootTemplates_Reference( "reference_loot_template", "reference id", false);
+LootStore LootTemplates_Skinning( "skinning_loot_template", "creature skinning id", true);
+LootStore LootTemplates_Spell( "spell_loot_template", "spell id (explicitly discovering ability)",false);
class LootTemplate::LootGroup // A set of loot definitions for items (refs are not allowed)
@@ -55,7 +58,7 @@ class LootTemplate::LootGroup // A set of loot def
bool HasQuestDrop() const; // True if group includes at least 1 quest drop entry
bool HasQuestDropForPlayer(Player const * player) const;
// The same for active quests of the player
- void Process(Loot& loot) const; // Rolls an item from the group (if any) and adds the item to the loot
+ void Process(Loot& loot, bool rate) const; // Rolls an item from the group (if any) and adds the item to the loot
float RawTotalChance() const; // Overall chance for the group (without equal chanced items)
float TotalChance() const; // Overall chance for the group
@@ -66,7 +69,7 @@ class LootTemplate::LootGroup // A set of loot def
LootStoreItemList ExplicitlyChanced; // Entries with chances defined in DB
LootStoreItemList EqualChanced; // Zero chances - every entry takes the same chance
- LootStoreItem const * Roll() const; // Rolls an item from the group, returns NULL if all miss their chances
+ LootStoreItem const * Roll(bool rate) const; // Rolls an item from the group, returns NULL if all miss their chances
};
//Remove all data and free all memory
@@ -230,17 +233,17 @@ void LootStore::ReportNotExistedId(uint32 id) const
// Checks if the entry (quest, non-quest, reference) takes it's chance (at loot generation)
// RATE_DROP_ITEMS is no longer used for all types of entries
-bool LootStoreItem::Roll() const
+bool LootStoreItem::Roll(bool rate) const
{
if(chance>=100.f)
return true;
if(mincountOrRef < 0) // reference case
- return roll_chance_f(chance*sWorld.getRate(RATE_DROP_ITEM_REFERENCED));
+ return roll_chance_f(chance* (rate ? sWorld.getRate(RATE_DROP_ITEM_REFERENCED) : 1.0f));
ItemPrototype const *pProto = objmgr.GetItemPrototype(itemid);
- float qualityModifier = pProto ? sWorld.getRate(qualityToRate[pProto->Quality]) : 1.0f;
+ float qualityModifier = pProto && rate ? sWorld.getRate(qualityToRate[pProto->Quality]) : 1.0f;
return roll_chance_f(chance*qualityModifier);
}
@@ -366,8 +369,12 @@ void Loot::AddItem(LootStoreItem const & item)
}
// Calls processor of corresponding LootTemplate (which handles everything including references)
-void Loot::FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner)
+void Loot::FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner, bool personal)
{
+ // Must be provided
+ if(!loot_owner)
+ return;
+
LootTemplate const* tab = store.GetLootFor(loot_id);
if (!tab)
@@ -379,37 +386,36 @@ void Loot::FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner)
items.reserve(MAX_NR_LOOT_ITEMS);
quest_items.reserve(MAX_NR_QUEST_ITEMS);
- tab->Process(*this, store); // Processing is done there, callback via Loot::AddItem()
+ tab->Process(*this, store,store.IsRatesAllowed ()); // Processing is done there, callback via Loot::AddItem()
- // Setting access rights fow group-looting case
- if(!loot_owner)
- return;
+ // Setting access rights for group loot case
Group * pGroup=loot_owner->GetGroup();
- if(!pGroup)
- return;
- for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
+ if(!personal && pGroup)
{
- //fill the quest item map for every player in the recipient's group
- Player* pl = itr->getSource();
- if(!pl)
- continue;
- uint32 plguid = pl->GetGUIDLow();
- QuestItemMap::iterator qmapitr = PlayerQuestItems.find(plguid);
- if (qmapitr == PlayerQuestItems.end())
- {
- FillQuestLoot(pl);
- }
- qmapitr = PlayerFFAItems.find(plguid);
- if (qmapitr == PlayerFFAItems.end())
- {
- FillFFALoot(pl);
- }
- qmapitr = PlayerNonQuestNonFFAConditionalItems.find(plguid);
- if (qmapitr == PlayerNonQuestNonFFAConditionalItems.end())
- {
- FillNonQuestNonFFAConditionalLoot(pl);
- }
+ for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
+ if(Player* pl = itr->getSource())
+ FillNotNormalLootFor(pl);
}
+ // ... for personal loot
+ else
+ FillNotNormalLootFor(loot_owner);
+}
+
+void Loot::FillNotNormalLootFor(Player* pl)
+{
+ uint32 plguid = pl->GetGUIDLow();
+
+ QuestItemMap::iterator qmapitr = PlayerQuestItems.find(plguid);
+ if (qmapitr == PlayerQuestItems.end())
+ FillQuestLoot(pl);
+
+ qmapitr = PlayerFFAItems.find(plguid);
+ if (qmapitr == PlayerFFAItems.end())
+ FillFFALoot(pl);
+
+ qmapitr = PlayerNonQuestNonFFAConditionalItems.find(plguid);
+ if (qmapitr == PlayerNonQuestNonFFAConditionalItems.end())
+ FillNonQuestNonFFAConditionalLoot(pl);
}
QuestItemList* Loot::FillFFALoot(Player* player)
@@ -640,6 +646,12 @@ LootItem* Loot::LootItemInSlot(uint32 lootSlot, Player* player, QuestItem **qite
return item;
}
+uint32 Loot::GetMaxSlotInLootFor(Player* player) const
+{
+ QuestItemMap::const_iterator itr = PlayerQuestItems.find(player->GetGUIDLow());
+ return items.size() + (itr != PlayerQuestItems.end() ? itr->second->size() : 0);
+}
+
ByteBuffer& operator<<(ByteBuffer& b, LootItem const& li)
{
b << uint32(li.itemid);
@@ -653,12 +665,19 @@ ByteBuffer& operator<<(ByteBuffer& b, LootItem const& li)
ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
{
+ if (lv.permission == NONE_PERMISSION)
+ {
+ b << uint32(0); //gold
+ b << uint8(0); // item count
+ return b; // nothing output more
+ }
+
Loot &l = lv.loot;
uint8 itemsShown = 0;
//gold
- b << uint32(lv.permission!=NONE_PERMISSION ? l.gold : 0);
+ b << uint32(l.gold);
size_t count_pos = b.wpos(); // pos of item count byte
b << uint8(0); // item count placeholder
@@ -697,19 +716,21 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
}
break;
}
- case NONE_PERMISSION:
default:
return b; // nothing output more
}
- if (lv.qlist)
+ QuestItemMap const& lootPlayerQuestItems = l.GetPlayerQuestItems();
+ QuestItemMap::const_iterator q_itr = lootPlayerQuestItems.find(lv.viewer->GetGUIDLow());
+ if (q_itr != lootPlayerQuestItems.end())
{
- for (QuestItemList::iterator qi = lv.qlist->begin() ; qi != lv.qlist->end(); ++qi)
+ QuestItemList *q_list = q_itr->second;
+ for (QuestItemList::iterator qi = q_list->begin() ; qi != q_list->end(); ++qi)
{
LootItem &item = l.quest_items[qi->index];
if (!qi->is_looted && !item.is_looted)
{
- b << uint8(l.items.size() + (qi - lv.qlist->begin()));
+ b << uint8(l.items.size() + (qi - q_list->begin()));
b << item;
b << uint8(0); // allow loot
++itemsShown;
@@ -717,9 +738,12 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
}
}
- if (lv.ffalist)
+ QuestItemMap const& lootPlayerFFAItems = l.GetPlayerFFAItems();
+ QuestItemMap::const_iterator ffa_itr = lootPlayerFFAItems.find(lv.viewer->GetGUIDLow());
+ if (ffa_itr != lootPlayerFFAItems.end())
{
- for (QuestItemList::iterator fi = lv.ffalist->begin() ; fi != lv.ffalist->end(); ++fi)
+ QuestItemList *ffa_list = ffa_itr->second;
+ for (QuestItemList::iterator fi = ffa_list->begin() ; fi != ffa_list->end(); ++fi)
{
LootItem &item = l.items[fi->index];
if (!fi->is_looted && !item.is_looted)
@@ -731,9 +755,12 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
}
}
- if (lv.conditionallist)
+ QuestItemMap const& lootPlayerNonQuestNonFFAConditionalItems = l.GetPlayerNonQuestNonFFAConditionalItems();
+ QuestItemMap::const_iterator nn_itr = lootPlayerNonQuestNonFFAConditionalItems.find(lv.viewer->GetGUIDLow());
+ if (nn_itr != lootPlayerNonQuestNonFFAConditionalItems.end())
{
- for (QuestItemList::iterator ci = lv.conditionallist->begin() ; ci != lv.conditionallist->end(); ++ci)
+ QuestItemList *conditional_list = nn_itr->second;
+ for (QuestItemList::iterator ci = conditional_list->begin() ; ci != conditional_list->end(); ++ci)
{
LootItem &item = l.items[ci->index];
if (!ci->is_looted && !item.is_looted)
@@ -765,7 +792,7 @@ void LootTemplate::LootGroup::AddEntry(LootStoreItem& item)
}
// Rolls an item from the group, returns NULL if all miss their chances
-LootStoreItem const * LootTemplate::LootGroup::Roll() const
+LootStoreItem const * LootTemplate::LootGroup::Roll(bool rate) const
{
if (!ExplicitlyChanced.empty()) // First explicitly chanced entries are checked
{
@@ -777,7 +804,8 @@ LootStoreItem const * LootTemplate::LootGroup::Roll() const
return &ExplicitlyChanced[i];
ItemPrototype const *pProto = objmgr.GetItemPrototype(ExplicitlyChanced[i].itemid);
- Roll -= ExplicitlyChanced[i].chance;
+ //float qualityMultiplier = pProto && rate ? sWorld.getRate(qualityToRate[pProto->Quality]) : 1.0f;
+ Roll -= ExplicitlyChanced[i].chance;// * qualityMultiplier;
if (Roll < 0)
return &ExplicitlyChanced[i];
}
@@ -813,9 +841,9 @@ bool LootTemplate::LootGroup::HasQuestDropForPlayer(Player const * player) const
}
// Rolls an item from the group (if any takes its chance) and adds the item to the loot
-void LootTemplate::LootGroup::Process(Loot& loot) const
+void LootTemplate::LootGroup::Process(Loot& loot, bool rate) const
{
- LootStoreItem const * item = Roll();
+ LootStoreItem const * item = Roll(rate);
if (item != NULL)
loot.AddItem(*item);
}
@@ -900,21 +928,21 @@ void LootTemplate::AddEntry(LootStoreItem& item)
}
// Rolls for every item in the template and adds the rolled items the the loot
-void LootTemplate::Process(Loot& loot, LootStore const& store, uint8 groupId) const
+void LootTemplate::Process(Loot& loot, LootStore const& store, bool rate, uint8 groupId) const
{
if (groupId) // Group reference uses own processing of the group
{
if (groupId > Groups.size())
return; // Error message already printed at loading stage
- Groups[groupId-1].Process(loot);
+ Groups[groupId-1].Process(loot,rate);
return;
}
// Rolling non-grouped items
for (LootStoreItemList::const_iterator i = Entries.begin() ; i != Entries.end() ; ++i )
{
- if ( !i->Roll() )
+ if (!i->Roll(rate))
continue; // Bad luck for the entry
if (i->mincountOrRef < 0) // References processing
@@ -925,7 +953,7 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, uint8 groupId) co
continue; // Error message already printed at loading stage
for (uint32 loop=0; loop < i->maxcount; ++loop )// Ref multiplicator
- Referenced->Process(loot, store, i->group); // Ref processing
+ Referenced->Process(loot, store, rate, i->group);
}
else // Plain entries (not a reference, not grouped)
loot.AddItem(*i); // Chance is already checked, just add
@@ -933,7 +961,7 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, uint8 groupId) co
// Now processing groups
for (LootGroups::const_iterator i = Groups.begin( ) ; i != Groups.end( ) ; ++i )
- i->Process(loot);
+ i->Process(loot,rate);
}
// True if template includes at least 1 quest drop entry
@@ -995,7 +1023,7 @@ bool LootTemplate::HasQuestDropForPlayer(LootTemplateMap const& store, Player co
// Now checking groups
for (LootGroups::const_iterator i = Groups.begin(); i != Groups.end(); ++i )
- if (i->HasQuestDrop())
+ if (i->HasQuestDropForPlayer(player))
return true;
return false;
@@ -1137,6 +1165,29 @@ void LoadLootTemplates_Item()
LootTemplates_Item.ReportUnusedIds(ids_set);
}
+void LoadLootTemplates_Milling()
+{
+ LootIdSet ids_set;
+ LootTemplates_Milling.LoadAndCollectLootIds(ids_set);
+
+ // remove real entries and check existence loot
+ for(uint32 i = 1; i < sItemStorage.MaxEntry; ++i )
+ {
+ ItemPrototype const* proto = sItemStorage.LookupEntry<ItemPrototype>(i);
+ if(!proto)
+ continue;
+
+ if((proto->BagFamily & BAG_FAMILY_MASK_HERBS)==0)
+ continue;
+
+ if(ids_set.count(proto->ItemId))
+ ids_set.erase(proto->ItemId);
+ }
+
+ // output error for any still listed (not referenced from appropriate table) ids
+ LootTemplates_Milling.ReportUnusedIds(ids_set);
+}
+
void LoadLootTemplates_Pickpocketing()
{
LootIdSet ids_set, ids_setUsed;
@@ -1170,9 +1221,17 @@ void LoadLootTemplates_Prospecting()
// remove real entries and check existence loot
for(uint32 i = 1; i < sItemStorage.MaxEntry; ++i )
- if(ItemPrototype const* proto = sItemStorage.LookupEntry<ItemPrototype>(i))
- if(ids_set.count(proto->ItemId))
- ids_set.erase(proto->ItemId);
+ {
+ ItemPrototype const* proto = sItemStorage.LookupEntry<ItemPrototype>(i);
+ if(!proto)
+ continue;
+
+ if((proto->BagFamily & BAG_FAMILY_MASK_MINING_SUPP)==0)
+ continue;
+
+ if(ids_set.count(proto->ItemId))
+ ids_set.erase(proto->ItemId);
+ }
// output error for any still listed (not referenced from appropriate table) ids
LootTemplates_Prospecting.ReportUnusedIds(ids_set);
@@ -1186,8 +1245,17 @@ void LoadLootTemplates_QuestMail()
// remove real entries and check existence loot
ObjectMgr::QuestMap const& questMap = objmgr.GetQuestTemplates();
for(ObjectMgr::QuestMap::const_iterator itr = questMap.begin(); itr != questMap.end(); ++itr )
+ {
+ if(!itr->second->GetRewMailTemplateId())
+ continue;
+
if(ids_set.count(itr->first))
ids_set.erase(itr->first);
+ /* disabled reporting: some quest mails not include items
+ else
+ LootTemplates_QuestMail.ReportNotExistedId(itr->first);
+ */
+ }
// output error for any still listed (not referenced from appropriate table) ids
LootTemplates_QuestMail.ReportUnusedIds(ids_set);
@@ -1219,6 +1287,37 @@ void LoadLootTemplates_Skinning()
LootTemplates_Skinning.ReportUnusedIds(ids_set);
}
+void LoadLootTemplates_Spell()
+{
+ LootIdSet ids_set;
+ LootTemplates_Spell.LoadAndCollectLootIds(ids_set);
+
+ // remove real entries and check existence loot
+ for(uint32 spell_id = 1; spell_id < sSpellStore.GetNumRows(); ++spell_id)
+ {
+ SpellEntry const* spellInfo = sSpellStore.LookupEntry (spell_id);
+ if(!spellInfo)
+ continue;
+
+ // possible cases
+ if( !IsLootCraftingSpell(spellInfo))
+ continue;
+
+ if(!ids_set.count(spell_id))
+ {
+ // not report about not trainable spells (optionally supported by DB) except with SPELL_ATTR_EX2_UNK14 (clams)
+ // 61756 (Northrend Inscription Research (FAST QA VERSION) for example
+ if ((spellInfo->Attributes & SPELL_ATTR_UNK5) || (spellInfo->AttributesEx2 & SPELL_ATTR_EX2_UNK14))
+ LootTemplates_Spell.ReportNotExistedId(spell_id);
+ }
+ else
+ ids_set.erase(spell_id);
+ }
+
+ // output error for any still listed (not referenced from appropriate table) ids
+ LootTemplates_QuestMail.ReportUnusedIds(ids_set);
+}
+
void LoadLootTemplates_Reference()
{
LootIdSet ids_set;
@@ -1229,6 +1328,7 @@ void LoadLootTemplates_Reference()
LootTemplates_Fishing.CheckLootRefs(&ids_set);
LootTemplates_Gameobject.CheckLootRefs(&ids_set);
LootTemplates_Item.CheckLootRefs(&ids_set);
+ LootTemplates_Milling.CheckLootRefs(&ids_set);
LootTemplates_Pickpocketing.CheckLootRefs(&ids_set);
LootTemplates_Skinning.CheckLootRefs(&ids_set);
LootTemplates_Disenchant.CheckLootRefs(&ids_set);
diff --git a/src/game/LootMgr.h b/src/game/LootMgr.h
index 1cb02c29bfc..8f54bb3bee1 100644
--- a/src/game/LootMgr.h
+++ b/src/game/LootMgr.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -77,7 +77,7 @@ struct LootStoreItem
group(_group), maxcount(_maxcount), conditionId(_conditionId),
needs_quest(_chanceOrQuestChance < 0) {}
- bool Roll() const; // Checks if the entry takes it's chance (at loot generation)
+ bool Roll(bool rate) const; // Checks if the entry takes it's chance (at loot generation)
bool IsValid(LootStore const& store, uint32 entry) const;
// Checks correctness of values
};
@@ -129,7 +129,8 @@ typedef std::set<uint32> LootIdSet;
class LootStore
{
public:
- explicit LootStore(char const* name, char const* entryName) : m_name(name), m_entryName(entryName) {}
+ explicit LootStore(char const* name, char const* entryName, bool ratesAllowed)
+ : m_name(name), m_entryName(entryName), m_ratesAllowed(ratesAllowed) {}
virtual ~LootStore() { Clear(); }
void Verify() const;
@@ -147,6 +148,7 @@ class LootStore
char const* GetName() const { return m_name; }
char const* GetEntryName() const { return m_entryName; }
+ bool IsRatesAllowed() const { return m_ratesAllowed; }
protected:
void LoadLootTable();
void Clear();
@@ -154,6 +156,7 @@ class LootStore
LootTemplateMap m_LootTemplates;
char const* m_name;
char const* m_entryName;
+ bool m_ratesAllowed;
};
class LootTemplate
@@ -165,7 +168,7 @@ class LootTemplate
// Adds an entry to the group (at loading stage)
void AddEntry(LootStoreItem& item);
// Rolls for every item in the template and adds the rolled items the the loot
- void Process(Loot& loot, LootStore const& store, uint8 GroupId = 0) const;
+ void Process(Loot& loot, LootStore const& store, bool rate, uint8 GroupId = 0) const;
// True if template includes at least 1 quest drop entry
bool HasQuestDrop(LootTemplateMap const& store, uint8 GroupId = 0) const;
@@ -207,19 +210,20 @@ class LootValidatorRefManager : public RefManager<Loot, LootValidatorRef>
};
//=====================================================
+struct LootView;
+
+ByteBuffer& operator<<(ByteBuffer& b, LootItem const& li);
+ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv);
struct Loot
{
+ friend ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv);
+
QuestItemMap const& GetPlayerQuestItems() const { return PlayerQuestItems; }
QuestItemMap const& GetPlayerFFAItems() const { return PlayerFFAItems; }
QuestItemMap const& GetPlayerNonQuestNonFFAConditionalItems() const { return PlayerNonQuestNonFFAConditionalItems; }
- QuestItemList* FillFFALoot(Player* player);
- QuestItemList* FillQuestLoot(Player* player);
- QuestItemList* FillNonQuestNonFFAConditionalLoot(Player* player);
-
std::vector<LootItem> items;
- std::vector<LootItem> quest_items;
uint32 gold;
uint8 unlootedCount;
@@ -264,13 +268,21 @@ struct Loot
void RemoveLooter(uint64 GUID) { PlayersLooting.erase(GUID); }
void generateMoneyLoot(uint32 minAmount, uint32 maxAmount);
- void FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner);
+ void FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner, bool personal);
// Inserts the item into the loot (called by LootTemplate processors)
void AddItem(LootStoreItem const & item);
LootItem* LootItemInSlot(uint32 lootslot, Player* player, QuestItem** qitem = NULL, QuestItem** ffaitem = NULL, QuestItem** conditem = NULL);
+ uint32 GetMaxSlotInLootFor(Player* player) const;
+
private:
+ void FillNotNormalLootFor(Player* player);
+ QuestItemList* FillFFALoot(Player* player);
+ QuestItemList* FillQuestLoot(Player* player);
+ QuestItemList* FillNonQuestNonFFAConditionalLoot(Player* player);
+
+ std::vector<LootItem> quest_items;
std::set<uint64> PlayersLooting;
QuestItemMap PlayerQuestItems;
QuestItemMap PlayerFFAItems;
@@ -278,40 +290,41 @@ struct Loot
// All rolls are registered here. They need to know, when the loot is not valid anymore
LootValidatorRefManager i_LootValidatorRefManager;
-
};
struct LootView
{
Loot &loot;
- QuestItemList *qlist;
- QuestItemList *ffalist;
- QuestItemList *conditionallist;
Player *viewer;
PermissionTypes permission;
- LootView(Loot &_loot, QuestItemList *_qlist, QuestItemList *_ffalist, QuestItemList *_conditionallist, Player *_viewer,PermissionTypes _permission = ALL_PERMISSION)
- : loot(_loot), qlist(_qlist), ffalist(_ffalist), conditionallist(_conditionallist), viewer(_viewer), permission(_permission) {}
+ LootView(Loot &_loot, Player *_viewer,PermissionTypes _permission = ALL_PERMISSION)
+ : loot(_loot), viewer(_viewer), permission(_permission) {}
};
extern LootStore LootTemplates_Creature;
extern LootStore LootTemplates_Fishing;
extern LootStore LootTemplates_Gameobject;
extern LootStore LootTemplates_Item;
+extern LootStore LootTemplates_Milling;
extern LootStore LootTemplates_Pickpocketing;
extern LootStore LootTemplates_Skinning;
extern LootStore LootTemplates_Disenchant;
extern LootStore LootTemplates_Prospecting;
extern LootStore LootTemplates_QuestMail;
+extern LootStore LootTemplates_Spell;
void LoadLootTemplates_Creature();
void LoadLootTemplates_Fishing();
void LoadLootTemplates_Gameobject();
void LoadLootTemplates_Item();
+void LoadLootTemplates_Milling();
void LoadLootTemplates_Pickpocketing();
void LoadLootTemplates_Skinning();
void LoadLootTemplates_Disenchant();
void LoadLootTemplates_Prospecting();
void LoadLootTemplates_QuestMail();
+
+void LoadLootTemplates_Spell();
void LoadLootTemplates_Reference();
inline void LoadLootTables()
@@ -320,14 +333,15 @@ inline void LoadLootTables()
LoadLootTemplates_Fishing();
LoadLootTemplates_Gameobject();
LoadLootTemplates_Item();
+ LoadLootTemplates_Milling();
LoadLootTemplates_Pickpocketing();
LoadLootTemplates_Skinning();
LoadLootTemplates_Disenchant();
LoadLootTemplates_Prospecting();
LoadLootTemplates_QuestMail();
+ LoadLootTemplates_Spell();
+
LoadLootTemplates_Reference();
}
-ByteBuffer& operator<<(ByteBuffer& b, LootItem const& li);
-ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv);
#endif
diff --git a/src/game/Mail.cpp b/src/game/Mail.cpp
index 48bf94c4411..a699d9acc4d 100644
--- a/src/game/Mail.cpp
+++ b/src/game/Mail.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -601,7 +601,7 @@ void WorldSession::HandleGetMail(WorldPacket & recv_data )
data << (uint32) (*itr)->mailTemplateId; // mail template (MailTemplate.dbc)
data << (*itr)->subject; // Subject string - once 00, when mail type = 3
- data << (uint8) item_count;
+ data << (uint8) item_count; // client limit is 0x10
for(uint8 i = 0; i < item_count; ++i)
{
@@ -612,7 +612,7 @@ void WorldSession::HandleGetMail(WorldPacket & recv_data )
data << (uint32) (item ? item->GetGUIDLow() : 0);
// entry
data << (uint32) (item ? item->GetEntry() : 0);
- for(uint8 j = 0; j < 6; ++j)
+ for(uint8 j = 0; j < MAX_INSPECTED_ENCHANTMENT_SLOT; ++j)
{
// unsure
data << (uint32) (item ? item->GetEnchantmentCharges((EnchantmentSlot)j) : 0);
@@ -626,13 +626,15 @@ void WorldSession::HandleGetMail(WorldPacket & recv_data )
// unk
data << (uint32) (item ? item->GetItemSuffixFactor() : 0);
// stack count
- data << (uint8) (item ? item->GetCount() : 0);
+ data << (uint32) (item ? item->GetCount() : 0);
// charges
data << (uint32) (item ? item->GetSpellCharges() : 0);
// durability
data << (uint32) (item ? item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY) : 0);
// durability
data << (uint32) (item ? item->GetUInt32Value(ITEM_FIELD_DURABILITY) : 0);
+ // unknown wotlk
+ data << (uint8) 0;
}
mails_count += 1;
diff --git a/src/game/Mail.h b/src/game/Mail.h
index f937c357325..ee4f6e54c4b 100644
--- a/src/game/Mail.h
+++ b/src/game/Mail.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/Makefile.am b/src/game/Makefile.am
index ec9cbab40cb..6107a75f20e 100644
--- a/src/game/Makefile.am
+++ b/src/game/Makefile.am
@@ -1,6 +1,6 @@
-# Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+# Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
#
-# Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+# Copyright (C) 2008-2009 Trinity <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
@@ -9,297 +9,304 @@
#
# 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
+# 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, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
## Process this file with automake to produce Makefile.in
## Sub-directories to parse
## CPP flags for includes, defines, etc.
-AM_CPPFLAGS =
+AM_CPPFLAGS = $(TRINI_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(srcdir)/../../dep/include -I$(srcdir)/../framework -I$(srcdir)/../shared -I$(srcdir)/../shared/vmap -I$(srcdir)/../realmd -DSYSCONFDIR=\"$(sysconfdir)/\"
## Build MaNGOS game library as convenience library.
# All libraries will be convenience libraries. Might be changed to shared
# later.
-noinst_LIBRARIES = libgame.a
-
-libgame_a_CPPFLAGS = \
-$(MYSQL_INCLUDES) \
-$(POSTGRE_INCLUDES) \
-$(TRINI_INCLUDES) \
--I$(top_srcdir)/dep/include \
--I$(top_srcdir)/src/framework \
--I$(top_srcdir)/src/shared \
--I$(top_srcdir)/src/shared/vmap
+noinst_LIBRARIES = libmangosgame.a
# libmangossgame library will later be reused by ...
-libgame_a_SOURCES = \
-$(srcdir)/AccountMgr.cpp \
-$(srcdir)/AccountMgr.h \
-$(srcdir)/AddonHandler.cpp \
-$(srcdir)/AddonHandler.h \
-$(srcdir)/AggressorAI.cpp \
-$(srcdir)/AggressorAI.h \
-$(srcdir)/AnimalRandomMovementGenerator.h \
-$(srcdir)/ArenaTeam.cpp \
-$(srcdir)/ArenaTeam.h \
-$(srcdir)/ArenaTeamHandler.cpp \
-$(srcdir)/AuctionHouse.cpp \
-$(srcdir)/AuctionHouseBot.cpp \
-$(srcdir)/AuctionHouseBot.h \
-$(srcdir)/AuctionHouseObject.h \
-$(srcdir)/Bag.cpp \
-$(srcdir)/Bag.h \
-$(srcdir)/BattleGround.cpp \
-$(srcdir)/BattleGroundAA.cpp \
-$(srcdir)/BattleGroundAB.cpp \
-$(srcdir)/BattleGroundAV.cpp \
-$(srcdir)/BattleGroundBE.cpp \
-$(srcdir)/BattleGroundEY.cpp \
-$(srcdir)/BattleGroundNA.cpp \
-$(srcdir)/BattleGroundRL.cpp \
-$(srcdir)/BattleGroundWS.cpp \
-$(srcdir)/BattleGround.h \
-$(srcdir)/BattleGroundAA.h \
-$(srcdir)/BattleGroundAB.h \
-$(srcdir)/BattleGroundAV.h \
-$(srcdir)/BattleGroundBE.h \
-$(srcdir)/BattleGroundEY.h \
-$(srcdir)/BattleGroundNA.h \
-$(srcdir)/BattleGroundRL.h \
-$(srcdir)/BattleGroundWS.h \
-$(srcdir)/BattleGroundHandler.cpp \
-$(srcdir)/BattleGroundMgr.cpp \
-$(srcdir)/BattleGroundMgr.h \
-$(srcdir)/Cell.h \
-$(srcdir)/CellImpl.h \
-$(srcdir)/Channel.cpp \
-$(srcdir)/Channel.h \
-$(srcdir)/ChannelHandler.cpp \
-$(srcdir)/ChannelMgr.h \
-$(srcdir)/CharacterHandler.cpp \
-$(srcdir)/Chat.cpp \
-$(srcdir)/Chat.h \
-$(srcdir)/ChatHandler.cpp \
-$(srcdir)/CombatHandler.cpp \
-$(srcdir)/ConfusedMovementGenerator.cpp \
-$(srcdir)/ConfusedMovementGenerator.h \
-$(srcdir)/Corpse.cpp \
-$(srcdir)/Corpse.h \
-$(srcdir)/CreatureAI.cpp \
-$(srcdir)/CreatureAI.h \
-$(srcdir)/CreatureAIImpl.h \
-$(srcdir)/CreatureAIRegistry.cpp \
-$(srcdir)/CreatureAIRegistry.h \
-$(srcdir)/CreatureAISelector.cpp \
-$(srcdir)/CreatureAISelector.h \
-$(srcdir)/CreatureGroups.cpp \
-$(srcdir)/CreatureGroups.h \
-$(srcdir)/Creature.cpp \
-$(srcdir)/Creature.h \
-$(srcdir)/Debugcmds.cpp \
-$(srcdir)/DestinationHolder.cpp \
-$(srcdir)/DestinationHolder.h \
-$(srcdir)/DestinationHolderImp.h \
-$(srcdir)/DuelHandler.cpp \
-$(srcdir)/DynamicObject.cpp \
-$(srcdir)/DynamicObject.h \
-$(srcdir)/FleeingMovementGenerator.cpp \
-$(srcdir)/FleeingMovementGenerator.h \
-$(srcdir)/Formulas.h \
-$(srcdir)/GameEvent.cpp \
-$(srcdir)/GameEvent.h \
-$(srcdir)/GameObject.cpp \
-$(srcdir)/GameObject.h \
-$(srcdir)/GlobalEvents.cpp \
-$(srcdir)/GlobalEvents.h \
-$(srcdir)/GossipDef.cpp \
-$(srcdir)/GossipDef.h \
-$(srcdir)/GridDefines.h \
-$(srcdir)/GridNotifiers.cpp \
-$(srcdir)/GridNotifiers.h \
-$(srcdir)/GridNotifiersImpl.h \
-$(srcdir)/GridStates.cpp \
-$(srcdir)/GridStates.h \
-$(srcdir)/Group.cpp \
-$(srcdir)/Group.h \
-$(srcdir)/GroupHandler.cpp \
-$(srcdir)/GuardAI.cpp \
-$(srcdir)/GuardAI.h \
-$(srcdir)/Guild.cpp \
-$(srcdir)/Guild.h \
-$(srcdir)/GuildHandler.cpp \
-$(srcdir)/HomeMovementGenerator.cpp \
-$(srcdir)/HomeMovementGenerator.h \
-$(srcdir)/HostilRefManager.cpp \
-$(srcdir)/HostilRefManager.h \
-$(srcdir)/IdleMovementGenerator.cpp \
-$(srcdir)/IdleMovementGenerator.h \
-$(srcdir)/InstanceData.cpp \
-$(srcdir)/InstanceData.h \
-$(srcdir)/InstanceSaveMgr.cpp \
-$(srcdir)/InstanceSaveMgr.h \
-$(srcdir)/Item.cpp \
-$(srcdir)/Item.h \
-$(srcdir)/ItemEnchantmentMgr.cpp \
-$(srcdir)/ItemEnchantmentMgr.h \
-$(srcdir)/ItemHandler.cpp \
-$(srcdir)/ItemPrototype.h \
-$(srcdir)/Language.h \
-$(srcdir)/Level0.cpp \
-$(srcdir)/Level1.cpp \
-$(srcdir)/Level2.cpp \
-$(srcdir)/Level3.cpp \
-$(srcdir)/LFGHandler.cpp \
-$(srcdir)/LootHandler.cpp \
-$(srcdir)/LootMgr.cpp \
-$(srcdir)/LootMgr.h \
-$(srcdir)/Mail.cpp \
-$(srcdir)/Mail.h \
-$(srcdir)/Map.cpp \
-$(srcdir)/Map.h \
-$(srcdir)/MapInstanced.cpp \
-$(srcdir)/MapInstanced.h \
-$(srcdir)/MapManager.cpp \
-$(srcdir)/MapManager.h \
-$(srcdir)/MiscHandler.cpp \
-$(srcdir)/MotionMaster.cpp \
-$(srcdir)/MotionMaster.h \
-$(srcdir)/MovementGenerator.cpp \
-$(srcdir)/MovementGenerator.h \
-$(srcdir)/MovementGeneratorImpl.h \
-$(srcdir)/MovementHandler.cpp \
-$(srcdir)/NPCHandler.cpp \
-$(srcdir)/NPCHandler.h \
-$(srcdir)/NullCreatureAI.cpp \
-$(srcdir)/NullCreatureAI.h \
-$(srcdir)/ObjectAccessor.cpp \
-$(srcdir)/ObjectAccessor.h \
-$(srcdir)/Object.cpp \
-$(srcdir)/ObjectDefines.h \
-$(srcdir)/ObjectGridLoader.cpp \
-$(srcdir)/ObjectGridLoader.h \
-$(srcdir)/Object.h \
-$(srcdir)/ObjectMgr.cpp \
-$(srcdir)/ObjectMgr.h \
-$(srcdir)/Opcodes.cpp \
-$(srcdir)/Opcodes.h \
-$(srcdir)/OutdoorPvP.cpp \
-$(srcdir)/OutdoorPvP.h \
-$(srcdir)/OutdoorPvPEP.cpp \
-$(srcdir)/OutdoorPvPEP.h \
-$(srcdir)/OutdoorPvPHP.cpp \
-$(srcdir)/OutdoorPvPHP.h \
-$(srcdir)/OutdoorPvPMgr.cpp \
-$(srcdir)/OutdoorPvPMgr.h \
-$(srcdir)/OutdoorPvPNA.cpp \
-$(srcdir)/OutdoorPvPNA.h \
-$(srcdir)/OutdoorPvPObjectiveAI.cpp \
-$(srcdir)/OutdoorPvPObjectiveAI.h \
-$(srcdir)/OutdoorPvPSI.cpp \
-$(srcdir)/OutdoorPvPSI.h \
-$(srcdir)/OutdoorPvPTF.cpp \
-$(srcdir)/OutdoorPvPTF.h \
-$(srcdir)/OutdoorPvPZM.cpp \
-$(srcdir)/OutdoorPvPZM.h \
-$(srcdir)/Path.h \
-$(srcdir)/PetAI.cpp \
-$(srcdir)/PetAI.h \
-$(srcdir)/Pet.cpp \
-$(srcdir)/Pet.h \
-$(srcdir)/PetHandler.cpp \
-$(srcdir)/PetitionsHandler.cpp \
-$(srcdir)/Player.cpp \
-$(srcdir)/Player.h \
-$(srcdir)/PlayerDump.cpp \
-$(srcdir)/PlayerDump.h \
-$(srcdir)/PointMovementGenerator.cpp \
-$(srcdir)/PointMovementGenerator.h \
-$(srcdir)/PossessedAI.cpp \
-$(srcdir)/PossessedAI.h \
-$(srcdir)/QueryHandler.cpp \
-$(srcdir)/QuestDef.cpp \
-$(srcdir)/QuestDef.h \
-$(srcdir)/QuestHandler.cpp \
-$(srcdir)/RandomMovementGenerator.cpp \
-$(srcdir)/RandomMovementGenerator.h \
-$(srcdir)/ReactorAI.cpp \
-$(srcdir)/ReactorAI.h \
-$(srcdir)/ScriptCalls.cpp \
-$(srcdir)/ScriptCalls.h \
-$(srcdir)/SharedDefines.h \
-$(srcdir)/SkillHandler.cpp \
-$(srcdir)/SpellAuraDefines.h \
-$(srcdir)/SpellAuras.cpp \
-$(srcdir)/SpellAuras.h \
-$(srcdir)/Spell.cpp \
-$(srcdir)/SpellEffects.cpp \
-$(srcdir)/Spell.h \
-$(srcdir)/SkillDiscovery.cpp \
-$(srcdir)/SkillDiscovery.h \
-$(srcdir)/SkillExtraItems.cpp \
-$(srcdir)/SkillExtraItems.h \
-$(srcdir)/SpellHandler.cpp \
-$(srcdir)/SocialMgr.cpp \
-$(srcdir)/SocialMgr.h \
-$(srcdir)/SpellMgr.cpp \
-$(srcdir)/SpellMgr.h \
-$(srcdir)/StatSystem.cpp \
-$(srcdir)/TargetedMovementGenerator.cpp \
-$(srcdir)/TargetedMovementGenerator.h \
-$(srcdir)/TaxiHandler.cpp \
-$(srcdir)/TemporarySummon.cpp \
-$(srcdir)/TemporarySummon.h \
-$(srcdir)/TicketHandler.cpp \
-$(srcdir)/TicketMgr.cpp \
-$(srcdir)/TicketMgr.h \
-$(srcdir)/Tools.cpp \
-$(srcdir)/Tools.h \
-$(srcdir)/TotemAI.cpp \
-$(srcdir)/TotemAI.h \
-$(srcdir)/Totem.cpp \
-$(srcdir)/Totem.h \
-$(srcdir)/TradeHandler.cpp \
-$(srcdir)/Transports.cpp \
-$(srcdir)/Transports.h \
-$(srcdir)/ThreatManager.cpp \
-$(srcdir)/ThreatManager.h \
-$(srcdir)/Traveller.h \
-$(srcdir)/Unit.cpp \
-$(srcdir)/Unit.h \
-$(srcdir)/UnitEvents.h \
-$(srcdir)/UpdateData.cpp \
-$(srcdir)/UpdateData.h \
-$(srcdir)/UpdateFields.h \
-$(srcdir)/UpdateMask.h \
-$(srcdir)/VoiceChatHandler.cpp \
-$(srcdir)/WaypointManager.cpp \
-$(srcdir)/WaypointManager.h \
-$(srcdir)/WaypointMovementGenerator.cpp \
-$(srcdir)/WaypointMovementGenerator.h \
-$(srcdir)/Weather.cpp \
-$(srcdir)/Weather.h \
-$(srcdir)/World.cpp \
-$(srcdir)/World.h \
-$(srcdir)/WorldLog.cpp \
-$(srcdir)/WorldLog.h \
-$(srcdir)/WorldSession.cpp \
-$(srcdir)/WorldSession.h \
-$(srcdir)/WorldSocket.cpp \
-$(srcdir)/WorldSocket.h \
-$(srcdir)/WorldSocketMgr.cpp \
-$(srcdir)/WorldSocketMgr.h \
-$(srcdir)/FollowerReference.cpp \
-$(srcdir)/FollowerReference.h \
-$(srcdir)/FollowerRefManager.h \
-$(srcdir)/GroupReference.cpp \
-$(srcdir)/GroupReference.h \
-$(srcdir)/GroupRefManager.h
+libmangosgame_a_SOURCES = \
+ AccountMgr.cpp \
+ AccountMgr.h \
+ AchievementMgr.h \
+ AchievementMgr.cpp \
+ AddonHandler.cpp \
+ AddonHandler.h \
+ AggressorAI.cpp \
+ AggressorAI.h \
+ AnimalRandomMovementGenerator.h \
+ ArenaTeam.cpp \
+ ArenaTeam.h \
+ ArenaTeamHandler.cpp \
+ AuctionHouse.cpp \
+ AuctionHouseObject.h \
+ Bag.cpp \
+ Bag.h \
+ BattleGround.cpp \
+ BattleGroundAA.cpp \
+ BattleGroundAB.cpp \
+ BattleGroundAV.cpp \
+ BattleGroundBE.cpp \
+ BattleGroundDS.cpp \
+ BattleGroundEY.cpp \
+ BattleGroundNA.cpp \
+ BattleGroundRL.cpp \
+ BattleGroundRV.cpp \
+ BattleGroundSA.cpp \
+ BattleGroundWS.cpp \
+ BattleGround.h \
+ BattleGroundAA.h \
+ BattleGroundAB.h \
+ BattleGroundAV.h \
+ BattleGroundBE.h \
+ BattleGroundDS.h \
+ BattleGroundEY.h \
+ BattleGroundNA.h \
+ BattleGroundRL.h \
+ BattleGroundRV.h \
+ BattleGroundSA.h \
+ BattleGroundWS.h \
+ BattleGroundHandler.cpp \
+ BattleGroundMgr.cpp \
+ BattleGroundMgr.h \
+ Calendar.cpp \
+ Calendar.h \
+ CalendarHandler.cpp \
+ Cell.h \
+ CellImpl.h \
+ Channel.cpp \
+ Channel.h \
+ ChannelHandler.cpp \
+ ChannelMgr.h \
+ CharacterHandler.cpp \
+ Chat.cpp \
+ Chat.h \
+ ChatHandler.cpp \
+ CombatHandler.cpp \
+ ConfusedMovementGenerator.cpp \
+ ConfusedMovementGenerator.h \
+ Corpse.cpp \
+ Corpse.h \
+ CreatureAI.cpp \
+ CreatureAI.h \
+ CreatureAIImpl.h \
+ CreatureAIRegistry.cpp \
+ CreatureAIRegistry.h \
+ CreatureAISelector.cpp \
+ CreatureAISelector.h \
+ CreatureGroups.cpp \
+ CreatureGroups.h \
+ Creature.cpp \
+ Creature.h \
+ debugcmds.cpp \
+ DestinationHolder.cpp \
+ DestinationHolder.h \
+ DestinationHolderImp.h \
+ DuelHandler.cpp \
+ DynamicObject.cpp \
+ DynamicObject.h \
+ FleeingMovementGenerator.cpp \
+ FleeingMovementGenerator.h \
+ Formulas.h \
+ GameEvent.cpp \
+ GameEvent.h \
+ GameObject.cpp \
+ GameObject.h \
+ GlobalEvents.cpp \
+ GlobalEvents.h \
+ GossipDef.cpp \
+ GossipDef.h \
+ GridDefines.h \
+ GridNotifiers.cpp \
+ GridNotifiers.h \
+ GridNotifiersImpl.h \
+ GridStates.cpp \
+ GridStates.h \
+ Group.cpp \
+ Group.h \
+ GroupHandler.cpp \
+ GuardAI.cpp \
+ GuardAI.h \
+ Guild.cpp \
+ Guild.h \
+ GuildHandler.cpp \
+ HomeMovementGenerator.cpp \
+ HomeMovementGenerator.h \
+ HostilRefManager.cpp \
+ HostilRefManager.h \
+ IdleMovementGenerator.cpp \
+ IdleMovementGenerator.h \
+ InstanceData.cpp \
+ InstanceData.h \
+ InstanceSaveMgr.cpp \
+ InstanceSaveMgr.h \
+ Item.cpp \
+ Item.h \
+ ItemEnchantmentMgr.cpp \
+ ItemEnchantmentMgr.h \
+ ItemHandler.cpp \
+ ItemPrototype.h \
+ Language.h \
+ Level0.cpp \
+ Level1.cpp \
+ Level2.cpp \
+ Level3.cpp \
+ LFGHandler.cpp \
+ LootHandler.cpp \
+ LootMgr.cpp \
+ LootMgr.h \
+ Mail.cpp \
+ Mail.h \
+ Map.cpp \
+ Map.h \
+ MapInstanced.cpp \
+ MapInstanced.h \
+ MapManager.cpp \
+ MapManager.h \
+ MapReference.h \
+ MapRefManager.h \
+ MiscHandler.cpp \
+ MotionMaster.cpp \
+ MotionMaster.h \
+ MovementGenerator.cpp \
+ MovementGenerator.h \
+ MovementGeneratorImpl.h \
+ MovementHandler.cpp \
+ NPCHandler.cpp \
+ NPCHandler.h \
+ NullCreatureAI.cpp \
+ NullCreatureAI.h \
+ ObjectAccessor.cpp \
+ ObjectAccessor.h \
+ Object.cpp \
+ ObjectDefines.h \
+ ObjectGridLoader.cpp \
+ ObjectGridLoader.h \
+ Object.h \
+ ObjectMgr.cpp \
+ ObjectMgr.h \
+ ObjectPosSelector.cpp \
+ ObjectPosSelector.h \
+ Opcodes.cpp \
+ Opcodes.h \
+ OutdoorPvP.cpp \
+ OutdoorPvP.h \
+ OutdoorPvPEP.cpp \
+ OutdoorPvPEP.h \
+ OutdoorPvPHP.cpp \
+ OutdoorPvPHP.h \
+ OutdoorPvPMgr.cpp \
+ OutdoorPvPMgr.h \
+ OutdoorPvPNA.cpp \
+ OutdoorPvPNA.h \
+ OutdoorPvPObjectiveAI.cpp \
+ OutdoorPvPObjectiveAI.h \
+ OutdoorPvPSI.cpp \
+ OutdoorPvPSI.h \
+ OutdoorPvPTF.cpp \
+ OutdoorPvPTF.h \
+ OutdoorPvPZM.cpp \
+ OutdoorPvPZM.h \
+ Path.h \
+ PetAI.cpp \
+ PetAI.h \
+ Pet.cpp \
+ Pet.h \
+ PetHandler.cpp \
+ PetitionsHandler.cpp \
+ Player.cpp \
+ Player.h \
+ PlayerDump.cpp \
+ PlayerDump.h \
+ PossessedAI.cpp \
+ PossessedAI.h \
+ PointMovementGenerator.cpp \
+ PointMovementGenerator.h \
+ QueryHandler.cpp \
+ QuestDef.cpp \
+ QuestDef.h \
+ QuestHandler.cpp \
+ RandomMovementGenerator.cpp \
+ RandomMovementGenerator.h \
+ ReactorAI.cpp \
+ ReactorAI.h \
+ ScriptCalls.cpp \
+ ScriptCalls.h \
+ SharedDefines.h \
+ SkillHandler.cpp \
+ SpellAuraDefines.h \
+ SpellAuras.cpp \
+ SpellAuras.h \
+ Spell.cpp \
+ SpellEffects.cpp \
+ Spell.h \
+ SkillDiscovery.cpp \
+ SkillDiscovery.h \
+ SkillExtraItems.cpp \
+ SkillExtraItems.h \
+ SpellHandler.cpp \
+ SocialMgr.cpp \
+ SocialMgr.h \
+ SpellMgr.cpp \
+ SpellMgr.h \
+ StatSystem.cpp \
+ TargetedMovementGenerator.cpp \
+ TargetedMovementGenerator.h \
+ TaxiHandler.cpp \
+ TemporarySummon.cpp \
+ TemporarySummon.h \
+ TotemAI.cpp \
+ TotemAI.h \
+ Totem.cpp \
+ Totem.h \
+ TradeHandler.cpp \
+ Transports.cpp \
+ Transports.h \
+ ThreatManager.cpp \
+ ThreatManager.h \
+ TicketHandler.cpp \
+ TicketMgr.cpp \
+ TicketMgr.h \
+ Traveller.h \
+ Unit.cpp \
+ Unit.h \
+ UnitEvents.h \
+ UpdateData.cpp \
+ UpdateData.h \
+ UpdateFields.h \
+ UpdateMask.h \
+ Vehicle.cpp \
+ Vehicle.h \
+ VoiceChatHandler.cpp \
+ WaypointManager.cpp \
+ WaypointManager.h \
+ WaypointMovementGenerator.cpp \
+ WaypointMovementGenerator.h \
+ Weather.cpp \
+ Weather.h \
+ World.cpp \
+ World.h \
+ WorldLog.cpp \
+ WorldLog.h \
+ WorldSession.cpp \
+ WorldSession.h \
+ WorldSocket.cpp \
+ WorldSocket.h \
+ WorldSocketMgr.cpp \
+ WorldSocketMgr.h \
+ FollowerReference.cpp \
+ FollowerReference.h \
+ FollowerRefManager.h \
+ GroupReference.cpp \
+ GroupReference.h \
+ GroupRefManager.h
+
+## Link against shared library
+libmangosgame_a_LIBADD = ../shared/libmangosshared.a ../shared/Auth/libmangosauth.a ../shared/Config/libmangosconfig.a ../shared/Database/libmangosdatabase.a ../shared/vmap/libmangosvmaps.a
## Additional files to include when running 'make dist'
# Nothing yet.
diff --git a/src/game/Map.cpp b/src/game/Map.cpp
index dd62f1e1c9f..40df012410b 100644
--- a/src/game/Map.cpp
+++ b/src/game/Map.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -45,7 +45,7 @@
#define MAX_GRID_LOAD_TIME 50
// magic *.map header
-const char MAP_MAGIC[] = "MAP_2.00";
+const char MAP_MAGIC[] = "MAP_2.01";
GridState* si_GridStates[MAX_GRID_STATE];
@@ -257,7 +257,7 @@ template<>
void Map::AddToGrid(Creature* obj, NGridType *grid, Cell const& cell)
{
// add to world object registry in grid
- if(obj->isPet() /*&& IS_PLAYER_GUID(obj->GetOwnerGUID())*/ || obj->isPossessedByPlayer())
+ if(obj->isPet() || obj->isPossessedByPlayer() || obj->isVehicle())
{
(*grid)(cell.CellX(), cell.CellY()).AddWorldObject<Creature>(obj, obj->GetGUID());
obj->SetCurrentCell(cell);
@@ -301,7 +301,7 @@ template<>
void Map::RemoveFromGrid(Creature* obj, NGridType *grid, Cell const& cell)
{
// remove from world object registry in grid
- if(obj->isPet() || obj->isPossessedByPlayer())
+ if(obj->isPet() || obj->isPossessedByPlayer() || obj->isVehicle())
{
(*grid)(cell.CellX(), cell.CellY()).RemoveWorldObject<Creature>(obj, obj->GetGUID());
}
@@ -1289,7 +1289,7 @@ float Map::GetVmapHeight(float x, float y, float z, bool useMaps) const
return vmapHeight;
}
-uint16 Map::GetAreaFlag(float x, float y ) const
+uint16 Map::GetAreaFlag(float x, float y, float z) const
{
//local x,y coords
float lx,ly;
@@ -1307,11 +1307,30 @@ uint16 Map::GetAreaFlag(float x, float y ) const
// ensure GridMap is loaded
const_cast<Map*>(this)->EnsureGridCreated(GridPair(63-gx,63-gy));
+ uint16 areaflag;
if(GridMaps[gx][gy])
- return GridMaps[gx][gy]->area_flag[(int)(lx)][(int)(ly)];
+ areaflag = GridMaps[gx][gy]->area_flag[(int)(lx)][(int)(ly)];
// this used while not all *.map files generated (instances)
else
- return GetAreaFlagByMapId(i_id);
+ areaflag = GetAreaFlagByMapId(i_id);
+
+ //FIXME: some hacks for areas above or underground for ground area
+ // required for area specific spells/etc, until map/vmap data
+ // not provided correct areaflag with this hacks
+ switch(areaflag)
+ {
+ // Acherus: The Ebon Hold (Plaguelands: The Scarlet Enclave)
+ case 1984: // Plaguelands: The Scarlet Enclave
+ case 2076: // Death's Breach (Plaguelands: The Scarlet Enclave)
+ case 2745: // The Noxious Pass (Plaguelands: The Scarlet Enclave)
+ if(z > 350.0f) areaflag = 2048; break;
+ // Acherus: The Ebon Hold (Eastern Plaguelands)
+ case 856: // The Noxious Glade (Eastern Plaguelands)
+ case 2456: // Death's Breach (Eastern Plaguelands)
+ if(z > 350.0f) areaflag = 1950; break;
+ }
+
+ return areaflag;
}
uint8 Map::GetTerrainType(float x, float y ) const
@@ -1752,10 +1771,10 @@ bool InstanceMap::CanEnter(Player *player)
}
// cannot enter if the instance is full (player cap), GMs don't count
- InstanceTemplate const* iTemplate = objmgr.GetInstanceTemplate(GetId());
- if (!player->isGameMaster() && GetPlayersCountExceptGMs() >= iTemplate->maxPlayers)
+ uint32 maxPlayers = GetMaxPlayers();
+ if (!player->isGameMaster() && GetPlayersCountExceptGMs() >= maxPlayers)
{
- sLog.outDetail("MAP: Instance '%u' of map '%s' cannot have more than '%u' players. Player '%s' rejected", GetInstanceId(), GetMapName(), iTemplate->maxPlayers, player->GetName());
+ sLog.outDetail("MAP: Instance '%u' of map '%s' cannot have more than '%u' players. Player '%s' rejected", GetInstanceId(), GetMapName(), maxPlayers, player->GetName());
player->SendTransferAborted(GetId(), TRANSFER_ABORT_MAX_PLAYERS);
return false;
}
@@ -2065,6 +2084,14 @@ void InstanceMap::SetResetSchedule(bool on)
}
}
+uint32 InstanceMap::GetMaxPlayers() const
+{
+ InstanceTemplate const* iTemplate = objmgr.GetInstanceTemplate(GetId());
+ if(!iTemplate)
+ return 0;
+ return IsHeroic() ? iTemplate->maxPlayersHeroic : iTemplate->maxPlayers;
+}
+
/* ******* Battleground Instance Maps ******* */
BattleGroundMap::BattleGroundMap(uint32 id, time_t expiry, uint32 InstanceId)
@@ -2120,12 +2147,14 @@ void BattleGroundMap::UnloadAll(bool pForce)
{
while(HavePlayers())
{
- Player * plr = m_mapRefManager.getFirst()->getSource();
- if(plr) (plr)->TeleportTo(plr->m_homebindMapId, plr->m_homebindX, plr->m_homebindY, plr->m_homebindZ, plr->GetOrientation());
- // TeleportTo removes the player from this map (if the map exists) -> calls BattleGroundMap::Remove -> invalidates the iterator.
- // just in case, remove the player from the list explicitly here as well to prevent a possible infinite loop
- // note that this remove is not needed if the code works well in other places
- plr->GetMapRef().unlink();
+ if(Player * plr = m_mapRefManager.getFirst()->getSource())
+ {
+ plr->TeleportTo(plr->GetBattleGroundEntryPoint());
+ // TeleportTo removes the player from this map (if the map exists) -> calls BattleGroundMap::Remove -> invalidates the iterator.
+ // just in case, remove the player from the list explicitly here as well to prevent a possible infinite loop
+ // note that this remove is not needed if the code works well in other places
+ plr->GetMapRef().unlink();
+ }
}
Map::UnloadAll(pForce);
diff --git a/src/game/Map.h b/src/game/Map.h
index 0c26fb36a00..92274932362 100644
--- a/src/game/Map.h
+++ b/src/game/Map.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -100,7 +100,8 @@ struct InstanceTemplate
uint32 levelMin;
uint32 levelMax;
uint32 maxPlayers;
- uint32 reset_delay;
+ uint32 maxPlayersHeroic;
+ uint32 reset_delay; // FIX ME: now exist normal/heroic raids with possible different time of reset.
float startLocX;
float startLocY;
float startLocZ;
@@ -135,10 +136,8 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
// currently unused for normal maps
bool CanUnload(uint32 diff)
{
- if(!m_unloadTimer)
- return false;
- if(m_unloadTimer <= diff)
- return true;
+ if(!m_unloadTimer) return false;
+ if(m_unloadTimer <= diff) return true;
m_unloadTimer -= diff;
return false;
}
@@ -160,7 +159,7 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
template<class LOCK_TYPE, class T, class CONTAINER> void Visit(const CellLock<LOCK_TYPE> &cell, TypeContainerVisitor<T, CONTAINER> &visitor);
- inline bool IsRemovalGrid(float x, float y) const
+ bool IsRemovalGrid(float x, float y) const
{
GridPair p = Trinity::ComputeGridPair(x, y);
return( !getNGrid(p.x_coord, p.y_coord) || getNGrid(p.x_coord, p.y_coord)->GetGridState() == GRID_STATE_REMOVAL );
@@ -194,7 +193,7 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
float GetVmapHeight(float x, float y, float z, bool useMaps) const;
bool IsInWater(float x, float y, float z) const; // does not use z pos. This is for future use
- uint16 GetAreaFlag(float x, float y ) const;
+ uint16 GetAreaFlag(float x, float y, float z) const;
uint8 GetTerrainType(float x, float y ) const;
float GetWaterLevel(float x, float y ) const;
bool IsUnderWater(float x, float y, float z) const;
@@ -202,14 +201,14 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
static uint32 GetAreaId(uint16 areaflag,uint32 map_id);
static uint32 GetZoneId(uint16 areaflag,uint32 map_id);
- uint32 GetAreaId(float x, float y) const
+ uint32 GetAreaId(float x, float y, float z) const
{
- return GetAreaId(GetAreaFlag(x,y),i_id);
+ return GetAreaId(GetAreaFlag(x,y,z),i_id);
}
- uint32 GetZoneId(float x, float y) const
+ uint32 GetZoneId(float x, float y, float z) const
{
- return GetZoneId(GetAreaFlag(x,y),i_id);
+ return GetZoneId(GetAreaFlag(x,y,z),i_id);
}
virtual void MoveAllCreaturesInMoveList();
@@ -233,6 +232,17 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
bool IsBattleGround() const { return i_mapEntry && i_mapEntry->IsBattleGround(); }
bool IsBattleArena() const { return i_mapEntry && i_mapEntry->IsBattleArena(); }
bool IsBattleGroundOrArena() const { return i_mapEntry && i_mapEntry->IsBattleGroundOrArena(); }
+ bool GetEntrancePos(int32 &mapid, float &x, float &y)
+ {
+ if(!i_mapEntry)
+ return false;
+ if(i_mapEntry->entrance_map < 0)
+ return false;
+ mapid = i_mapEntry->entrance_map;
+ x = i_mapEntry->entrance_x;
+ y = i_mapEntry->entrance_y;
+ return true;
+ }
void AddObjectToRemoveList(WorldObject *obj);
void DoDelayedMovesAndRemoves();
@@ -304,7 +314,7 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
bool isGridObjectDataLoaded(uint32 x, uint32 y) const { return getNGrid(x,y)->isGridObjectDataLoaded(); }
void setGridObjectDataLoaded(bool pLoaded, uint32 x, uint32 y) { getNGrid(x,y)->setGridObjectDataLoaded(pLoaded); }
- inline void setNGrid(NGridType* grid, uint32 x, uint32 y);
+ void setNGrid(NGridType* grid, uint32 x, uint32 y);
void UpdateActiveCells(const float &x, const float &y, const uint32 &t_diff);
protected:
@@ -375,6 +385,7 @@ class TRINITY_DLL_SPEC InstanceMap : public Map
bool CanEnter(Player* player);
void SendResetWarnings(uint32 timeLeft) const;
void SetResetSchedule(bool on);
+ uint32 GetMaxPlayers() const;
private:
bool m_resetAfterUnload;
bool m_unloadWhenEmpty;
diff --git a/src/game/MapInstanced.cpp b/src/game/MapInstanced.cpp
index 841d366b6c5..c61ed531c9a 100644
--- a/src/game/MapInstanced.cpp
+++ b/src/game/MapInstanced.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/MapInstanced.h b/src/game/MapInstanced.h
index cde37f9f3ff..924f77b8d82 100644
--- a/src/game/MapInstanced.h
+++ b/src/game/MapInstanced.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp
index fdd62d2d4ce..d159b1a6265 100644
--- a/src/game/MapManager.cpp
+++ b/src/game/MapManager.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -175,7 +175,8 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player)
//The player has a heroic mode and tries to enter into instance which has no a heroic mode
if (!entry->SupportsHeroicMode() && player->GetDifficulty() == DIFFICULTY_HEROIC)
{
- player->SendTransferAborted(mapid, TRANSFER_ABORT_DIFFICULTY2); //Send aborted message
+ //Send aborted message
+ player->SendTransferAborted(mapid, TRANSFER_ABORT_DIFFICULTY, DIFFICULTY_HEROIC);
return false;
}
@@ -240,7 +241,7 @@ void MapManager::RemoveBonesFromMap(uint32 mapid, uint64 guid, float x, float y)
}
void
-MapManager::Update(time_t diff)
+MapManager::Update(uint32 diff)
{
i_timer.Update(diff);
if( !i_timer.Passed() )
@@ -286,7 +287,8 @@ bool MapManager::ExistMapAndVMap(uint32 mapid, float x,float y)
bool MapManager::IsValidMAP(uint32 mapid)
{
MapEntry const* mEntry = sMapStore.LookupEntry(mapid);
- return mEntry && (!mEntry->Instanceable() || objmgr.GetInstanceTemplate(mapid));
+ return mEntry && (!mEntry->IsDungeon() || objmgr.GetInstanceTemplate(mapid));
+ // TODO: add check for battleground template
}
void MapManager::LoadGrid(int mapid, float x, float y, const WorldObject* obj, bool no_unload)
diff --git a/src/game/MapManager.h b/src/game/MapManager.h
index cba0a86d1a5..8d4b2ba8885 100644
--- a/src/game/MapManager.h
+++ b/src/game/MapManager.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -47,18 +47,18 @@ class TRINITY_DLL_DECL MapManager : public Trinity::Singleton<MapManager, Trinit
Map const* GetBaseMap(uint32 id) const { return const_cast<MapManager*>(this)->_GetBaseMap(id); }
void DeleteInstance(uint32 mapid, uint32 instanceId);
- inline uint16 GetAreaFlag(uint32 mapid, float x, float y) const
+ uint16 GetAreaFlag(uint32 mapid, float x, float y, float z) const
{
Map const* m = GetBaseMap(mapid);
- return m->GetAreaFlag(x, y);
+ return m->GetAreaFlag(x, y, z);
}
- inline uint32 GetAreaId(uint32 mapid, float x, float y) { return Map::GetAreaId(GetAreaFlag(mapid, x, y),mapid); }
- inline uint32 GetZoneId(uint32 mapid, float x, float y) { return Map::GetZoneId(GetAreaFlag(mapid, x, y),mapid); }
+ uint32 GetAreaId(uint32 mapid, float x, float y, float z) const { return Map::GetAreaId(GetAreaFlag(mapid, x, y, z),mapid); }
+ uint32 GetZoneId(uint32 mapid, float x, float y, float z) const { return Map::GetZoneId(GetAreaFlag(mapid, x, y, z),mapid); }
void Initialize(void);
- void Update(time_t);
+ void Update(uint32);
- inline void SetGridCleanUpDelay(uint32 t)
+ void SetGridCleanUpDelay(uint32 t)
{
if( t < MIN_GRID_DELAY )
i_gridCleanUpDelay = MIN_GRID_DELAY;
@@ -66,7 +66,7 @@ class TRINITY_DLL_DECL MapManager : public Trinity::Singleton<MapManager, Trinit
i_gridCleanUpDelay = t;
}
- inline void SetMapUpdateInterval(uint32 t)
+ void SetMapUpdateInterval(uint32 t)
{
if( t > MIN_MAP_UPDATE_DELAY )
t = MIN_MAP_UPDATE_DELAY;
@@ -96,6 +96,11 @@ class TRINITY_DLL_DECL MapManager : public Trinity::Singleton<MapManager, Trinit
return IsValidMAP(mapid) && Trinity::IsValidMapCoord(x,y,z,o);
}
+ static bool IsValidMapCoord(WorldLocation const& loc)
+ {
+ return IsValidMapCoord(loc.mapid,loc.x,loc.y,loc.z,loc.o);
+ }
+
void DoDelayedMovesAndRemoves();
void LoadTransports();
@@ -108,7 +113,7 @@ class TRINITY_DLL_DECL MapManager : public Trinity::Singleton<MapManager, Trinit
bool CanPlayerEnter(uint32 mapid, Player* player);
void RemoveBonesFromMap(uint32 mapid, uint64 guid, float x, float y);
- inline uint32 GenerateInstanceId() { return ++i_MaxInstanceId; }
+ uint32 GenerateInstanceId() { return ++i_MaxInstanceId; }
void InitMaxInstanceId();
/* statistics */
diff --git a/src/game/MapRefManager.h b/src/game/MapRefManager.h
index bfd0ca12eda..02f8b2ea465 100644
--- a/src/game/MapRefManager.h
+++ b/src/game/MapRefManager.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
+ * 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
diff --git a/src/game/MapReference.h b/src/game/MapReference.h
index 5300d1aa4a7..397eec0a06b 100644
--- a/src/game/MapReference.h
+++ b/src/game/MapReference.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
+ * 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
diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp
index a6b84d30de2..bae43ca26dc 100644
--- a/src/game/MiscHandler.cpp
+++ b/src/game/MiscHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -306,13 +306,13 @@ void WorldSession::HandleLogoutRequestOpcode( WorldPacket & /*recv_data*/ )
// not set flags if player can't free move to prevent lost state at logout cancel
if(GetPlayer()->CanFreeMove())
{
- GetPlayer()->SetStandState(PLAYER_STATE_SIT);
+ 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()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
+ GetPlayer()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
}
WorldPacket data( SMSG_LOGOUT_RESPONSE, 5 );
@@ -346,10 +346,10 @@ void WorldSession::HandleLogoutCancelOpcode( WorldPacket & /*recv_data*/ )
SendPacket( &data );
//! Stand Up
- GetPlayer()->SetStandState(PLAYER_STATE_NONE);
+ GetPlayer()->SetStandState(UNIT_STAND_STATE_STAND);
//! DISABLE_ROTATE
- GetPlayer()->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
+ GetPlayer()->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
}
sLog.outDebug( "WORLD: sent SMSG_LOGOUT_CANCEL_ACK Message" );
@@ -363,10 +363,12 @@ void WorldSession::HandleTogglePvP( WorldPacket & recv_data )
bool newPvPStatus;
recv_data >> newPvPStatus;
GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP, newPvPStatus);
+ GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_PVP_TIMER, !newPvPStatus);
}
else
{
GetPlayer()->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP);
+ GetPlayer()->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_PVP_TIMER);
}
if(GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP))
@@ -816,7 +818,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data)
GetPlayer()->SetRestType(REST_TYPE_IN_TAVERN);
if(sWorld.IsFFAPvPRealm())
- GetPlayer()->RemoveFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP);
+ GetPlayer()->RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
return;
}
@@ -886,7 +888,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data)
if(missingItem)
SendAreaTriggerMessage(GetTrinityString(LANG_LEVEL_MINREQUIRED_AND_ITEM), at->requiredLevel, objmgr.GetItemPrototype(missingItem)->Name1);
else if(missingKey)
- GetPlayer()->SendTransferAborted(at->target_mapId, TRANSFER_ABORT_DIFFICULTY2);
+ GetPlayer()->SendTransferAborted(at->target_mapId, TRANSFER_ABORT_DIFFICULTY, DIFFICULTY_HEROIC);
else if(missingHeroicQuest)
SendAreaTriggerMessage(at->heroicQuestFailedText.c_str());
else if(missingQuest)
@@ -900,16 +902,96 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data)
GetPlayer()->TeleportTo(at->target_mapId,at->target_X,at->target_Y,at->target_Z,at->target_Orientation,TELE_TO_NOT_LEAVE_TRANSPORT);
}
-void WorldSession::HandleUpdateAccountData(WorldPacket &/*recv_data*/)
+void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data)
{
sLog.outDetail("WORLD: Received CMSG_UPDATE_ACCOUNT_DATA");
- //recv_data.hexlike();
+
+ CHECK_PACKET_SIZE(recv_data, 4+4+4);
+
+ uint32 type, timestamp, decompressedSize;
+ recv_data >> type >> timestamp >> decompressedSize;
+
+ sLog.outDebug("UAD: type %u, time %u, decompressedSize %u", type, timestamp, decompressedSize);
+
+ if(type > NUM_ACCOUNT_DATA_TYPES)
+ return;
+
+ if(decompressedSize == 0) // erase
+ {
+ SetAccountData(type, timestamp, "");
+
+ WorldPacket data(SMSG_UPDATE_ACCOUNT_DATA_COMPLETE, 4+4);
+ data << uint32(type);
+ data << uint32(0);
+ SendPacket(&data);
+
+ return;
+ }
+
+ if(decompressedSize > 0xFFFF)
+ {
+ sLog.outError("UAD: Account data packet too big, size %u", decompressedSize);
+ return;
+ }
+
+ ByteBuffer dest;
+ dest.resize(decompressedSize);
+
+ uLongf realSize = decompressedSize;
+ if(uncompress(const_cast<uint8*>(dest.contents()), &realSize, const_cast<uint8*>(recv_data.contents() + recv_data.rpos()), recv_data.size() - recv_data.rpos()) != Z_OK)
+ {
+ sLog.outError("UAD: Failed to decompress account data");
+ return;
+ }
+
+ std::string adata;
+ dest >> adata;
+
+ SetAccountData(type, timestamp, adata);
+
+ WorldPacket data(SMSG_UPDATE_ACCOUNT_DATA_COMPLETE, 4+4);
+ data << uint32(type);
+ data << uint32(0);
+ SendPacket(&data);
}
-void WorldSession::HandleRequestAccountData(WorldPacket& /*recv_data*/)
+void WorldSession::HandleRequestAccountData(WorldPacket& recv_data)
{
sLog.outDetail("WORLD: Received CMSG_REQUEST_ACCOUNT_DATA");
- //recv_data.hexlike();
+
+ CHECK_PACKET_SIZE(recv_data, 4);
+
+ uint32 type;
+ recv_data >> type;
+
+ sLog.outDebug("RAD: type %u", type);
+
+ if(type > NUM_ACCOUNT_DATA_TYPES)
+ return;
+
+ AccountData *adata = GetAccountData(type);
+
+ uint32 size = adata->Data.size();
+
+ ByteBuffer dest;
+ dest.resize(size);
+
+ uLongf destSize = size;
+ if(size && compress(const_cast<uint8*>(dest.contents()), &destSize, (uint8*)adata->Data.c_str(), size) != Z_OK)
+ {
+ sLog.outDebug("RAD: Failed to compress account data");
+ return;
+ }
+
+ dest.resize(destSize);
+
+ WorldPacket data (SMSG_UPDATE_ACCOUNT_DATA, 8+4+4+4+destSize);
+ data << uint64(_player->GetGUID()); // player guid
+ data << uint32(type); // type (0-7)
+ data << uint32(adata->Time); // unix time
+ data << uint32(size); // decompressed length
+ data.append(dest); // compressed data
+ SendPacket(&data);
}
void WorldSession::HandleSetActionButtonOpcode(WorldPacket& recv_data)
@@ -1441,11 +1523,11 @@ void WorldSession::HandleChooseTitleOpcode( WorldPacket & recv_data )
GetPlayer()->SetUInt32Value(PLAYER_CHOSEN_TITLE, title);
}
-void WorldSession::HandleAllowMoveAckOpcode( WorldPacket & recv_data )
+void WorldSession::HandleTimeSyncResp( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE(recv_data, 4+4);
- sLog.outDebug("CMSG_ALLOW_MOVE_ACK");
+ sLog.outDebug("CMSG_TIME_SYNC_RESP");
uint32 counter, time_;
recv_data >> counter >> time_;
@@ -1515,26 +1597,6 @@ void WorldSession::HandleDungeonDifficultyOpcode( WorldPacket & recv_data )
}
}
-void WorldSession::HandleNewUnknownOpcode( WorldPacket & recv_data )
-{
- sLog.outDebug("New Unknown Opcode %u", recv_data.GetOpcode());
- recv_data.hexlike();
- /*
- New Unknown Opcode 837
- STORAGE_SIZE: 60
- 02 00 00 00 00 00 00 00 | 00 00 00 00 01 20 00 00
- 89 EB 33 01 71 5C 24 C4 | 15 03 35 45 74 47 8B 42
- BA B8 1B 40 00 00 00 00 | 00 00 00 00 77 66 42 BF
- 23 91 26 3F 00 00 60 41 | 00 00 00 00
-
- New Unknown Opcode 837
- STORAGE_SIZE: 44
- 02 00 00 00 00 00 00 00 | 00 00 00 00 00 00 80 00
- 7B 80 34 01 84 EA 2B C4 | 5F A1 36 45 C9 39 1C 42
- BA B8 1B 40 CE 06 00 00 | 00 00 80 3F
- */
-}
-
void WorldSession::HandleDismountOpcode( WorldPacket & /*recv_data*/ )
{
sLog.outDebug("WORLD: CMSG_CANCEL_MOUNT_AURA");
@@ -1601,3 +1663,32 @@ void WorldSession::HandleSetTaxiBenchmarkOpcode( WorldPacket & recv_data )
sLog.outDebug("Client used \"/timetest %d\" command", mode);
}
+
+void WorldSession::HandleSpellClick( WorldPacket & recv_data )
+{
+ CHECK_PACKET_SIZE(recv_data, 8);
+
+ uint64 guid;
+ recv_data >> guid;
+
+ Vehicle *vehicle = ObjectAccessor::GetVehicle(guid);
+
+ if(!vehicle)
+ return;
+
+ _player->EnterVehicle(vehicle);
+}
+
+void WorldSession::HandleInspectAchievements( WorldPacket & recv_data )
+{
+ CHECK_PACKET_SIZE(recv_data, 1);
+ uint64 guid;
+ if(!recv_data.readPackGUID(guid))
+ return;
+
+ Player *player = objmgr.GetPlayer(guid);
+ if(!player)
+ return;
+
+ player->GetAchievementMgr().SendRespondInspectAchievements(_player);
+}
diff --git a/src/game/MovementGenerator.cpp b/src/game/MovementGenerator.cpp
index 3cfccdb81c7..a80f09c7204 100644
--- a/src/game/MovementGenerator.cpp
+++ b/src/game/MovementGenerator.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/MovementGenerator.h b/src/game/MovementGenerator.h
index d362b6be648..554158129d6 100644
--- a/src/game/MovementGenerator.h
+++ b/src/game/MovementGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/MovementGeneratorImpl.h b/src/game/MovementGeneratorImpl.h
index 43c18ac6866..03b0c873f33 100644
--- a/src/game/MovementGeneratorImpl.h
+++ b/src/game/MovementGeneratorImpl.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp
index 8c808e3a53a..4e4dff56a47 100644
--- a/src/game/MovementHandler.cpp
+++ b/src/game/MovementHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -31,6 +31,7 @@
#include "BattleGround.h"
#include "WaypointMovementGenerator.h"
#include "InstanceSaveMgr.h"
+#include "ObjectMgr.h"
void WorldSession::HandleMoveWorldportAckOpcode( WorldPacket & /*recv_data*/ )
{
@@ -131,31 +132,23 @@ void WorldSession::HandleMoveWorldportAckOpcode()
if(!mEntry->IsMountAllowed())
_player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
- // battleground state prepare
+ // battleground state prepare (in case join to BG), at relogin/tele player not invited
// only add to bg group and object, if the player was invited (else he entered through command)
- if(_player->InBattleGround() && _player->IsInvitedForBattleGroundInstance(_player->GetBattleGroundId()))
+ if(_player->InBattleGround())
{
- BattleGround *bg = _player->GetBattleGround();
- if(bg)
+ // cleanup seting if outdated
+ if(!mEntry->IsBattleGroundOrArena())
{
- bg->AddPlayer(_player);
- if(bg->GetMapId() == _player->GetMapId()) // we teleported to bg
- {
- // get the team this way, because arenas might 'override' the teams.
- uint32 team = bg->GetPlayerTeam(_player->GetGUID());
- if(!team)
- team = _player->GetTeam();
- if(!bg->GetBgRaid(team)) // first player joined
- {
- Group *group = new Group;
- bg->SetBgRaid(team, group);
- group->Create(_player->GetGUIDLow(), _player->GetName());
- }
- else // raid already exist
- {
- bg->GetBgRaid(team)->AddMember(_player->GetGUID(), _player->GetName());
- }
- }
+ // Do next only if found in battleground
+ _player->SetBattleGroundId(0); // We're not in BG.
+ // reset destination bg team
+ _player->SetBGTeam(0);
+ }
+ // join to bg case
+ else if(BattleGround *bg = _player->GetBattleGround())
+ {
+ if(_player->IsInvitedForBattleGroundInstance(_player->GetBattleGroundId()))
+ bg->AddPlayer(_player);
}
}
@@ -178,64 +171,15 @@ void WorldSession::HandleMoveWorldportAckOpcode()
void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
{
- CHECK_PACKET_SIZE(recv_data, 4+1+4+4+4+4+4);
+ uint32 opcode = recv_data.GetOpcode();
+ sLog.outDebug("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(opcode), opcode, opcode);
+
+ if(GetPlayer()->GetDontMove())
+ return;
/* extract packet */
MovementInfo movementInfo;
- uint32 MovementFlags;
-
- recv_data >> MovementFlags;
- recv_data >> movementInfo.unk1;
- recv_data >> movementInfo.time;
- recv_data >> movementInfo.x;
- recv_data >> movementInfo.y;
- recv_data >> movementInfo.z;
- recv_data >> movementInfo.o;
-
- if(MovementFlags & MOVEMENTFLAG_ONTRANSPORT)
- {
- // recheck
- CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8+4+4+4+4+4);
-
- recv_data >> movementInfo.t_guid;
- recv_data >> movementInfo.t_x;
- recv_data >> movementInfo.t_y;
- recv_data >> movementInfo.t_z;
- recv_data >> movementInfo.t_o;
- recv_data >> movementInfo.t_time;
- }
-
- if(MovementFlags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2))
- {
- // recheck
- CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4);
-
- recv_data >> movementInfo.s_pitch; // pitch, -1.55=looking down, 0=looking straight forward, +1.55=looking up
- }
-
- // recheck
- CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4);
-
- recv_data >> movementInfo.fallTime; // duration of last jump (when in jump duration from jump begin to now)
-
- if(MovementFlags & MOVEMENTFLAG_JUMPING)
- {
- // recheck
- CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4+4+4+4);
-
- recv_data >> movementInfo.j_unk; // constant, but different when jumping in water and on land?
- recv_data >> movementInfo.j_sinAngle; // sin of angle between orientation0 and players orientation
- recv_data >> movementInfo.j_cosAngle; // cos of angle between orientation0 and players orientation
- recv_data >> movementInfo.j_xyspeed; // speed of xy movement
- }
-
- if(MovementFlags & MOVEMENTFLAG_SPLINE)
- {
- // recheck
- CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4);
-
- recv_data >> movementInfo.u_unk1; // unknown
- }
+ ReadMovementInfo(recv_data, &movementInfo);
/*----------------*/
if(recv_data.size() != recv_data.rpos())
@@ -248,22 +192,8 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
if (!Trinity::IsValidMapCoord(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o))
return;
- // Handle possessed unit movement separately
- Unit* pos_unit = GetPlayer()->GetCharm();
- if (pos_unit && pos_unit->isPossessed()) // can be charmed but not possessed
- {
- HandlePossessedMovement(recv_data, movementInfo, MovementFlags);
- return;
- }
-
- if (GetPlayer()->GetDontMove())
- return;
-
- //Save movement flags
- GetPlayer()->SetUnitMovementFlags(MovementFlags);
-
/* handle special cases */
- if (MovementFlags & MOVEMENTFLAG_ONTRANSPORT)
+ if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT)
{
// transports size limited
// (also received at zeppelin leave by some reason with t_* as absolute in continent coordinates, can be safely skipped)
@@ -282,9 +212,6 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
{
if ((*iter)->GetGUID() == movementInfo.t_guid)
{
- // unmount before boarding
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
-
GetPlayer()->m_transport = (*iter);
(*iter)->AddPassenger(GetPlayer());
break;
@@ -301,13 +228,14 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
movementInfo.t_z = 0.0f;
movementInfo.t_o = 0.0f;
movementInfo.t_time = 0;
+ movementInfo.t_seat = -1;
}
// fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
- if (recv_data.GetOpcode() == MSG_MOVE_FALL_LAND && !GetPlayer()->isInFlight())
+ if (opcode == MSG_MOVE_FALL_LAND && !GetPlayer()->isInFlight())
GetPlayer()->HandleFallDamage(movementInfo);
- if(((MovementFlags & MOVEMENTFLAG_SWIMMING) != 0) != GetPlayer()->IsInWater())
+ if(((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != GetPlayer()->IsInWater())
{
// now client not include swimming flag in case jumping under water
GetPlayer()->SetInWater( !GetPlayer()->IsInWater() || GetPlayer()->GetBaseMap()->IsUnderWater(movementInfo.x, movementInfo.y, movementInfo.z) );
@@ -316,100 +244,54 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
/*----------------------*/
/* process position-change */
- recv_data.put<uint32>(5, getMSTime()); // offset flags(4) + unk(1)
- WorldPacket data(recv_data.GetOpcode(), (GetPlayer()->GetPackGUID().size()+recv_data.size()));
- data.append(GetPlayer()->GetPackGUID());
+ Unit *mover = _player->m_mover;
+ recv_data.put<uint32>(6, getMSTime()); // fix time, offset flags(4) + unk(2)
+ WorldPacket data(recv_data.GetOpcode(), (mover->GetPackGUID().size()+recv_data.size()));
+ data.append(_player->m_mover->GetPackGUID()); // use mover guid
data.append(recv_data.contents(), recv_data.size());
GetPlayer()->SendMessageToSet(&data, false);
- GetPlayer()->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
- GetPlayer()->m_movementInfo = movementInfo;
- if (GetPlayer()->m_lastFallTime >= movementInfo.fallTime || GetPlayer()->m_lastFallZ <=movementInfo.z || recv_data.GetOpcode() == MSG_MOVE_FALL_LAND)
- GetPlayer()->SetFallInformation(movementInfo.fallTime, movementInfo.z);
-
- if(GetPlayer()->isMovingOrTurning())
- GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
-
- if(movementInfo.z < -500.0f)
- GetPlayer()->HandleFallUnderMap();
-}
-
-void WorldSession::HandlePossessedMovement(WorldPacket& recv_data, MovementInfo& movementInfo, uint32& MovementFlags)
-{
- // Whatever the client is controlling, it will send the GUID of the original player.
- // If current player is controlling, it must be handled like the controlled player sent these opcodes
-
- Unit* pos_unit = GetPlayer()->GetCharm();
-
- if (pos_unit->GetTypeId() == TYPEID_PLAYER && ((Player*)pos_unit)->GetDontMove())
- return;
-
- //Save movement flags
- pos_unit->SetUnitMovementFlags(MovementFlags);
-
- // Remove possession if possessed unit enters a transport
- if (MovementFlags & MOVEMENTFLAG_ONTRANSPORT)
+ if(!_player->GetCharmGUID()) // nothing is charmed
{
- GetPlayer()->RemovePossess(true);
- return;
+ _player->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
+ _player->m_movementInfo = movementInfo;
+ _player->SetUnitMovementFlags(movementInfo.flags);
}
-
- recv_data.put<uint32>(5, getMSTime());
- WorldPacket data(recv_data.GetOpcode(), pos_unit->GetPackGUID().size()+recv_data.size());
- data.append(pos_unit->GetPackGUID());
- data.append(recv_data.contents(), recv_data.size());
- // Send the packet to self but not to the possessed player; for creatures the first bool is irrelevant
- pos_unit->SendMessageToSet(&data, true, false);
-
- // Possessed is a player
- if (pos_unit->GetTypeId() == TYPEID_PLAYER)
+ else
{
- Player* plr = (Player*)pos_unit;
-
- if (recv_data.GetOpcode() == MSG_MOVE_FALL_LAND)
- plr->HandleFallDamage(movementInfo);
-
- if(((MovementFlags & MOVEMENTFLAG_SWIMMING) != 0) != plr->IsInWater())
+ if(mover->GetTypeId() != TYPEID_PLAYER) // unit, creature, pet, vehicle...
{
- // Now client not include swimming flag in case jumping under water
- plr->SetInWater( !plr->IsInWater() || plr->GetBaseMap()->IsUnderWater(movementInfo.x, movementInfo.y, movementInfo.z) );
+ if(Map *map = mover->GetMap())
+ map->CreatureRelocation((Creature*)mover, movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
+ mover->SetUnitMovementFlags(movementInfo.flags);
}
-
- plr->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o, false);
- plr->m_movementInfo = movementInfo;
-
- if(plr->isMovingOrTurning())
- plr->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
-
- if(movementInfo.z < -500.0f)
+ else // player
{
- GetPlayer()->RemovePossess(false);
- plr->HandleFallUnderMap();
+ ((Player*)mover)->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
+ ((Player*)mover)->m_movementInfo = movementInfo;
+ ((Player*)mover)->SetUnitMovementFlags(movementInfo.flags);
}
}
- else // Possessed unit is a creature
- {
- Map* map = MapManager::Instance().GetMap(pos_unit->GetMapId(), pos_unit);
- map->CreatureRelocation((Creature*)pos_unit, movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
- }
+
+ if (GetPlayer()->m_lastFallTime >= movementInfo.fallTime || GetPlayer()->m_lastFallZ <=movementInfo.z || recv_data.GetOpcode() == MSG_MOVE_FALL_LAND)
+ GetPlayer()->SetFallInformation(movementInfo.fallTime, movementInfo.z);
+
+ if(GetPlayer()->isMovingOrTurning())
+ GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+
+ if(movementInfo.z < -500.0f)
+ GetPlayer()->HandleFallUnderMap();
}
void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
{
- CHECK_PACKET_SIZE(recv_data, 8+4+4+1+4+4+4+4+4);
+ sLog.outDebug("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(recv_data.GetOpcode()), recv_data.GetOpcode(), recv_data.GetOpcode());
+
+ CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8+4);
/* extract packet */
uint64 guid;
- uint8 unkB;
- uint32 unk1, flags, time, fallTime;
- float x, y, z, orientation;
-
- uint64 t_GUID;
- float t_x, t_y, t_z, t_o;
- uint32 t_time;
- float s_pitch;
- float j_unk1, j_sinAngle, j_cosAngle, j_xyspeed;
- float u_unk1;
+ uint32 unk1;
float newspeed;
recv_data >> guid;
@@ -420,47 +302,10 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
// continue parse packet
- recv_data >> unk1;
- recv_data >> flags >> unkB >> time;
- recv_data >> x >> y >> z >> orientation;
- if (flags & MOVEMENTFLAG_ONTRANSPORT)
- {
- // recheck
- CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8+4+4+4+4+4);
-
- recv_data >> t_GUID;
- recv_data >> t_x >> t_y >> t_z >> t_o >> t_time;
- }
- if (flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2))
- {
- // recheck
- CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4);
-
- recv_data >> s_pitch; // pitch, -1.55=looking down, 0=looking straight forward, +1.55=looking up
- }
-
- // recheck
- CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4);
-
- recv_data >> fallTime; // duration of last jump (when in jump duration from jump begin to now)
-
- if ((flags & MOVEMENTFLAG_JUMPING) || (flags & MOVEMENTFLAG_FALLING))
- {
- // recheck
- CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4+4+4+4);
-
- recv_data >> j_unk1; // ?constant, but different when jumping in water and on land?
- recv_data >> j_sinAngle >> j_cosAngle; // sin + cos of angle between orientation0 and players orientation
- recv_data >> j_xyspeed; // speed of xy movement
- }
-
- if(flags & MOVEMENTFLAG_SPLINE)
- {
- // recheck
- CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4);
+ recv_data >> unk1; // counter or moveEvent
- recv_data >> u_unk1; // unknown
- }
+ MovementInfo movementInfo;
+ ReadMovementInfo(recv_data, &movementInfo);
// recheck
CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4);
@@ -473,7 +318,7 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
UnitMoveType move_type;
UnitMoveType force_move_type;
- static char const* move_type_name[MAX_MOVE_TYPE] = { "Walk", "Run", "RunBack", "Swim", "SwimBack", "TurnRate", "Flight", "FlightBack" };
+ static char const* move_type_name[MAX_MOVE_TYPE] = { "Walk", "Run", "RunBack", "Swim", "SwimBack", "TurnRate", "Flight", "FlightBack", "PitchRate" };
uint16 opcode = recv_data.GetOpcode();
switch(opcode)
@@ -486,6 +331,7 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
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;
default:
sLog.outError("WorldSession::HandleForceSpeedChangeAck: Unknown move type opcode: %u", opcode);
return;
@@ -520,20 +366,61 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
void WorldSession::HandleSetActiveMoverOpcode(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: Recvd CMSG_SET_ACTIVE_MOVER");
+ recv_data.hexlike();
- CHECK_PACKET_SIZE(recv_data,8);
+ CHECK_PACKET_SIZE(recv_data, 8);
uint64 guid;
recv_data >> guid;
- WorldPacket data(SMSG_TIME_SYNC_REQ, 4); // new 2.0.x, enable movement
- data << uint32(0x00000000); // on blizz it increments periodically
- SendPacket(&data);
+ if(_player->m_mover->GetGUID() != guid)
+ {
+ sLog.outError("HandleSetActiveMoverOpcode: incorrect mover guid: mover is " I64FMT " and should be " I64FMT, _player->m_mover->GetGUID(), guid);
+ return;
+ }
}
-void WorldSession::HandleNotActiveMoverOpcode(WorldPacket& /*recv_data*/)
+void WorldSession::HandleMoveNotActiveMover(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: Recvd CMSG_MOVE_NOT_ACTIVE_MOVER");
+ recv_data.hexlike();
+
+ CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8);
+
+ uint64 old_mover_guid;
+ recv_data >> old_mover_guid;
+
+ if(_player->m_mover->GetGUID() == old_mover_guid)
+ {
+ sLog.outError("HandleMoveNotActiveMover: incorrect mover guid: mover is " I64FMT " and should be " I64FMT " instead of " I64FMT, _player->m_mover->GetGUID(), _player->GetGUID(), old_mover_guid);
+ return;
+ }
+
+ MovementInfo mi;
+ ReadMovementInfo(recv_data, &mi);
+ _player->m_movementInfo = mi;
+}
+
+void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data)
+{
+ sLog.outDebug("WORLD: Recvd CMSG_DISMISS_CONTROLLED_VEHICLE");
+ recv_data.hexlike();
+
+ uint64 vehicleGUID = _player->GetCharmGUID();
+
+ if(!vehicleGUID) // something wrong here...
+ return;
+
+ MovementInfo mi;
+ ReadMovementInfo(recv_data, &mi);
+ _player->m_movementInfo = mi;
+
+ // using charm guid, because we don't have vehicle guid...
+ if(Vehicle *vehicle = ObjectAccessor::GetVehicle(vehicleGUID))
+ {
+ _player->ExitVehicle(vehicle);
+ vehicle->Dismiss();
+ }
}
void WorldSession::HandleMountSpecialAnimOpcode(WorldPacket& /*recvdata*/)
diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp
index fd23991392a..1865f90ea27 100644
--- a/src/game/NPCHandler.cpp
+++ b/src/game/NPCHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -166,25 +166,25 @@ void WorldSession::SendTrainerList( uint64 guid, const std::string& strTitle )
{
TrainerSpell const* tSpell = *itr;
- if(!_player->IsSpellFitByClassAndRace(tSpell->spell))
+ if(!_player->IsSpellFitByClassAndRace(tSpell->learnedSpell))
continue;
++count;
- bool primary_prof_first_rank = spellmgr.IsPrimaryProfessionFirstRankSpell(tSpell->spell);
+ bool primary_prof_first_rank = spellmgr.IsPrimaryProfessionFirstRankSpell(tSpell->learnedSpell);
- SpellChainNode const* chain_node = spellmgr.GetSpellChainNode(tSpell->spell);
+ SpellChainNode const* chain_node = spellmgr.GetSpellChainNode(tSpell->learnedSpell);
uint32 req_spell = spellmgr.GetSpellRequired(tSpell->spell);
- data << uint32(tSpell->spell);
+ data << uint32(tSpell->spell); // learned spell (or cast-spell in profession case)
data << uint8(_player->GetTrainerSpellState(tSpell));
- data << uint32(floor(tSpell->spellcost * fDiscountMod));
+ data << uint32(floor(tSpell->spellCost * fDiscountMod));
data << uint32(primary_prof_first_rank ? 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);
+ data << uint8(tSpell->reqLevel);
+ data << uint32(tSpell->reqSkill);
+ data << uint32(tSpell->reqSkillValue);
data << uint32(chain_node && chain_node->prev ? chain_node->prev : req_spell);
data << uint32(chain_node && chain_node->prev ? req_spell : 0);
data << uint32(0);
@@ -235,12 +235,14 @@ void WorldSession::HandleTrainerBuySpellOpcode( WorldPacket & recv_data )
return;
// apply reputation discount
- uint32 nSpellCost = uint32(floor(trainer_spell->spellcost * _player->GetReputationPriceDiscount(unit)));
+ uint32 nSpellCost = uint32(floor(trainer_spell->spellCost * _player->GetReputationPriceDiscount(unit)));
// check money requirement
if(_player->GetMoney() < nSpellCost )
return;
+ _player->ModifyMoney( -int32(nSpellCost) );
+
WorldPacket data(SMSG_PLAY_SPELL_VISUAL, 12); // visual effect on trainer
data << uint64(guid) << uint32(0xB3);
SendPacket(&data);
@@ -249,13 +251,15 @@ void WorldSession::HandleTrainerBuySpellOpcode( WorldPacket & recv_data )
data << uint64(_player->GetGUID()) << uint32(0x016A);
SendPacket(&data);
- _player->ModifyMoney( -int32(nSpellCost) );
-
- // learn explicitly to prevent lost money at lags, learning spell will be only show spell animation
- _player->learnSpell(trainer_spell->spell);
+ // learn explicitly or cast explicitly
+ if(trainer_spell->IsCastable ())
+ //FIXME: prof. spell entry in trainer list not marked gray until list re-open.
+ _player->CastSpell(_player,trainer_spell->spell,true);
+ else
+ _player->learnSpell(spellId,false);
data.Initialize(SMSG_TRAINER_BUY_SUCCEEDED, 12);
- data << uint64(guid) << uint32(spellId);
+ data << uint64(guid) << uint32(trainer_spell->spell);
SendPacket(&data);
}
@@ -528,13 +532,12 @@ void WorldSession::SendStablePet(uint64 guid )
data << uint32(pet->GetEntry());
data << uint32(pet->getLevel());
data << pet->GetName(); // petname
- data << uint32(pet->GetLoyaltyLevel()); // loyalty
- data << uint8(0x01); // client slot 1 == current pet (0)
+ data << uint8(0x01); // flags?, client slot 1 == current pet (0)
++num;
}
- // 0 1 2 3 4 5 6
- QueryResult* result = CharacterDatabase.PQuery("SELECT owner, slot, id, entry, level, loyalty, name FROM character_pet WHERE owner = '%u' AND slot > 0 AND slot < 3",_player->GetGUIDLow());
+ // 0 1 2 3 4 5
+ QueryResult* result = CharacterDatabase.PQuery("SELECT owner, slot, id, entry, level, name FROM character_pet WHERE owner = '%u' AND slot > 0 AND slot < 5",_player->GetGUIDLow());
if(result)
{
@@ -545,8 +548,7 @@ void WorldSession::SendStablePet(uint64 guid )
data << uint32(fields[2].GetUInt32()); // petnumber
data << uint32(fields[3].GetUInt32()); // creature entry
data << uint32(fields[4].GetUInt32()); // level
- data << fields[6].GetString(); // name
- data << uint32(fields[5].GetUInt32()); // loyalty
+ data << fields[5].GetString(); // name
data << uint8(fields[1].GetUInt32()+1); // slot
++num;
@@ -596,7 +598,7 @@ void WorldSession::HandleStablePet( WorldPacket & recv_data )
uint32 free_slot = 1;
- QueryResult *result = CharacterDatabase.PQuery("SELECT owner,slot,id FROM character_pet WHERE owner = '%u' AND slot > 0 AND slot < 3 ORDER BY slot ",_player->GetGUIDLow());
+ QueryResult *result = CharacterDatabase.PQuery("SELECT owner,slot,id FROM character_pet WHERE owner = '%u' AND slot > 0 AND slot < 5 ORDER BY slot ",_player->GetGUIDLow());
if(result)
{
do
@@ -660,7 +662,7 @@ void WorldSession::HandleUnstablePet( WorldPacket & recv_data )
Pet *newpet = NULL;
- QueryResult *result = CharacterDatabase.PQuery("SELECT entry FROM character_pet WHERE owner = '%u' AND id = '%u' AND slot > 0 AND slot < 3",_player->GetGUIDLow(),petnumber);
+ QueryResult *result = CharacterDatabase.PQuery("SELECT entry FROM character_pet WHERE owner = '%u' AND id = '%u' AND slot > 0 AND slot < 5",_player->GetGUIDLow(),petnumber);
if(result)
{
Field *fields = result->Fetch();
@@ -704,7 +706,7 @@ void WorldSession::HandleBuyStableSlot( WorldPacket & recv_data )
WorldPacket data(SMSG_STABLE_RESULT, 200);
- if(GetPlayer()->m_stableSlots < 2) // max slots amount = 2
+ if(GetPlayer()->m_stableSlots < 4) // max slots amount = 4
{
StableSlotPricesEntry const *SlotPrice = sStableSlotPricesStore.LookupEntry(GetPlayer()->m_stableSlots+1);
if(_player->GetMoney() >= SlotPrice->Price)
diff --git a/src/game/NPCHandler.h b/src/game/NPCHandler.h
index 096017b1054..e6e97df696b 100644
--- a/src/game/NPCHandler.h
+++ b/src/game/NPCHandler.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/NullCreatureAI.cpp b/src/game/NullCreatureAI.cpp
index 164aa2f7974..37dcdc3bc9d 100644
--- a/src/game/NullCreatureAI.cpp
+++ b/src/game/NullCreatureAI.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/NullCreatureAI.h b/src/game/NullCreatureAI.h
index a9814c9c5e0..7d88518ab1a 100644
--- a/src/game/NullCreatureAI.h
+++ b/src/game/NullCreatureAI.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/Object.cpp b/src/game/Object.cpp
index 1d5db0e925e..14a893f243e 100644
--- a/src/game/Object.cpp
+++ b/src/game/Object.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -58,8 +58,9 @@ uint32 GuidHigh2TypeId(uint32 guid_hi)
case HIGHGUID_DYNAMICOBJECT:return TYPEID_DYNAMICOBJECT;
case HIGHGUID_CORPSE: return TYPEID_CORPSE;
case HIGHGUID_MO_TRANSPORT: return TYPEID_GAMEOBJECT;
+ case HIGHGUID_VEHICLE: return TYPEID_UNIT;
}
- return 10; // unknown
+ return MAX_TYPEID; // unknown
}
Object::Object( )
@@ -146,15 +147,9 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) c
/** lower flag1 **/
if(target == this) // building packet for oneself
- {
flags |= UPDATEFLAG_SELF;
- /*** temporary reverted - until real source of stack corruption will not found
- updatetype = UPDATETYPE_CREATE_OBJECT2;
- ****/
- }
-
- if(flags & UPDATEFLAG_HASPOSITION)
+ if(flags & UPDATEFLAG_HAS_POSITION)
{
// UPDATETYPE_CREATE_OBJECT2 dynamic objects, corpses...
if(isType(TYPEMASK_DYNAMICOBJECT) || isType(TYPEMASK_CORPSE) || isType(TYPEMASK_PLAYER))
@@ -180,6 +175,12 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) c
break;
}
}
+
+ if(isType(TYPEMASK_UNIT))
+ {
+ if(((Unit*)this)->getVictim())
+ flags |= UPDATEFLAG_HAS_TARGET;
+ }
}
//sLog.outDebug("BuildCreateUpdate: update-type: %u, object-type: %u got flags: %X, flags2: %X", updatetype, m_objectTypeId, flags, flags2);
@@ -251,11 +252,18 @@ void Object::DestroyForPlayer(Player *target) const
WorldPacket data(SMSG_DESTROY_OBJECT, 8);
data << GetGUID();
+ data << uint8(0); // WotLK (bool)
target->GetSession()->SendPacket( &data );
}
-void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2 ) const
+void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2) const
{
+ uint16 unk_flags = ((GetTypeId() == TYPEID_PLAYER) ? ((Player*)this)->m_movementInfo.unk1 : 0);
+
+ if(GetTypeId() == TYPEID_UNIT)
+ if(((Creature*)this)->isVehicle())
+ unk_flags |= 0x20; // always allow pitch
+
*data << (uint8)flags; // update flags
// 0x20
@@ -292,12 +300,12 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2
}
*data << uint32(flags2); // movement flags
- *data << uint8(0); // unk 2.3.0
+ *data << uint16(unk_flags); // unknown 2.3.0
*data << uint32(getMSTime()); // time (in milliseconds)
}
// 0x40
- if (flags & UPDATEFLAG_HASPOSITION)
+ if (flags & UPDATEFLAG_HAS_POSITION)
{
// 0x02
if(flags & UPDATEFLAG_TRANSPORT && ((GameObject*)this)->GetGoType() == GAMEOBJECT_TYPE_MO_TRANSPORT)
@@ -330,12 +338,13 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2
*data << (float)((Player*)this)->GetTransOffsetZ();
*data << (float)((Player*)this)->GetTransOffsetO();
*data << (uint32)((Player*)this)->GetTransTime();
+ *data << (int8)((Player*)this)->GetTransSeat();
}
//TrinIty currently not have support for other than player on transport
}
// 0x02200000
- if(flags2 & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2))
+ if((flags2 & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2)) || (unk_flags & 0x20))
{
if(GetTypeId() == TYPEID_PLAYER)
*data << (float)((Player*)this)->m_movementInfo.s_pitch;
@@ -384,6 +393,7 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2
*data << ((Unit*)this)->GetSpeed( MOVE_FLIGHT );
*data << ((Unit*)this)->GetSpeed( MOVE_FLIGHT_BACK );
*data << ((Unit*)this)->GetSpeed( MOVE_TURN_RATE );
+ *data << ((Unit*)this)->GetSpeed( MOVE_PITCH_RATE );
// 0x08000000
if(flags2 & MOVEMENTFLAG_SPLINE2)
@@ -448,6 +458,8 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2
*data << path.GetNodes()[i].z;
}
+ *data << uint8(0); // added in 3.0.8
+
/*for(uint32 i = 0; i < poscount; i++)
{
// path points
@@ -485,7 +497,7 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2
break;
case TYPEID_PLAYER:
if(flags & UPDATEFLAG_SELF)
- *data << uint32(0x00000015); // unk, can be 0x15 or 0x22
+ *data << uint32(0x0000002F); // unk, can be 0x15 or 0x22
else
*data << uint32(0x00000008); // unk, can be 0x7 or 0x8
break;
@@ -508,6 +520,15 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2
case TYPEID_CORPSE:
*data << uint32(GetGUIDHigh()); // GetGUIDHigh()
break;
+ case TYPEID_UNIT:
+ *data << uint32(0x0000000B); // unk, can be 0xB or 0xC
+ break;
+ case TYPEID_PLAYER:
+ if(flags & UPDATEFLAG_SELF)
+ *data << uint32(0x0000002F); // unk, can be 0x15 or 0x22
+ else
+ *data << uint32(0x00000008); // unk, can be 0x7 or 0x8
+ break;
default:
*data << uint32(0x00000000); // unk
break;
@@ -515,9 +536,12 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2
}
// 0x4
- if(flags & UPDATEFLAG_FULLGUID)
+ if(flags & UPDATEFLAG_HAS_TARGET) // packed guid (current target guid)
{
- *data << uint8(0); // packed guid (probably target guid)
+ if(Unit *victim = ((Unit*)this)->getVictim())
+ data->append(victim->GetPackGUID());
+ else
+ *data << uint8(0);
}
// 0x2
@@ -525,6 +549,13 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2
{
*data << uint32(getMSTime()); // ms time
}
+
+ // 0x80
+ if(flags & UPDATEFLAG_VEHICLE) // unused for now
+ {
+ *data << uint32(((Vehicle*)this)->GetVehicleId()); // vehicle id
+ *data << float(0); // facing adjustment
+ }
}
void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask *updateMask, Player *target) const
@@ -540,10 +571,10 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
if ( ((GameObject*)this)->ActivateToQuest(target) || target->isGameMaster())
{
IsActivateToQuest = true;
- updateMask->SetBit(GAMEOBJECT_DYN_FLAGS);
+ updateMask->SetBit(GAMEOBJECT_DYNAMIC);
}
- if (GetUInt32Value(GAMEOBJECT_ARTKIT))
- updateMask->SetBit(GAMEOBJECT_ARTKIT);
+ if (((GameObject*)this)->GetGoArtKit())
+ updateMask->SetBit(GAMEOBJECT_BYTES_1);
}
}
else //case UPDATETYPE_VALUES
@@ -554,8 +585,8 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
{
IsActivateToQuest = true;
}
- updateMask->SetBit(GAMEOBJECT_DYN_FLAGS);
- updateMask->SetBit(GAMEOBJECT_ANIMPROGRESS);
+ updateMask->SetBit(GAMEOBJECT_DYNAMIC);
+ updateMask->SetBit(GAMEOBJECT_BYTES_1);
}
}
@@ -572,7 +603,6 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
if( updateMask->GetBit( index ) )
{
// remove custom flag before send
-
if( index == UNIT_NPC_FLAGS )
*data << uint32(m_uint32Values[ index ] & ~(UNIT_NPC_FLAG_GUARD + UNIT_NPC_FLAG_OUTDOORPVP));
// FIXME: Some values at server stored in float format but must be sent to client in uint32 format
@@ -673,7 +703,7 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
if( updateMask->GetBit( index ) )
{
// send in current format (float as float, uint32 as uint32)
- if ( index == GAMEOBJECT_DYN_FLAGS )
+ if ( index == GAMEOBJECT_DYNAMIC )
{
if(IsActivateToQuest )
{
@@ -1054,6 +1084,9 @@ bool Object::PrintIndexError(uint32 index, bool set) const
}
WorldObject::WorldObject()
+ : m_mapId(0), m_InstanceId(0), m_phaseMask(PHASEMASK_NORMAL),
+ m_positionX(0.0f), m_positionY(0.0f), m_positionZ(0.0f), m_orientation(0.0f),
+ mSemaphoreTeleport(false)
{
m_positionX = 0.0f;
m_positionY = 0.0f;
@@ -1106,26 +1139,27 @@ void WorldObject::RemoveFromWorld()
Object::RemoveFromWorld();
}
-void WorldObject::_Create( uint32 guidlow, HighGuid guidhigh, uint32 mapid )
+void WorldObject::_Create( uint32 guidlow, HighGuid guidhigh, uint32 mapid, uint32 phaseMask )
{
Object::_Create(guidlow, 0, guidhigh);
m_mapId = mapid;
+ m_phaseMask = phaseMask;
}
uint32 WorldObject::GetZoneId() const
{
- return MapManager::Instance().GetBaseMap(m_mapId)->GetZoneId(m_positionX,m_positionY);
+ return MapManager::Instance().GetBaseMap(m_mapId)->GetZoneId(m_positionX,m_positionY,m_positionZ);
}
uint32 WorldObject::GetAreaId() const
{
- return MapManager::Instance().GetBaseMap(m_mapId)->GetAreaId(m_positionX,m_positionY);
+ return MapManager::Instance().GetBaseMap(m_mapId)->GetAreaId(m_positionX,m_positionY,m_positionZ);
}
InstanceData* WorldObject::GetInstanceData()
{
- Map *map = MapManager::Instance().GetMap(m_mapId, this);
+ Map *map = GetMap();
return map->IsDungeon() ? ((InstanceMap*)map)->GetInstanceData() : NULL;
}
@@ -1417,9 +1451,9 @@ void WorldObject::MonsterSay(int32 textId, uint32 language, uint64 TargetGuid)
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
- Trinity::MessageChatLocaleCacheDo say_do(*this, CHAT_MSG_MONSTER_SAY, textId,language,TargetGuid,sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY));
- Trinity::PlayerWorker<Trinity::MessageChatLocaleCacheDo> say_worker(say_do);
- TypeContainerVisitor<Trinity::PlayerWorker<Trinity::MessageChatLocaleCacheDo>, WorldTypeMapContainer > message(say_worker);
+ MaNGOS::MessageChatLocaleCacheDo say_do(*this, CHAT_MSG_MONSTER_SAY, textId,language,TargetGuid,sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY));
+ MaNGOS::PlayerWorker<MaNGOS::MessageChatLocaleCacheDo> say_worker(this,say_do);
+ TypeContainerVisitor<MaNGOS::PlayerWorker<MaNGOS::MessageChatLocaleCacheDo>, WorldTypeMapContainer > message(say_worker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, message, *GetMap());
}
@@ -1432,9 +1466,9 @@ void WorldObject::MonsterYell(int32 textId, uint32 language, uint64 TargetGuid)
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
- Trinity::MessageChatLocaleCacheDo say_do(*this, CHAT_MSG_MONSTER_YELL, textId,language,TargetGuid,sWorld.getConfig(CONFIG_LISTEN_RANGE_YELL));
- Trinity::PlayerWorker<Trinity::MessageChatLocaleCacheDo> say_worker(say_do);
- TypeContainerVisitor<Trinity::PlayerWorker<Trinity::MessageChatLocaleCacheDo>, WorldTypeMapContainer > message(say_worker);
+ MaNGOS::MessageChatLocaleCacheDo say_do(*this, CHAT_MSG_MONSTER_YELL, textId,language,TargetGuid,sWorld.getConfig(CONFIG_LISTEN_RANGE_YELL));
+ MaNGOS::PlayerWorker<MaNGOS::MessageChatLocaleCacheDo> say_worker(this,say_do);
+ TypeContainerVisitor<MaNGOS::PlayerWorker<MaNGOS::MessageChatLocaleCacheDo>, WorldTypeMapContainer > message(say_worker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, message, *GetMap());
}
@@ -1447,9 +1481,9 @@ void WorldObject::MonsterTextEmote(int32 textId, uint64 TargetGuid, bool IsBossE
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
- Trinity::MessageChatLocaleCacheDo say_do(*this, IsBossEmote ? CHAT_MSG_RAID_BOSS_EMOTE : CHAT_MSG_MONSTER_EMOTE, textId,LANG_UNIVERSAL,TargetGuid,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
- Trinity::PlayerWorker<Trinity::MessageChatLocaleCacheDo> say_worker(say_do);
- TypeContainerVisitor<Trinity::PlayerWorker<Trinity::MessageChatLocaleCacheDo>, WorldTypeMapContainer > message(say_worker);
+ MaNGOS::MessageChatLocaleCacheDo say_do(*this, IsBossEmote ? CHAT_MSG_RAID_BOSS_EMOTE : CHAT_MSG_MONSTER_EMOTE, textId,LANG_UNIVERSAL,TargetGuid,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
+ MaNGOS::PlayerWorker<MaNGOS::MessageChatLocaleCacheDo> say_worker(this,say_do);
+ TypeContainerVisitor<MaNGOS::PlayerWorker<MaNGOS::MessageChatLocaleCacheDo>, WorldTypeMapContainer > message(say_worker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, message, *GetMap());
}
@@ -1501,7 +1535,7 @@ void WorldObject::BuildHeartBeatMsg(WorldPacket *data) const
data->Initialize(MSG_MOVE_HEARTBEAT, 32);
data->append(GetPackGUID());
*data << uint32(((Unit*)this)->GetUnitMovementFlags()); // movement flags
- *data << uint8(0); // 2.3.0
+ *data << uint16(0); // 2.3.0
*data << getMSTime(); // time
*data << m_positionX;
*data << m_positionY;
@@ -1520,7 +1554,7 @@ void WorldObject::BuildTeleportAckMsg(WorldPacket *data, float x, float y, float
data->append(GetPackGUID());
*data << uint32(0); // this value increments every time
*data << uint32(((Unit*)this)->GetUnitMovementFlags()); // movement flags
- *data << uint8(0); // 2.3.0
+ *data << uint16(0); // 2.3.0
*data << getMSTime(); // time
*data << x;
*data << y;
@@ -1577,7 +1611,7 @@ Creature* WorldObject::SummonCreature(uint32 id, float x, float y, float z, floa
if (GetTypeId()==TYPEID_PLAYER)
team = ((Player*)this)->GetTeam();
- if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), GetMap(), id, team))
+ if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), GetMap(), GetPhaseMask(), id, team))
{
delete pCreature;
return NULL;
@@ -1616,17 +1650,16 @@ GameObject* WorldObject::SummonGameObject(uint32 entry, float x, float y, float
{
if(!IsInWorld())
return NULL;
- Map * map = GetMap();
- if(!map)
- return NULL;
+
GameObjectInfo const* goinfo = objmgr.GetGameObjectInfo(entry);
if(!goinfo)
{
sLog.outErrorDb("Gameobject template %u not found in database!", entry);
return NULL;
}
+ Map *map = GetMap();
GameObject *go = new GameObject();
- if(!go->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT),entry,map,x,y,z,ang,rotation0,rotation1,rotation2,rotation3,100,1))
+ if(!go->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), entry, map, GetPhaseMask(), x,y,z,ang,rotation0,rotation1,rotation2,rotation3,100,1))
return NULL;
go->SetRespawnTime(respawnTime);
if(GetTypeId()==TYPEID_PLAYER || GetTypeId()==TYPEID_UNIT) //not sure how to handle this
@@ -1685,4 +1718,10 @@ void WorldObject::GetGroundPoint(float &x, float &y, float &z, float dist, float
UpdateGroundPositionZ(x, y, z);
}
+void WorldObject::SetPhaseMask(uint32 newPhaseMask, bool update)
+{
+ m_phaseMask = newPhaseMask;
+ if(update && IsInWorld())
+ ObjectAccessor::UpdateObjectVisibility(this);
+}
diff --git a/src/game/Object.h b/src/game/Object.h
index d4d9759ed1b..8bb8d770519 100644
--- a/src/game/Object.h
+++ b/src/game/Object.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -56,7 +56,8 @@ enum TypeMask
TYPEMASK_DYNAMICOBJECT = 0x0040,
TYPEMASK_CORPSE = 0x0080,
TYPEMASK_AIGROUP = 0x0100,
- TYPEMASK_AREATRIGGER = 0x0200
+ TYPEMASK_AREATRIGGER = 0x0200,
+ TYPEMASK_FARSIGHTOBJ = TYPEMASK_PLAYER | TYPEMASK_UNIT | TYPEMASK_DYNAMICOBJECT
};
enum TypeID
@@ -72,6 +73,7 @@ enum TypeID
TYPEID_AIGROUP = 8,
TYPEID_AREATRIGGER = 9
};
+#define MAX_TYPEID 10
uint32 GuidHigh2TypeId(uint32 guid_hi);
@@ -87,6 +89,12 @@ enum TempSummonType
TEMPSUMMON_MANUAL_DESPAWN = 8 // despawns when UnSummon() is called
};
+enum PhaseMasks
+{
+ PHASEMASK_NORMAL = 0x00000001,
+ PHASEMASK_ANYWHERE = 0xFFFFFFFF
+};
+
class WorldPacket;
class UpdateData;
class ByteBuffer;
@@ -358,7 +366,7 @@ class TRINITY_DLL_SPEC WorldObject : public Object
virtual void Update ( uint32 /*time_diff*/ ) { }
- void _Create( uint32 guidlow, HighGuid guidhigh, uint32 mapid );
+ void _Create( uint32 guidlow, HighGuid guidhigh, uint32 mapid, uint32 phaseMask);
void Relocate(float x, float y, float z, float orientation)
{
@@ -420,9 +428,13 @@ class TRINITY_DLL_SPEC WorldObject : public Object
void GetRandomPoint( float x, float y, float z, float distance, float &rand_x, float &rand_y, float &rand_z ) const;
void SetMapId(uint32 newMap) { m_mapId = newMap; }
-
uint32 GetMapId() const { return m_mapId; }
+ virtual void SetPhaseMask(uint32 newPhaseMask, bool update);
+ uint32 GetPhaseMask() const { return m_phaseMask; }
+ bool InSamePhase(WorldObject const* obj) const { return InSamePhase(obj->GetPhaseMask()); }
+ bool InSamePhase(uint32 phasemask) const { return GetPhaseMask()==0 && phasemask==0 || (GetPhaseMask() & phasemask); }
+
uint32 GetZoneId() const;
uint32 GetAreaId() const;
@@ -439,7 +451,11 @@ class TRINITY_DLL_SPEC WorldObject : public Object
float GetDistance2d(const WorldObject* obj) const;
float GetDistance2d(const float x, const float y) const;
float GetDistanceZ(const WorldObject* obj) const;
- bool IsInMap(const WorldObject* obj) const { return GetMapId()==obj->GetMapId() && GetInstanceId()==obj->GetInstanceId(); }
+ bool IsInMap(const WorldObject* obj) const
+ {
+ return IsInWorld() && obj->IsInWorld() && GetMapId()==obj->GetMapId() &&
+ GetInstanceId()==obj->GetInstanceId() && InSamePhase(obj);
+ }
bool IsWithinDistInMap(const WorldObject* obj, const float dist2compare, const bool is3D = true) const;
bool IsWithinLOS(const float x, const float y, const float z ) const;
bool IsWithinLOSInMap(const WorldObject* obj) const;
@@ -499,7 +515,9 @@ class TRINITY_DLL_SPEC WorldObject : public Object
bool m_isActive;
private:
- uint32 m_mapId;
+ uint32 m_mapId; // object at map with map_id
+ uint32 m_InstanceId; // in map copy with instance id
+ uint32 m_phaseMask; // in area phase state
float m_positionX;
float m_positionY;
@@ -507,7 +525,5 @@ class TRINITY_DLL_SPEC WorldObject : public Object
float m_orientation;
bool mSemaphoreTeleport;
-
- uint32 m_InstanceId;
};
#endif
diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp
index d2b0878c595..95ead040cb8 100644
--- a/src/game/ObjectAccessor.cpp
+++ b/src/game/ObjectAccessor.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -38,6 +38,7 @@
#include "Opcodes.h"
#include "ObjectDefines.h"
#include "MapInstanced.h"
+#include "World.h"
#include <cmath>
@@ -45,38 +46,6 @@
INSTANTIATE_SINGLETON_2(ObjectAccessor, CLASS_LOCK);
INSTANTIATE_CLASS_MUTEX(ObjectAccessor, ZThread::FastMutex);
-namespace Trinity
-{
- struct TRINITY_DLL_DECL BuildUpdateForPlayer
- {
- Player &i_player;
- UpdateDataMapType &i_updatePlayers;
-
- BuildUpdateForPlayer(Player &player, UpdateDataMapType &data_map) : i_player(player), i_updatePlayers(data_map) {}
-
- void Visit(PlayerMapType &m)
- {
- for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
- {
- if( iter->getSource() == &i_player )
- continue;
-
- UpdateDataMapType::iterator iter2 = i_updatePlayers.find(iter->getSource());
- if( iter2 == i_updatePlayers.end() )
- {
- std::pair<UpdateDataMapType::iterator, bool> p = i_updatePlayers.insert( ObjectAccessor::UpdateDataValueType(iter->getSource(), UpdateData()) );
- assert(p.second);
- iter2 = p.first;
- }
-
- i_player.BuildValuesUpdateBlockForPlayer(&iter2->second, iter2->first);
- }
- }
-
- template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
- };
-}
-
ObjectAccessor::ObjectAccessor() {}
ObjectAccessor::~ObjectAccessor() {}
@@ -129,11 +98,14 @@ ObjectAccessor::GetNPCIfCanInteractWith(Player const &player, uint64 guid, uint3
}
Creature*
-ObjectAccessor::GetCreatureOrPet(WorldObject const &u, uint64 guid)
+ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const &u, uint64 guid)
{
if(Creature *unit = GetPet(guid))
return unit;
+ if(Creature *unit = GetVehicle(guid))
+ return unit;
+
return GetCreature(u, guid);
}
@@ -162,18 +134,23 @@ ObjectAccessor::GetUnit(WorldObject const &u, uint64 guid)
if(IS_PLAYER_GUID(guid))
return FindPlayer(guid);
- return GetCreatureOrPet(u, guid);
+ return GetCreatureOrPetOrVehicle(u, guid);
}
Corpse*
ObjectAccessor::GetCorpse(WorldObject const &u, uint64 guid)
{
Corpse * ret = GetObjectInWorld(guid, (Corpse*)NULL);
- if(ret && ret->GetMapId() != u.GetMapId()) ret = NULL;
+ if(!ret)
+ return NULL;
+ if(ret->GetMapId() != u.GetMapId())
+ return NULL;
+ if(ret->GetInstanceId() != u.GetInstanceId())
+ return NULL;
return ret;
}
-Object* ObjectAccessor::GetObjectByTypeMask(Player const &p, uint64 guid, uint32 typemask)
+Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const &p, uint64 guid, uint32 typemask)
{
Object *obj = NULL;
@@ -185,7 +162,7 @@ Object* ObjectAccessor::GetObjectByTypeMask(Player const &p, uint64 guid, uint32
if(typemask & TYPEMASK_UNIT)
{
- obj = GetCreatureOrPet(p,guid);
+ obj = GetCreatureOrPetOrVehicle(p,guid);
if(obj) return obj;
}
@@ -201,9 +178,9 @@ Object* ObjectAccessor::GetObjectByTypeMask(Player const &p, uint64 guid, uint32
if(obj) return obj;
}
- if(typemask & TYPEMASK_ITEM)
+ if(typemask & TYPEMASK_ITEM && p.GetTypeId() == TYPEID_PLAYER)
{
- obj = p.GetItemByGuid( guid );
+ obj = ((Player const &)p).GetItemByGuid( guid );
if(obj) return obj;
}
@@ -214,15 +191,25 @@ GameObject*
ObjectAccessor::GetGameObject(WorldObject const &u, uint64 guid)
{
GameObject * ret = GetObjectInWorld(guid, (GameObject*)NULL);
- if(ret && ret->GetMapId() != u.GetMapId()) ret = NULL;
+ if(!ret)
+ return NULL;
+ if(ret->GetMapId() != u.GetMapId())
+ return NULL;
+ if(ret->GetInstanceId() != u.GetInstanceId())
+ return NULL;
return ret;
}
DynamicObject*
-ObjectAccessor::GetDynamicObject(Unit const &u, uint64 guid)
+ObjectAccessor::GetDynamicObject(WorldObject const &u, uint64 guid)
{
DynamicObject * ret = GetObjectInWorld(guid, (DynamicObject*)NULL);
- if(ret && ret->GetMapId() != u.GetMapId()) ret = NULL;
+ if(!ret)
+ return NULL;
+ if(ret->GetMapId() != u.GetMapId())
+ return NULL;
+ if(ret->GetInstanceId() != u.GetInstanceId())
+ return NULL;
return ret;
}
@@ -273,22 +260,6 @@ ObjectAccessor::UpdateObject(Object* obj, Player* exceptPlayer)
}
void
-ObjectAccessor::AddUpdateObject(Object *obj)
-{
- Guard guard(i_updateGuard);
- i_objects.insert(obj);
-}
-
-void
-ObjectAccessor::RemoveUpdateObject(Object *obj)
-{
- Guard guard(i_updateGuard);
- std::set<Object *>::iterator iter = i_objects.find(obj);
- if( iter != i_objects.end() )
- i_objects.erase( iter );
-}
-
-void
ObjectAccessor::_buildUpdateObject(Object *obj, UpdateDataMapType &update_players)
{
bool build_for_all = true;
@@ -351,6 +322,12 @@ ObjectAccessor::GetPet(uint64 guid)
return GetObjectInWorld(guid, (Pet*)NULL);
}
+Vehicle*
+ObjectAccessor::GetVehicle(uint64 guid)
+{
+ return GetObjectInWorld(guid, (Vehicle*)NULL);
+}
+
Corpse*
ObjectAccessor::GetCorpseForPlayerGUID(uint64 guid)
{
@@ -423,7 +400,7 @@ ObjectAccessor::AddCorpsesToGrid(GridPair const& gridpair,GridType& grid,Map* ma
}
Corpse*
-ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid)
+ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid, bool insignia)
{
Corpse *corpse = GetCorpseForPlayerGUID(player_guid);
if(!corpse)
@@ -449,7 +426,10 @@ ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid)
Corpse *bones = NULL;
// create the bones only if the map and the grid is loaded at the corpse's location
- if(map && !map->IsRemovalGrid(corpse->GetPositionX(), corpse->GetPositionY()))
+ // ignore bones creating option in case insignia
+ if (map && (insignia ||
+ (map->IsBattleGroundOrArena() ? sWorld.getConfig(CONFIG_DEATH_BONES_BG_OR_ARENA) : sWorld.getConfig(CONFIG_DEATH_BONES_WORLD))) &&
+ !map->IsRemovalGrid(corpse->GetPositionX(), corpse->GetPositionY()))
{
// Create bones, don't change Corpse
bones = new Corpse;
@@ -465,6 +445,7 @@ ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid)
bones->Relocate(corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ(), corpse->GetOrientation());
bones->SetMapId(corpse->GetMapId());
bones->SetInstanceId(corpse->GetInstanceId());
+ bones->SetPhaseMask(corpse->GetPhaseMask(),false);
bones->SetUInt32Value(CORPSE_FIELD_FLAGS, CORPSE_FLAG_UNK2 | CORPSE_FLAG_BONES);
bones->SetUInt64Value(CORPSE_FIELD_OWNER, 0);
@@ -602,6 +583,7 @@ template <class T> ZThread::FastMutex HashMapHolder<T>::i_lock;
template class HashMapHolder<Player>;
template class HashMapHolder<Pet>;
+template class HashMapHolder<Vehicle>;
template class HashMapHolder<GameObject>;
template class HashMapHolder<DynamicObject>;
template class HashMapHolder<Creature>;
@@ -609,6 +591,7 @@ template class HashMapHolder<Corpse>;
template Player* ObjectAccessor::GetObjectInWorld<Player>(uint32 mapid, float x, float y, uint64 guid, Player* /*fake*/);
template Pet* ObjectAccessor::GetObjectInWorld<Pet>(uint32 mapid, float x, float y, uint64 guid, Pet* /*fake*/);
+template Vehicle* ObjectAccessor::GetObjectInWorld<Vehicle>(uint32 mapid, float x, float y, uint64 guid, Vehicle* /*fake*/);
template Creature* ObjectAccessor::GetObjectInWorld<Creature>(uint32 mapid, float x, float y, uint64 guid, Creature* /*fake*/);
template Corpse* ObjectAccessor::GetObjectInWorld<Corpse>(uint32 mapid, float x, float y, uint64 guid, Corpse* /*fake*/);
template GameObject* ObjectAccessor::GetObjectInWorld<GameObject>(uint32 mapid, float x, float y, uint64 guid, GameObject* /*fake*/);
diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h
index 879c73288cc..723eecb1510 100644
--- a/src/game/ObjectAccessor.h
+++ b/src/game/ObjectAccessor.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -33,6 +33,7 @@
#include "GridDefines.h"
#include "Object.h"
#include "Player.h"
+#include "Vehicle.h"
#include <set>
@@ -58,9 +59,7 @@ class HashMapHolder
static void Remove(T* o)
{
Guard guard(i_lock);
- typename MapType::iterator itr = m_objectMap.find(o->GetGUID());
- if (itr != m_objectMap.end())
- m_objectMap.erase(itr);
+ m_objectMap.erase(o->GetGUID());
}
static T* Find(uint64 guid)
@@ -139,17 +138,18 @@ class TRINITY_DLL_DECL ObjectAccessor : public Trinity::Singleton<ObjectAccessor
else return NULL;
}
- static Object* GetObjectByTypeMask(Player const &, uint64, uint32 typemask);
+ static Object* GetObjectByTypeMask(WorldObject const &, uint64, uint32 typemask);
static Creature* GetNPCIfCanInteractWith(Player const &player, uint64 guid, uint32 npcflagmask);
static Creature* GetCreature(WorldObject const &, uint64);
- static Creature* GetCreatureOrPet(WorldObject const &, uint64);
+ static Creature* GetCreatureOrPetOrVehicle(WorldObject const &, uint64);
static Unit* GetUnit(WorldObject const &, uint64);
static Pet* GetPet(Unit const &, uint64 guid) { return GetPet(guid); }
static Player* GetPlayer(Unit const &, uint64 guid) { return FindPlayer(guid); }
static GameObject* GetGameObject(WorldObject const &, uint64);
- static DynamicObject* GetDynamicObject(Unit const &, uint64);
+ static DynamicObject* GetDynamicObject(WorldObject const &, uint64);
static Corpse* GetCorpse(WorldObject const &u, uint64 guid);
static Pet* GetPet(uint64 guid);
+ static Vehicle* GetVehicle(uint64 guid);
static Player* FindPlayer(uint64);
Player* FindPlayerByName(const char *name) ;
@@ -174,16 +174,22 @@ class TRINITY_DLL_DECL ObjectAccessor : public Trinity::Singleton<ObjectAccessor
HashMapHolder<Player>::Remove(pl);
Guard guard(i_updateGuard);
-
- std::set<Object *>::iterator iter2 = std::find(i_objects.begin(), i_objects.end(), (Object *)pl);
- if( iter2 != i_objects.end() )
- i_objects.erase(iter2);
+ i_objects.erase((Object *)pl);
}
void SaveAllPlayers();
- void AddUpdateObject(Object *obj);
- void RemoveUpdateObject(Object *obj);
+ void AddUpdateObject(Object *obj)
+ {
+ Guard guard(i_updateGuard);
+ i_objects.insert(obj);
+ }
+
+ void RemoveUpdateObject(Object *obj)
+ {
+ Guard guard(i_updateGuard);
+ i_objects.erase( obj );
+ }
void Update(uint32 diff);
void UpdatePlayers(uint32 diff);
@@ -192,7 +198,7 @@ class TRINITY_DLL_DECL ObjectAccessor : public Trinity::Singleton<ObjectAccessor
void RemoveCorpse(Corpse *corpse);
void AddCorpse(Corpse* corpse);
void AddCorpsesToGrid(GridPair const& gridpair,GridType& grid,Map* map);
- Corpse* ConvertCorpseForPlayer(uint64 player_guid);
+ Corpse* ConvertCorpseForPlayer(uint64 player_guid, bool insignia = false);
static void UpdateObject(Object* obj, Player* exceptPlayer);
static void _buildUpdateObject(Object* obj, UpdateDataMapType &);
diff --git a/src/game/ObjectDefines.h b/src/game/ObjectDefines.h
index 88840ebd251..39082fb5e4d 100644
--- a/src/game/ObjectDefines.h
+++ b/src/game/ObjectDefines.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -41,6 +41,7 @@ enum HighGuid
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_CORPSE = 0xF101, // blizz F100
HIGHGUID_MO_TRANSPORT = 0x1FC0, // blizz 1FC0 (for GAMEOBJECT_TYPE_MO_TRANSPORT)
@@ -50,6 +51,7 @@ enum HighGuid
#define IS_CREATURE_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_UNIT )
#define IS_PET_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_PET )
+#define IS_VEHICLE_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_VEHICLE )
#define IS_CREATURE_OR_PET_GUID(Guid)( IS_CREATURE_GUID(Guid) || IS_PET_GUID(Guid) )
#define IS_PLAYER_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_PLAYER && Guid!=0 )
#define IS_UNIT_GUID(Guid) ( IS_CREATURE_OR_PET_GUID(Guid) || IS_PLAYER_GUID(Guid) )
@@ -87,6 +89,7 @@ inline bool IsGuidHaveEnPart(uint64 const& guid)
case HIGHGUID_TRANSPORT:
case HIGHGUID_UNIT:
case HIGHGUID_PET:
+ case HIGHGUID_VEHICLE:
case HIGHGUID_MO_TRANSPORT:
default:
return true;
@@ -106,6 +109,7 @@ inline char const* GetLogNameForGuid(uint64 guid)
case HIGHGUID_TRANSPORT: return "transport";
case HIGHGUID_UNIT: return "creature";
case HIGHGUID_PET: return "pet";
+ case HIGHGUID_VEHICLE: return "vehicle";
case HIGHGUID_DYNAMICOBJECT:return "dynobject";
case HIGHGUID_CORPSE: return "corpse";
case HIGHGUID_MO_TRANSPORT: return "mo_transport";
diff --git a/src/game/ObjectGridLoader.cpp b/src/game/ObjectGridLoader.cpp
index 0e2b6ae329d..89df0582de0 100644
--- a/src/game/ObjectGridLoader.cpp
+++ b/src/game/ObjectGridLoader.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -59,7 +59,7 @@ ObjectGridRespawnMover::Visit(CreatureMapType &m)
Creature * c = iter->getSource();
- assert(!c->isPet() && "ObjectGridRespawnMover don't must be called for pets");
+ assert((!c->isPet() || !c->isVehicle()) && "ObjectGridRespawnMover don't must be called for pets");
Cell const& cur_cell = c->GetCurrentCell();
diff --git a/src/game/ObjectGridLoader.h b/src/game/ObjectGridLoader.h
index ebaaa1f5010..b75db484463 100644
--- a/src/game/ObjectGridLoader.h
+++ b/src/game/ObjectGridLoader.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp
index 8ba8320b432..97eed337799 100644
--- a/src/game/ObjectMgr.cpp
+++ b/src/game/ObjectMgr.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -46,6 +46,7 @@
#include "Util.h"
#include "WaypointManager.h"
#include "InstanceData.h" //for condition_instance_data
+#include "BattleGround.h"
INSTANTIATE_SINGLETON_1(ObjectMgr);
@@ -116,6 +117,7 @@ ObjectMgr::ObjectMgr()
m_hiCharGuid = 1;
m_hiCreatureGuid = 1;
m_hiPetGuid = 1;
+ m_hiVehicleGuid = 1;
m_hiItemGuid = 1;
m_hiGoGuid = 1;
m_hiDoGuid = 1;
@@ -325,14 +327,14 @@ void ObjectMgr::RemoveArenaTeam(ArenaTeam* arenaTeam)
mArenaTeamMap.erase( arenaTeam->GetId() );
}
-AuctionHouseObject * ObjectMgr::GetAuctionsMap( uint32 location )
+AuctionHouseObject * ObjectMgr::GetAuctionsMap( AuctionLocation location )
{
switch ( location )
{
- case 6: //horde
+ case AUCTION_HORDE:
return & mHordeAuctions;
break;
- case 2: //alliance
+ case AUCTION_ALLIANCE:
return & mAllianceAuctions;
break;
default: //neutral
@@ -340,18 +342,18 @@ AuctionHouseObject * ObjectMgr::GetAuctionsMap( uint32 location )
}
}
-uint32 ObjectMgr::GetAuctionCut(uint32 location, uint32 highBid)
+uint32 ObjectMgr::GetAuctionCut(AuctionLocation location, uint32 highBid)
{
- if (location == 7 && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
+ if (location == AUCTION_NEUTRAL && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
return (uint32) (0.15f * highBid * sWorld.getRate(RATE_AUCTION_CUT));
else
return (uint32) (0.05f * highBid * sWorld.getRate(RATE_AUCTION_CUT));
}
-uint32 ObjectMgr::GetAuctionDeposit(uint32 location, uint32 time, Item *pItem)
+uint32 ObjectMgr::GetAuctionDeposit(AuctionLocation location, uint32 time, Item *pItem)
{
float percentance; // in 0..1
- if ( location == 7 && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
+ if (location == AUCTION_NEUTRAL && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
percentance = 0.75f;
else
percentance = 0.15f;
@@ -842,6 +844,19 @@ void ObjectMgr::LoadCreatureTemplates()
if((cInfo->npcflag & UNIT_NPC_FLAG_TRAINER) && cInfo->trainer_type >= MAX_TRAINER_TYPE)
sLog.outErrorDb("Creature (Entry: %u) has wrong trainer type %u",cInfo->Entry,cInfo->trainer_type);
+ if(cInfo->type && !sCreatureTypeStore.LookupEntry(cInfo->type))
+ {
+ sLog.outErrorDb("Creature (Entry: %u) has invalid creature type (%u) in `type`",cInfo->Entry,cInfo->type);
+ const_cast<CreatureInfo*>(cInfo)->type = CREATURE_TYPE_HUMANOID;
+ }
+
+ // must exist or used hidden but used in data horse case
+ if(cInfo->family && !sCreatureFamilyStore.LookupEntry(cInfo->family) && cInfo->family != CREATURE_FAMILY_HORSE_CUSTOM )
+ {
+ sLog.outErrorDb("Creature (Entry: %u) has invalid creature family (%u) in `family`",cInfo->Entry,cInfo->family);
+ const_cast<CreatureInfo*>(cInfo)->family = 0;
+ }
+
if(cInfo->InhabitType <= 0 || cInfo->InhabitType > INHABIT_ANYWHERE)
{
sLog.outErrorDb("Creature (Entry: %u) has wrong value (%u) in `InhabitType`, creature will not correctly walk/swim/fly",cInfo->Entry,cInfo->InhabitType);
@@ -855,6 +870,15 @@ void ObjectMgr::LoadCreatureTemplates()
sLog.outErrorDb("Creature (Entry: %u) has non-existing PetSpellDataId (%u)", cInfo->Entry, cInfo->PetSpellDataId);
}
+ for(int i = 0; i < CREATURE_MAX_SPELLS; ++i)
+ {
+ if(cInfo->spells[i] && !sSpellStore.LookupEntry(cInfo->spells[i]))
+ {
+ sLog.outErrorDb("Creature (Entry: %u) has non-existing Spell%d (%u), set to 0", cInfo->Entry, i+1,cInfo->spells[i]);
+ const_cast<CreatureInfo*>(cInfo)->spells[i] = 0;
+ }
+ }
+
if(cInfo->MovementType >= MAX_DB_MOTION_TYPE)
{
sLog.outErrorDb("Creature (Entry: %u) has wrong movement generator type (%u), ignore and set to IDLE.",cInfo->Entry,cInfo->MovementType);
@@ -1003,8 +1027,47 @@ void ObjectMgr::LoadEquipmentTemplates()
{
sEquipmentStorage.Load();
+ for(uint32 i=0; i< sEquipmentStorage.MaxEntry; ++i)
+ {
+ EquipmentInfo const* eqInfo = sEquipmentStorage.LookupEntry<EquipmentInfo>(i);
+
+ if(!eqInfo)
+ continue;
+
+ for(uint8 j=0; j<3; j++)
+ {
+ if(!eqInfo->equipentry[j])
+ continue;
+
+ ItemEntry const *dbcitem = sItemStore.LookupEntry(eqInfo->equipentry[j]);
+
+ if(!dbcitem)
+ {
+ sLog.outErrorDb("Unknown item (entry=%u) in creature_equip_template.equipentry%u for entry = %u, forced to 0.", eqInfo->equipentry[j], j+1, i);
+ const_cast<EquipmentInfo*>(eqInfo)->equipentry[j] = 0;
+ continue;
+ }
+
+ if(dbcitem->InventoryType != INVTYPE_WEAPON &&
+ dbcitem->InventoryType != INVTYPE_SHIELD &&
+ dbcitem->InventoryType != INVTYPE_RANGED &&
+ dbcitem->InventoryType != INVTYPE_2HWEAPON &&
+ dbcitem->InventoryType != INVTYPE_WEAPONMAINHAND &&
+ dbcitem->InventoryType != INVTYPE_WEAPONOFFHAND &&
+ dbcitem->InventoryType != INVTYPE_HOLDABLE &&
+ dbcitem->InventoryType != INVTYPE_THROWN &&
+ dbcitem->InventoryType != INVTYPE_RANGEDRIGHT)
+ {
+ sLog.outErrorDb("Item (entry=%u) in creature_equip_template.equipentry%u for entry = %u is not equipable in a hand, forced to 0.", eqInfo->equipentry[j], j+1, i);
+ const_cast<EquipmentInfo*>(eqInfo)->equipentry[j] = 0;
+ }
+ }
+ }
sLog.outString( ">> Loaded %u equipment template", sEquipmentStorage.RecordCount );
sLog.outString();
+
+ // This DBC is currently only used for item templates and creature equipments checks.
+ sItemStore.Clear();
}
CreatureModelInfo const* ObjectMgr::GetCreatureModelInfo(uint32 modelid)
@@ -1076,8 +1139,8 @@ void ObjectMgr::LoadCreatures()
QueryResult *result = WorldDatabase.Query("SELECT creature.guid, id, map, modelid,"
// 4 5 6 7 8 9 10 11
"equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, spawndist, currentwaypoint,"
- // 12 13 14 15 16 17
- "curhealth, curmana, DeathState, MovementType, spawnMask, event "
+ // 12 13 14 15 16 17 18
+ "curhealth, curmana, DeathState, MovementType, spawnMask, phaseMask, event "
"FROM creature LEFT OUTER JOIN game_event_creature ON creature.guid = game_event_creature.guid");
if(!result)
@@ -1125,7 +1188,8 @@ void ObjectMgr::LoadCreatures()
data.is_dead = fields[14].GetBool();
data.movementType = fields[15].GetUInt8();
data.spawnMask = fields[16].GetUInt8();
- int16 gameEvent = fields[17].GetInt16();
+ data.phaseMask = fields[17].GetUInt16();
+ int16 gameEvent = fields[18].GetInt16();
CreatureInfo const* cInfo = GetCreatureTemplate(data.id);
if(!cInfo)
@@ -1183,6 +1247,40 @@ void ObjectMgr::LoadCreatures()
}
}
+ if(data.phaseMask==0)
+ {
+ sLog.outErrorDb("Table `creature` have creature (GUID: %u Entry: %u) with `phaseMask`=0 (not visible for anyone), set to 1.",guid,data.id );
+ data.phaseMask = 1;
+ }
+ else
+ {
+ int count = 0;
+ for(int i=0; i < sizeof(data.phaseMask)*8; ++i)
+ if(data.phaseMask & (1 << i))
+ ++count;
+
+ if(count > 1)
+ {
+ uint32 phaseMask = data.phaseMask & ~PHASEMASK_NORMAL;
+ count = 0;
+ for(int i=0; i < sizeof(phaseMask)*8; ++i)
+ if(phaseMask & (1 << i))
+ ++count;
+
+ if(count > 1)
+ {
+ sLog.outErrorDb("Table `creature` have creature (GUID: %u Entry: %u) with more single bit set in `phaseMask` (not visible for anyone), set to 1.",guid,data.id );
+ data.phaseMask = phaseMask;
+ }
+ else
+ {
+ sLog.outErrorDb("Table `creature` have creature (GUID: %u Entry: %u) with more single bit set in `phaseMask` (not visible for anyone), set to %u (possible expected).",guid,data.id,phaseMask);
+ data.phaseMask = 1;
+ }
+
+ }
+ }
+
if (gameEvent==0) // if not this is to be managed by GameEvent System
AddCreatureToGrid(guid, &data);
++count;
@@ -1233,8 +1331,8 @@ void ObjectMgr::LoadGameobjects()
// 0 1 2 3 4 5 6
QueryResult *result = WorldDatabase.Query("SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation,"
- // 7 8 9 10 11 12 13 14 15
- "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, event "
+ // 7 8 9 10 11 12 13 14 15 16
+ "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, phaseMask, event "
"FROM gameobject LEFT OUTER JOIN game_event_gameobject ON gameobject.guid = game_event_gameobject.guid");
if(!result)
@@ -1274,7 +1372,8 @@ void ObjectMgr::LoadGameobjects()
data.go_state = fields[13].GetUInt32();
data.ArtKit = 0;
data.spawnMask = fields[14].GetUInt8();
- int16 gameEvent = fields[15].GetInt16();
+ data.phaseMask = fields[15].GetUInt16();
+ int16 gameEvent = fields[16].GetInt16();
GameObjectInfo const* gInfo = GetGameObjectInfo(data.id);
if(!gInfo)
@@ -1283,6 +1382,12 @@ void ObjectMgr::LoadGameobjects()
continue;
}
+ if(data.phaseMask==0)
+ {
+ sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) with `phaseMask`=0 (not visible for anyone), set to 1.",guid,data.id );
+ data.phaseMask = 1;
+ }
+
if (gameEvent==0) // if not this is to be managed by GameEvent System
AddGameobjectToGrid(guid, &data);
++count;
@@ -1502,18 +1607,36 @@ void ObjectMgr::LoadAuctions()
{
QueryResult *result = CharacterDatabase.Query("SELECT COUNT(*) FROM auctionhouse");
if( !result )
+ {
+ barGoLink bar(1);
+ bar.step();
+ sLog.outString("");
+ sLog.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
return;
+ }
Field *fields = result->Fetch();
uint32 AuctionCount=fields[0].GetUInt32();
delete result;
if(!AuctionCount)
+ {
+ barGoLink bar(1);
+ bar.step();
+ sLog.outString("");
+ sLog.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
return;
+ }
result = CharacterDatabase.Query( "SELECT id,auctioneerguid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit,location FROM auctionhouse" );
if( !result )
+ {
+ barGoLink bar(1);
+ bar.step();
+ sLog.outString("");
+ sLog.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
return;
+ }
barGoLink bar( AuctionCount );
@@ -1537,24 +1660,36 @@ void ObjectMgr::LoadAuctions()
aItem->bid = fields[8].GetUInt32();
aItem->startbid = fields[9].GetUInt32();
aItem->deposit = fields[10].GetUInt32();
- aItem->location = fields[11].GetUInt8();
- //check if sold item exists
- if ( GetAItem( aItem->item_guidlow ) )
+
+ uint32 loc = fields[11].GetUInt8();
+ if(!IsValidAuctionLocation(loc))
{
- GetAuctionsMap( aItem->location )->AddAuction(aItem);
+ CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",aItem->Id);
+ sLog.outError("Auction %u has wrong auction location (%u)", aItem->Id, loc);
+ delete aItem;
+ continue;
}
- else
+ aItem->location = AuctionLocation(loc);
+
+ // check if sold item exists for guid
+ // and item_template in fact (GetAItem will fail if problematic in result check in ObjectMgr::LoadAuctionItems)
+ if ( !GetAItem( aItem->item_guidlow ) )
{
CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",aItem->Id);
sLog.outError("Auction %u has not a existing item : %u", aItem->Id, aItem->item_guidlow);
delete aItem;
+ continue;
}
+
+ if(aItem->location)
+
+ GetAuctionsMap( aItem->location )->AddAuction(aItem);
+
} while (result->NextRow());
delete result;
sLog.outString();
sLog.outString( ">> Loaded %u auctions", AuctionCount );
- sLog.outString();
}
void ObjectMgr::LoadItemLocales()
@@ -1653,6 +1788,32 @@ void ObjectMgr::LoadItemPrototypes()
if(dbcitem)
{
+ if(proto->Class != dbcitem->Class)
+ {
+ sLog.outErrorDb("Item (Entry: %u) not correct class %u, must be %u (still using DB value).",i,proto->Class,dbcitem->Class);
+ // It safe let use Class from DB
+ }
+ /* disabled: have some strange wrong cases for Subclass values.
+ for enable also uncomment Subclass field in ItemEntry structure and in Itemfmt[]
+ if(proto->SubClass != dbcitem->SubClass)
+ {
+ sLog.outErrorDb("Item (Entry: %u) not correct (Class: %u, Sub: %u) pair, must be (Class: %u, Sub: %u) (still using DB value).",i,proto->Class,proto->SubClass,dbcitem->Class,dbcitem->SubClass);
+ // It safe let use Subclass from DB
+ }
+ */
+
+ if(proto->Unk0 != dbcitem->Unk0)
+ {
+ sLog.outErrorDb("Item (Entry: %u) not correct %i Unk0, must be %i (still using DB value).",i,proto->Unk0,dbcitem->Unk0);
+ // It safe let use Unk0 from DB
+ }
+
+ if(proto->Material != dbcitem->Material)
+ {
+ sLog.outErrorDb("Item (Entry: %u) not correct %i material, must be %i (still using DB value).",i,proto->Material,dbcitem->Material);
+ // It safe let use Material from DB
+ }
+
if(proto->InventoryType != dbcitem->InventoryType)
{
sLog.outErrorDb("Item (Entry: %u) not correct %u inventory type, must be %u (still using DB value).",i,proto->InventoryType,dbcitem->InventoryType);
@@ -1678,7 +1839,7 @@ void ObjectMgr::LoadItemPrototypes()
if(proto->Class >= MAX_ITEM_CLASS)
{
sLog.outErrorDb("Item (Entry: %u) has wrong Class value (%u)",i,proto->Class);
- const_cast<ItemPrototype*>(proto)->Class = ITEM_CLASS_JUNK;
+ const_cast<ItemPrototype*>(proto)->Class = ITEM_CLASS_MISC;
}
if(proto->SubClass >= MaxItemSubclassValues[proto->Class])
@@ -1711,14 +1872,30 @@ void ObjectMgr::LoadItemPrototypes()
const_cast<ItemPrototype*>(proto)->RequiredSkill = 0;
}
- if(!(proto->AllowableClass & CLASSMASK_ALL_PLAYABLE))
{
- sLog.outErrorDb("Item (Entry: %u) not have in `AllowableClass` any playable classes (%u) and can't be equipped.",i,proto->AllowableClass);
- }
- if(!(proto->AllowableRace & RACEMASK_ALL_PLAYABLE))
- {
- sLog.outErrorDb("Item (Entry: %u) not have in `AllowableRace` any playable races (%u) and can't be equipped.",i,proto->AllowableRace);
+ // can be used in equip slot, as page read use in inventory, or spell casting at use
+ bool req = proto->InventoryType!=INVTYPE_NON_EQUIP || proto->PageText;
+ if(!req)
+ {
+ for (int j = 0; j < 5; ++j)
+ {
+ if(proto->Spells[j].SpellId)
+ {
+ req = true;
+ break;
+ }
+ }
+ }
+
+ if(req)
+ {
+ if(!(proto->AllowableClass & CLASSMASK_ALL_PLAYABLE))
+ sLog.outErrorDb("Item (Entry: %u) not have in `AllowableClass` any playable classes (%u) and can't be equipped or use.",i,proto->AllowableClass);
+
+ if(!(proto->AllowableRace & RACEMASK_ALL_PLAYABLE))
+ sLog.outErrorDb("Item (Entry: %u) not have in `AllowableRace` any playable races (%u) and can't be equipped or use.",i,proto->AllowableRace);
+ }
}
if(proto->RequiredSpell && !sSpellStore.LookupEntry(proto->RequiredSpell))
@@ -1744,11 +1921,22 @@ void ObjectMgr::LoadItemPrototypes()
else if(proto->RequiredReputationRank > MIN_REPUTATION_RANK)
sLog.outErrorDb("Item (Entry: %u) has RequiredReputationFaction ==0 but RequiredReputationRank > 0, rank setting is useless.",i);
+ if(proto->MaxCount < -1)
+ {
+ sLog.outErrorDb("Item (Entry: %u) has too large negative in maxcount (%i), replace by value (-1) no storing limits.",i,proto->MaxCount);
+ const_cast<ItemPrototype*>(proto)->MaxCount = -1;
+ }
+
if(proto->Stackable==0)
{
- sLog.outErrorDb("Item (Entry: %u) has wrong value in stackable (%u), replace by default 1.",i,proto->Stackable);
+ sLog.outErrorDb("Item (Entry: %u) has wrong value in stackable (%i), replace by default 1.",i,proto->Stackable);
const_cast<ItemPrototype*>(proto)->Stackable = 1;
}
+ else if(proto->Stackable < -1)
+ {
+ sLog.outErrorDb("Item (Entry: %u) has too large negative in stackable (%i), replace by value (-1) no stacking limits.",i,proto->Stackable);
+ const_cast<ItemPrototype*>(proto)->Stackable = -1;
+ }
else if(proto->Stackable > 255)
{
sLog.outErrorDb("Item (Entry: %u) has too large value in stackable (%u), replace by hardcoded upper limit (255).",i,proto->Stackable);
@@ -1775,7 +1963,7 @@ void ObjectMgr::LoadItemPrototypes()
}
// special format
- if(proto->Spells[0].SpellId == SPELL_ID_GENERIC_LEARN)
+ if((proto->Spells[0].SpellId == SPELL_ID_GENERIC_LEARN) || (proto->Spells[0].SpellId == SPELL_ID_GENERIC_LEARN_PET))
{
// spell_1
if(proto->Spells[0].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE)
@@ -1812,7 +2000,7 @@ void ObjectMgr::LoadItemPrototypes()
const_cast<ItemPrototype*>(proto)->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
}
// allowed only in special format
- else if(proto->Spells[1].SpellId==SPELL_ID_GENERIC_LEARN)
+ else if((proto->Spells[1].SpellId==SPELL_ID_GENERIC_LEARN) || (proto->Spells[1].SpellId==SPELL_ID_GENERIC_LEARN_PET))
{
sLog.outErrorDb("Item (Entry: %u) has broken spell in spellid_%d (%u)",i,1+1,proto->Spells[1].SpellId);
const_cast<ItemPrototype*>(proto)->Spells[0].SpellId = 0;
@@ -1858,7 +2046,7 @@ void ObjectMgr::LoadItemPrototypes()
const_cast<ItemPrototype*>(proto)->Spells[j].SpellId = 0;
}
// allowed only in special format
- else if(proto->Spells[j].SpellId==SPELL_ID_GENERIC_LEARN)
+ else if((proto->Spells[j].SpellId==SPELL_ID_GENERIC_LEARN) || (proto->Spells[j].SpellId==SPELL_ID_GENERIC_LEARN_PET))
{
sLog.outErrorDb("Item (Entry: %u) has broken spell in spellid_%d (%u)",i,j+1,proto->Spells[j].SpellId);
const_cast<ItemPrototype*>(proto)->Spells[j].SpellId = 0;
@@ -1927,17 +2115,21 @@ void ObjectMgr::LoadItemPrototypes()
const_cast<ItemPrototype*>(proto)->FoodType = 0;
}
}
-
- // this DBC used currently only for check item templates in DB.
- sItemStore.Clear();
}
void ObjectMgr::LoadAuctionItems()
{
- QueryResult *result = CharacterDatabase.Query( "SELECT itemguid,item_template FROM auctionhouse" );
+ // data needs to be at first place for Item::LoadFromDB
+ QueryResult *result = CharacterDatabase.Query( "SELECT data,itemguid,item_template FROM auctionhouse JOIN item_instance ON itemguid = guid" );
if( !result )
+ {
+ barGoLink bar(1);
+ bar.step();
+ sLog.outString("");
+ sLog.outString(">> Loaded 0 auction items");
return;
+ }
barGoLink bar( result->GetRowCount() );
@@ -1949,8 +2141,8 @@ void ObjectMgr::LoadAuctionItems()
bar.step();
fields = result->Fetch();
- uint32 item_guid = fields[0].GetUInt32();
- uint32 item_template = fields[1].GetUInt32();
+ uint32 item_guid = fields[1].GetUInt32();
+ uint32 item_template = fields[2].GetUInt32();
ItemPrototype const *proto = GetItemPrototype(item_template);
@@ -1962,7 +2154,7 @@ void ObjectMgr::LoadAuctionItems()
Item *item = NewItemOrBag(proto);
- if(!item->LoadFromDB(item_guid,0))
+ if(!item->LoadFromDB(item_guid,0, result))
{
delete item;
continue;
@@ -1972,7 +2164,6 @@ void ObjectMgr::LoadAuctionItems()
++count;
}
while( result->NextRow() );
-
delete result;
sLog.outString();
@@ -2260,7 +2451,7 @@ void ObjectMgr::LoadPlayerInfo()
if(sWorld.getConfig(CONFIG_START_ALL_SPELLS))
result = WorldDatabase.Query("SELECT race, class, Spell, Active FROM playercreateinfo_spell_custom");
else
- result = WorldDatabase.Query("SELECT race, class, Spell, Active FROM playercreateinfo_spell");
+ result = WorldDatabase.Query("SELECT race, class, Spell FROM playercreateinfo_spell");
uint32 count = 0;
@@ -2295,7 +2486,7 @@ void ObjectMgr::LoadPlayerInfo()
}
PlayerInfo* pInfo = &playerInfo[current_race][current_class];
- pInfo->spell.push_back(CreateSpellPair(fields[2].GetUInt16(), fields[3].GetUInt8()));
+ pInfo->spell.push_back(fields[2].GetUInt32());
bar.step();
++count;
@@ -2567,6 +2758,67 @@ void ObjectMgr::LoadPlayerInfo()
}
}
}
+
+ // Loading xp per level data
+ {
+ mPlayerXPperLevel.resize(sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
+ for (uint32 level = 0; level < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
+ mPlayerXPperLevel[level] = 0;
+
+ // 0 1
+ QueryResult *result = WorldDatabase.Query("SELECT lvl, xp_for_next_level FROM player_xp_for_level");
+
+ uint32 count = 0;
+
+ if (!result)
+ {
+ barGoLink bar( 1 );
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u xp for level definitions", count );
+ sLog.outErrorDb( "Error loading `player_xp_for_level` table or empty table.");
+ exit(1);
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ do
+ {
+ Field* fields = result->Fetch();
+
+ uint32 current_level = fields[0].GetUInt32();
+ uint32 current_xp = fields[1].GetUInt32();
+
+ if(current_level >= sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
+ {
+ if(current_level > STRONG_MAX_LEVEL) // hardcoded level maximum
+ sLog.outErrorDb("Wrong (> %u) level %u in `player_xp_for_level` table, ignoring.", STRONG_MAX_LEVEL,current_level);
+ else
+ sLog.outDetail("Unused (> MaxPlayerLevel in mangosd.conf) level %u in `player_xp_for_levels` table, ignoring.",current_level);
+ continue;
+ }
+ //PlayerXPperLevel
+ mPlayerXPperLevel[current_level] = current_xp;
+ bar.step();
+ ++count;
+ }
+ while (result->NextRow());
+
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u xp for level definitions", count );
+ }
+
+ // fill level gaps
+ for (uint32 level = 1; level < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
+ {
+ if( mPlayerXPperLevel[level] == 0)
+ {
+ sLog.outErrorDb("Level %i does not have XP for level data. Using data of level [%i] + 100.",level+1, level);
+ mPlayerXPperLevel[level] = mPlayerXPperLevel[level-1]+100;
+ }
+ }
}
void ObjectMgr::GetPlayerClassLevelInfo(uint32 class_, uint32 level, PlayerClassLevelInfo* info) const
@@ -2919,31 +3171,31 @@ void ObjectMgr::LoadQuests()
QueryResult *result = WorldDatabase.Query("SELECT entry, Method, ZoneOrSort, SkillOrClass, MinLevel, QuestLevel, Type, RequiredRaces, RequiredSkillValue,"
// 9 10 11 12 13 14 15 16
"RepObjectiveFaction, RepObjectiveValue, RequiredMinRepFaction, RequiredMinRepValue, RequiredMaxRepFaction, RequiredMaxRepValue, SuggestedPlayers, LimitTime,"
- // 17 18 19 20 21 22 23 24 25 26
- "QuestFlags, SpecialFlags, CharTitleId, PrevQuestId, NextQuestId, ExclusiveGroup, NextQuestInChain, SrcItemId, SrcItemCount, SrcSpell,"
- // 27 28 29 30 31 32 33 34 35 36
+ // 17 18 19 20 21 22 23 24 25 26 27 28
+ "QuestFlags, SpecialFlags, CharTitleId, PlayersSlain, BonusTalents, PrevQuestId, NextQuestId, ExclusiveGroup, NextQuestInChain, SrcItemId, SrcItemCount, SrcSpell,"
+ // 29 30 31 32 33 34 35 36 37 38
"Title, Details, Objectives, OfferRewardText, RequestItemsText, EndText, ObjectiveText1, ObjectiveText2, ObjectiveText3, ObjectiveText4,"
- // 37 38 39 40 41 42 43 44
+ // 39 40 41 42 43 44 45 46
"ReqItemId1, ReqItemId2, ReqItemId3, ReqItemId4, ReqItemCount1, ReqItemCount2, ReqItemCount3, ReqItemCount4,"
- // 45 46 47 48 49 50 51 52 53 54 54 55
+ // 47 48 49 50 51 52 53 54 55 56 57 58
"ReqSourceId1, ReqSourceId2, ReqSourceId3, ReqSourceId4, ReqSourceCount1, ReqSourceCount2, ReqSourceCount3, ReqSourceCount4, ReqSourceRef1, ReqSourceRef2, ReqSourceRef3, ReqSourceRef4,"
- // 57 58 59 60 61 62 63 64
+ // 59 60 61 62 63 64 65 66
"ReqCreatureOrGOId1, ReqCreatureOrGOId2, ReqCreatureOrGOId3, ReqCreatureOrGOId4, ReqCreatureOrGOCount1, ReqCreatureOrGOCount2, ReqCreatureOrGOCount3, ReqCreatureOrGOCount4,"
- // 65 66 67 68
+ // 67 68 69 70
"ReqSpellCast1, ReqSpellCast2, ReqSpellCast3, ReqSpellCast4,"
- // 69 70 71 72 73 74
- "RewChoiceItemId1, RewChoiceItemId2, RewChoiceItemId3, RewChoiceItemId4, RewChoiceItemId5, RewChoiceItemId6,"
- // 75 76 77 78 79 80
- "RewChoiceItemCount1, RewChoiceItemCount2, RewChoiceItemCount3, RewChoiceItemCount4, RewChoiceItemCount5, RewChoiceItemCount6,"
- // 81 82 83 84 85 86 87 88
+ // 71 72 73 74 75 76 77
+ "RewChoiceItemId1, RewChoiceItemId2, RewChoiceItemId3, RewChoiceItemId4, RewChoiceItemId5, RewChoiceItemId6, RewChoiceItemId7,"
+ // 78 79 80 81 82 83 84
+ "RewChoiceItemCount1, RewChoiceItemCount2, RewChoiceItemCount3, RewChoiceItemCount4, RewChoiceItemCount5, RewChoiceItemCount6, RewChoiceItemCount7,"
+ // 85 86 87 88 89 90 91 92
"RewItemId1, RewItemId2, RewItemId3, RewItemId4, RewItemCount1, RewItemCount2, RewItemCount3, RewItemCount4,"
- // 89 90 91 92 93 94 95 96 97 98
+ // 93 94 95 96 97 98 99 100 101 102
"RewRepFaction1, RewRepFaction2, RewRepFaction3, RewRepFaction4, RewRepFaction5, RewRepValue1, RewRepValue2, RewRepValue3, RewRepValue4, RewRepValue5,"
- // 99 100 101 102 103 104 105 106 107 108 109
+ // 103 104 105 106 107 108 109 110 111 112 113
"RewHonorableKills, RewOrReqMoney, RewMoneyMaxLevel, RewSpell, RewSpellCast, RewMailTemplateId, RewMailDelaySecs, PointMapId, PointX, PointY, PointOpt,"
- // 110 111 112 113 114 115 116 117 118 119
- "DetailsEmote1, DetailsEmote2, DetailsEmote3, DetailsEmote4,IncompleteEmote, CompleteEmote, OfferRewardEmote1, OfferRewardEmote2, OfferRewardEmote3, OfferRewardEmote4,"
- // 120 121
+ // 114 115 116 117 118 119 120 121 122 123
+ "DetailsEmote1, DetailsEmote2, DetailsEmote3, DetailsEmote4,IncompleteEmote, CompleteEmote, OfferRewardEmote1, OfferRewardEmote2, OfferRewardEmote3, OfferRewardEmote4,"
+ // 124 125
"StartScript, CompleteScript"
" FROM quest_template");
if(result == NULL)
@@ -4296,14 +4548,20 @@ void ObjectMgr::LoadInstanceTemplate()
else if(!entry->HasResetTime())
continue;
+ //FIXME: now exist heroic instance, normal/heroic raid instances
+ // entry->resetTimeHeroic store reset time for both heroic mode instance (raid and non-raid)
+ // entry->resetTimeRaid store reset time for normal raid only
+ // for current state entry->resetTimeRaid == entry->resetTimeHeroic in case raid instances with heroic mode.
+ // but at some point wee need implement reset time dependen from raid insatance mode
if(temp->reset_delay == 0)
{
// use defaults from the DBC
- if(entry->SupportsHeroicMode())
+ if(entry->resetTimeHeroic) // for both raid and non raids, read above
{
temp->reset_delay = entry->resetTimeHeroic / DAY;
}
else if (entry->resetTimeRaid && entry->map_type == MAP_RAID)
+ // for normal raid only
{
temp->reset_delay = entry->resetTimeRaid / DAY;
}
@@ -4481,14 +4739,27 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp)
// 0 1 2 3 4 5 6 7 8 9
QueryResult* result = CharacterDatabase.PQuery("SELECT id,messageType,sender,receiver,itemTextId,has_items,expire_time,cod,checked,mailTemplateId FROM mail WHERE expire_time < '" I64FMTD "'", (uint64)basetime);
if ( !result )
+ {
+ barGoLink bar(1);
+ bar.step();
+ sLog.outString("");
+ sLog.outString(">> Only expired mails (need to be return or delete) or DB table `mail` is empty.");
return; // any mails need to be returned or deleted
- Field *fields;
+ }
+
//std::ostringstream delitems, delmails; //will be here for optimization
//bool deletemail = false, deleteitem = false;
//delitems << "DELETE FROM item_instance WHERE guid IN ( ";
//delmails << "DELETE FROM mail WHERE id IN ( "
+
+ barGoLink bar( result->GetRowCount() );
+ uint32 count = 0;
+ Field *fields;
+
do
{
+ bar.step();
+
fields = result->Fetch();
Mail *m = new Mail;
m->messageID = fields[0].GetUInt32();
@@ -4554,8 +4825,12 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp)
//delmails << m->messageID << ", ";
CharacterDatabase.PExecute("DELETE FROM mail WHERE id = '%u'", m->messageID);
delete m;
+ ++count;
} while (result->NextRow());
delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u mails", count );
}
void ObjectMgr::LoadQuestAreaTriggers()
@@ -4712,7 +4987,7 @@ void ObjectMgr::LoadAreaTriggerScripts()
sLog.outString( ">> Loaded %u areatrigger scripts", count );
}
-uint32 ObjectMgr::GetNearestTaxiNode( float x, float y, float z, uint32 mapid )
+uint32 ObjectMgr::GetNearestTaxiNode( float x, float y, float z, uint32 mapid, uint32 team )
{
bool found = false;
float dist;
@@ -4721,24 +4996,31 @@ uint32 ObjectMgr::GetNearestTaxiNode( float x, float y, float z, uint32 mapid )
for(uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i)
{
TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(i);
- if(node && node->map_id == mapid)
+ if(!node || node->map_id != mapid || !node->MountCreatureID[team == ALLIANCE ? 1 : 0])
+ continue;
+
+ uint8 field = (uint8)((i - 1) / 32);
+ uint32 submask = 1<<((i-1)%32);
+
+ // skip not taxi network nodes
+ if((sTaxiNodesMask[field] & submask)==0)
+ continue;
+
+ float dist2 = (node->x - x)*(node->x - x)+(node->y - y)*(node->y - y)+(node->z - z)*(node->z - z);
+ if(found)
{
- float dist2 = (node->x - x)*(node->x - x)+(node->y - y)*(node->y - y)+(node->z - z)*(node->z - z);
- if(found)
+ if(dist2 < dist)
{
- if(dist2 < dist)
- {
- dist = dist2;
- id = i;
- }
- }
- else
- {
- found = true;
dist = dist2;
id = i;
}
}
+ else
+ {
+ found = true;
+ dist = dist2;
+ id = i;
+ }
}
return id;
@@ -4776,17 +5058,19 @@ uint16 ObjectMgr::GetTaxiMount( uint32 id, uint32 team )
TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(id);
if(node)
{
- if (team == ALLIANCE) mount_entry = node->alliance_mount_type;
- else mount_entry = node->horde_mount_type;
-
- CreatureInfo const *cinfo = GetCreatureTemplate(mount_entry);
- if (cinfo)
+ if (team == ALLIANCE)
{
- if(! (mount_id = cinfo->GetRandomValidModelId()))
- {
- sLog.outErrorDb("No displayid found for the taxi mount with the entry %u! Can't load it!", mount_entry);
- return false;
- }
+ mount_entry = node->MountCreatureID[1];
+ CreatureInfo const *ci = GetCreatureTemplate(mount_entry);
+ if(ci)
+ mount_id = ci->Modelid1;
+ }
+ if (team == HORDE)
+ {
+ mount_entry = node->MountCreatureID[0];
+ CreatureInfo const *ci = GetCreatureTemplate(mount_entry);
+ if(ci)
+ mount_id = ci->Modelid3;
}
}
@@ -4914,7 +5198,7 @@ void ObjectMgr::LoadGraveyardZones()
WorldSafeLocsEntry const *ObjectMgr::GetClosestGraveYard(float x, float y, float z, uint32 MapId, uint32 team)
{
// search for zone associated closest graveyard
- uint32 zoneId = MapManager::Instance().GetZoneId(MapId,x,y);
+ uint32 zoneId = MapManager::Instance().GetZoneId(MapId,x,y,z);
// Simulate std. algorithm:
// found some graveyard associated to (ghost_zone,ghost_map)
@@ -5242,6 +5526,9 @@ void ObjectMgr::LoadAreaTriggerTeleports()
sLog.outString( ">> Loaded %u area trigger teleport definitions", count );
}
+/*
+ * Searches for the areatrigger which teleports players out of the given map
+ */
AreaTrigger const* ObjectMgr::GetGoBackTrigger(uint32 Map) const
{
const MapEntry *mapEntry = sMapStore.LookupEntry(Map);
@@ -5258,6 +5545,23 @@ AreaTrigger const* ObjectMgr::GetGoBackTrigger(uint32 Map) const
return NULL;
}
+/**
+ * Searches for the areatrigger which teleports players to the given map
+ */
+AreaTrigger const* ObjectMgr::GetMapEntranceTrigger(uint32 Map) const
+{
+ for (AreaTriggerMap::const_iterator itr = mAreaTriggers.begin(); itr != mAreaTriggers.end(); ++itr)
+ {
+ if(itr->second.target_mapId == Map)
+ {
+ AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(itr->first);
+ if(atEntry)
+ return &itr->second;
+ }
+ }
+ return NULL;
+}
+
void ObjectMgr::SetHighestGuids()
{
QueryResult *result = CharacterDatabase.Query( "SELECT MAX(guid) FROM characters" );
@@ -5274,9 +5578,6 @@ void ObjectMgr::SetHighestGuids()
delete result;
}
- // pet guids are not saved to DB, set to 0 (pet guid != pet id)
- m_hiPetGuid = 0;
-
result = CharacterDatabase.Query( "SELECT MAX(guid) FROM item_instance" );
if( result )
{
@@ -5429,6 +5730,13 @@ uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh)
World::StopNow(ERROR_EXIT_CODE);
}
return m_hiPetGuid++;
+ case HIGHGUID_VEHICLE:
+ if(m_hiVehicleGuid>=0x00FFFFFF)
+ {
+ sLog.outError("Vehicle guid overflow!! Can't continue, shutting down server. ");
+ World::StopNow(ERROR_EXIT_CODE);
+ }
+ return m_hiVehicleGuid++;
case HIGHGUID_PLAYER:
if(m_hiCharGuid>=0xFFFFFFFE)
{
@@ -5616,10 +5924,10 @@ void ObjectMgr::LoadGameobjectInfo()
break;
}
case GAMEOBJECT_TYPE_CHAIR: //7
- if(goInfo->chair.height > 2)
+ if(goInfo->chair.height > (UNIT_STAND_STATE_SIT_HIGH_CHAIR-UNIT_STAND_STATE_SIT_LOW_CHAIR) )
{
- sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data1=%u but correct chair height in range 0..2.",
- id,goInfo->type,goInfo->chair.height);
+ sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data1=%u but correct chair height in range 0..%i.",
+ id,goInfo->type,goInfo->chair.height,UNIT_STAND_STATE_SIT_HIGH_CHAIR-UNIT_STAND_STATE_SIT_LOW_CHAIR);
// prevent client and server unexpected work
const_cast<GameObjectInfo*>(goInfo)->chair.height = 0;
@@ -5714,6 +6022,16 @@ void ObjectMgr::LoadGameobjectInfo()
}
break;
}
+ case GAMEOBJECT_TYPE_BARBER_CHAIR: //32
+ if(goInfo->barberChair.chairheight > (UNIT_STAND_STATE_SIT_HIGH_CHAIR-UNIT_STAND_STATE_SIT_LOW_CHAIR) )
+ {
+ sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data1=%u but correct chair height in range 0..%i.",
+ id,goInfo->type,goInfo->barberChair.chairheight,UNIT_STAND_STATE_SIT_HIGH_CHAIR-UNIT_STAND_STATE_SIT_LOW_CHAIR);
+
+ // prevent client and server unexpected work
+ const_cast<GameObjectInfo*>(goInfo)->barberChair.chairheight = 0;
+ }
+ break;
}
}
@@ -5762,6 +6080,13 @@ uint32 ObjectMgr::GetBaseXP(uint32 level)
return mBaseXPTable[level] ? mBaseXPTable[level] : 0;
}
+uint32 ObjectMgr::GetXPForLevel(uint32 level)
+{
+ if (level < mPlayerXPperLevel.size())
+ return mPlayerXPperLevel[level];
+ return 0;
+}
+
void ObjectMgr::LoadPetNames()
{
uint32 count = 0;
@@ -6230,11 +6555,18 @@ void ObjectMgr::LoadReservedPlayersNames()
bar.step();
fields = result->Fetch();
std::string name= fields[0].GetCppString();
- if(normalizePlayerName(name))
+
+ std::wstring wstr;
+ if(!Utf8toWStr (name,wstr))
{
- m_ReservedNames.insert(name);
- ++count;
+ sLog.outError("Table `reserved_name` have invalid name: %s", name.c_str() );
+ continue;
}
+
+ wstrToLower(wstr);
+
+ m_ReservedNames.insert(wstr);
+ ++count;
} while ( result->NextRow() );
delete result;
@@ -6243,6 +6575,17 @@ void ObjectMgr::LoadReservedPlayersNames()
sLog.outString( ">> Loaded %u reserved player names", count );
}
+bool ObjectMgr::IsReservedName( const std::string& name ) const
+{
+ std::wstring wstr;
+ if(!Utf8toWStr (name,wstr))
+ return false;
+
+ wstrToLower(wstr);
+
+ return m_ReservedNames.find(wstr) != m_ReservedNames.end();
+}
+
enum LanguageType
{
LT_BASIC_LATIN = 0x0000,
@@ -6391,55 +6734,26 @@ int ObjectMgr::GetOrNewIndexForLocale( LocaleConstant loc )
return m_LocalForIndex.size()-1;
}
-void ObjectMgr::LoadBattleMastersEntry()
+void ObjectMgr::LoadGameObjectForQuests()
{
- mBattleMastersMap.clear(); // need for reload case
-
- QueryResult *result = WorldDatabase.Query( "SELECT entry,bg_template FROM battlemaster_entry" );
-
- uint32 count = 0;
+ mGameObjectForQuestSet.clear(); // need for reload case
- if( !result )
+ if( !sGOStorage.MaxEntry )
{
barGoLink bar( 1 );
bar.step();
-
sLog.outString();
- sLog.outString( ">> Loaded 0 battlemaster entries - table is empty!" );
+ sLog.outString( ">> Loaded 0 GameObjects for quests" );
return;
}
- barGoLink bar( result->GetRowCount() );
-
- do
- {
- ++count;
- bar.step();
-
- Field *fields = result->Fetch();
-
- uint32 entry = fields[0].GetUInt32();
- uint32 bgTypeId = fields[1].GetUInt32();
-
- mBattleMastersMap[entry] = bgTypeId;
-
- } while( result->NextRow() );
-
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %u battlemaster entries", count );
-}
-
-void ObjectMgr::LoadGameObjectForQuests()
-{
- mGameObjectForQuestSet.clear(); // need for reload case
-
+ barGoLink bar( sGOStorage.MaxEntry - 1 );
uint32 count = 0;
// collect GO entries for GO that must activated
for(uint32 go_entry = 1; go_entry < sGOStorage.MaxEntry; ++go_entry)
{
+ bar.step();
GameObjectInfo const* goInfo = sGOStorage.LookupEntry<GameObjectInfo>(go_entry);
if(!goInfo)
continue;
@@ -6474,7 +6788,7 @@ void ObjectMgr::LoadGameObjectForQuests()
}
sLog.outString();
- sLog.outString( ">> Loaded %u GameObject for quests", count );
+ sLog.outString( ">> Loaded %u GameObjects for quests", count );
}
bool ObjectMgr::LoadTrinityStrings(DatabaseType& db, char const* table, int32 min_value, int32 max_value)
@@ -6767,7 +7081,7 @@ bool PlayerCondition::Meets(Player const * player) const
{
Unit::AuraMap const& auras = player->GetAuras();
for(Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
- if((itr->second->GetSpellProto()->Attributes & 0x1000010) && itr->second->GetSpellProto()->SpellVisual==3580)
+ if((itr->second->GetSpellProto()->Attributes & 0x1000010) && itr->second->GetSpellProto()->SpellVisual[0]==3580)
return true;
return false;
}
@@ -6944,7 +7258,7 @@ SkillRangeType GetSkillRangeType(SkillLineEntry const *pSkill, bool racial)
return SKILL_RANGE_MONO;
case SKILL_CATEGORY_ARMOR:
case SKILL_CATEGORY_CLASS:
- if(pSkill->id != SKILL_POISONS && pSkill->id != SKILL_LOCKPICKING)
+ if(pSkill->id != SKILL_LOCKPICKING)
return SKILL_RANGE_MONO;
else
return SKILL_RANGE_LEVEL;
@@ -6959,7 +7273,7 @@ SkillRangeType GetSkillRangeType(SkillLineEntry const *pSkill, bool racial)
return SKILL_RANGE_MONO;
default:
case SKILL_CATEGORY_ATTRIBUTES: //not found in dbc
- case SKILL_CATEGORY_NOT_DISPLAYED: //only GENEREC(DND)
+ case SKILL_CATEGORY_GENERIC: //only GENERIC(DND)
return SKILL_RANGE_NONE;
}
}
@@ -7020,11 +7334,10 @@ void ObjectMgr::LoadGameTele()
++count;
}
while (result->NextRow());
-
delete result;
sLog.outString();
- sLog.outString( ">> Loaded %u game tele's", count );
+ sLog.outString( ">> Loaded %u GameTeleports", count );
}
GameTele const* ObjectMgr::GetGameTele(const std::string& name) const
@@ -7162,14 +7475,27 @@ void ObjectMgr::LoadTrainerSpell()
TrainerSpell* pTrainerSpell = new TrainerSpell();
pTrainerSpell->spell = spell;
- pTrainerSpell->spellcost = fields[2].GetUInt32();
- pTrainerSpell->reqskill = fields[3].GetUInt32();
- pTrainerSpell->reqskillvalue = fields[4].GetUInt32();
- pTrainerSpell->reqlevel = fields[5].GetUInt32();
+ pTrainerSpell->spellCost = fields[2].GetUInt32();
+ pTrainerSpell->reqSkill = fields[3].GetUInt32();
+ pTrainerSpell->reqSkillValue = fields[4].GetUInt32();
+ pTrainerSpell->reqLevel = fields[5].GetUInt32();
- if(!pTrainerSpell->reqlevel)
- pTrainerSpell->reqlevel = spellinfo->spellLevel;
+ if(!pTrainerSpell->reqLevel)
+ pTrainerSpell->reqLevel = spellinfo->spellLevel;
+
+ // calculate learned spell for profession case when stored cast-spell
+ pTrainerSpell->learnedSpell = spell;
+ for(int i = 0; i <3; ++i)
+ {
+ if(spellinfo->Effect[i]!=SPELL_EFFECT_LEARN_SPELL)
+ continue;
+ if(SpellMgr::IsProfessionOrRidingSpell(spellinfo->EffectTriggerSpell[i]))
+ {
+ pTrainerSpell->learnedSpell = spellinfo->EffectTriggerSpell[i];
+ break;
+ }
+ }
TrainerSpellData& data = m_mCacheTrainerSpellMap[entry];
@@ -7183,7 +7509,7 @@ void ObjectMgr::LoadTrainerSpell()
delete result;
sLog.outString();
- sLog.outString( ">> Loaded Trainers %d", count );
+ sLog.outString( ">> Loaded %d Trainers", count );
}
void ObjectMgr::LoadVendors()
@@ -7461,16 +7787,30 @@ void ObjectMgr::LoadScriptNames()
"SELECT DISTINCT(ScriptName) FROM areatrigger_scripts WHERE ScriptName <> '' "
"UNION "
"SELECT DISTINCT(script) FROM instance_template WHERE script <> ''");
- if(result)
+
+ if( !result )
{
- do
- {
- m_scriptNames.push_back((*result)[0].GetString());
- } while (result->NextRow());
- delete result;
+ barGoLink bar( 1 );
+ bar.step();
+ sLog.outString();
+ sLog.outErrorDb(">> Loaded empty set of Script Names!");
+ return;
}
+ barGoLink bar( result->GetRowCount() );
+ uint32 count = 0;
+
+ do
+ {
+ bar.step();
+ m_scriptNames.push_back((*result)[0].GetString());
+ ++count;
+ } while (result->NextRow());
+ delete result;
+
std::sort(m_scriptNames.begin(), m_scriptNames.end());
+ sLog.outString();
+ sLog.outString( ">> Loaded %d Script Names", count );
}
uint32 ObjectMgr::GetScriptId(const char *name)
diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h
index 7d7a419d923..99cd9a5d573 100644
--- a/src/game/ObjectMgr.h
+++ b/src/game/ObjectMgr.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -399,15 +399,15 @@ class ObjectMgr
mAitems.erase(i);
return true;
}
- AuctionHouseObject * GetAuctionsMap( uint32 location );
+ AuctionHouseObject * GetAuctionsMap( AuctionLocation location );
//auction messages
void SendAuctionWonMail( AuctionEntry * auction );
void SendAuctionSalePendingMail( AuctionEntry * auction );
void SendAuctionSuccessfulMail( AuctionEntry * auction );
void SendAuctionExpiredMail( AuctionEntry * auction );
- static uint32 GetAuctionCut( uint32 location, uint32 highBid );
- static uint32 GetAuctionDeposit(uint32 location, uint32 time, Item *pItem);
+ static uint32 GetAuctionCut( AuctionLocation location, uint32 highBid );
+ static uint32 GetAuctionDeposit(AuctionLocation location, uint32 time, Item *pItem);
static uint32 GetAuctionOutBid(uint32 currentBid);
PetLevelInfo const* GetPetLevelInfo(uint32 creature_id, uint32 level) const;
@@ -435,7 +435,7 @@ class ObjectMgr
uint32 GetPlayerAccountIdByGUID(const uint64 &guid) const;
uint32 GetPlayerAccountIdByPlayerName(const std::string& name) const;
- uint32 GetNearestTaxiNode( float x, float y, float z, uint32 mapid );
+ uint32 GetNearestTaxiNode( float x, float y, float z, uint32 mapid, uint32 team );
void GetTaxiPath( uint32 source, uint32 destination, uint32 &path, uint32 &cost);
uint16 GetTaxiMount( uint32 id, uint32 team );
void GetTaxiPathNodes( uint32 path, Path &pathnodes, std::vector<uint32>& mapIds );
@@ -465,14 +465,6 @@ class ObjectMgr
return false;
}
- uint32 GetBattleMasterBG(uint32 entry) const
- {
- BattleMastersMap::const_iterator itr = mBattleMastersMap.find(entry);
- if(itr != mBattleMastersMap.end())
- return itr->second;
- return 2; //BATTLEGROUND_WS - i will not add include only for constant usage!
- }
-
void AddGossipText(GossipText *pGText);
GossipText *GetGossipText(uint32 Text_ID);
@@ -491,6 +483,7 @@ class ObjectMgr
}
AreaTrigger const* GetGoBackTrigger(uint32 Map) const;
+ AreaTrigger const* GetMapEntranceTrigger(uint32 Map) const;
uint32 GetAreaTriggerScriptId(uint32 trigger_id);
@@ -568,7 +561,6 @@ class ObjectMgr
void LoadQuestAreaTriggers();
void LoadAreaTriggerScripts();
void LoadTavernAreaTriggers();
- void LoadBattleMastersEntry();
void LoadGameObjectForQuests();
void LoadItemTexts();
@@ -597,6 +589,7 @@ class ObjectMgr
std::string GeneratePetName(uint32 entry);
uint32 GetBaseXP(uint32 level);
+ uint32 GetXPForLevel(uint32 level);
int32 GetFishingBaseSkillLevel(uint32 entry) const
{
@@ -734,10 +727,7 @@ class ObjectMgr
// reserved names
void LoadReservedPlayersNames();
- bool IsReservedName(const std::string& name) const
- {
- return m_ReservedNames.find(name) != m_ReservedNames.end();
- }
+ bool IsReservedName(const std::string& name) const;
// name with valid structure and symbols
static bool IsValidName( const std::string& name, bool create = false );
@@ -811,6 +801,8 @@ class ObjectMgr
ScriptNameMap &GetScriptNames() { return m_scriptNames; }
const char * GetScriptName(uint32 id) { return id < m_scriptNames.size() ? m_scriptNames[id].c_str() : ""; }
uint32 GetScriptId(const char *name);
+
+ int GetOrNewIndexForLocale(LocaleConstant loc);
protected:
// first free id for selected id type
@@ -825,6 +817,7 @@ class ObjectMgr
uint32 m_hiCharGuid;
uint32 m_hiCreatureGuid;
uint32 m_hiPetGuid;
+ uint32 m_hiVehicleGuid;
uint32 m_hiItemGuid;
uint32 m_hiGoGuid;
uint32 m_hiDoGuid;
@@ -834,7 +827,6 @@ class ObjectMgr
typedef UNORDERED_MAP<uint32, GossipText*> GossipTextMap;
typedef UNORDERED_MAP<uint32, uint32> QuestAreaTriggerMap;
- typedef UNORDERED_MAP<uint32, uint32> BattleMastersMap;
typedef UNORDERED_MAP<uint32, std::string> ItemTextMap;
typedef std::set<uint32> TavernAreaTriggerSet;
typedef std::set<uint32> GameObjectForQuestSet;
@@ -853,7 +845,6 @@ class ObjectMgr
AuctionHouseObject mNeutralAuctions;
QuestAreaTriggerMap mQuestAreaTriggerMap;
- BattleMastersMap mBattleMastersMap;
TavernAreaTriggerSet mTavernAreaTriggerSet;
GameObjectForQuestSet mGameObjectForQuestSet;
GossipTextMap mGossipText;
@@ -867,7 +858,7 @@ class ObjectMgr
PetCreateSpellMap mPetCreateSpell;
//character reserved names
- typedef std::set<std::string> ReservedNamesMap;
+ typedef std::set<std::wstring> ReservedNamesMap;
ReservedNamesMap m_ReservedNames;
std::set<uint32> m_DisabledPlayerSpells;
@@ -881,7 +872,6 @@ class ObjectMgr
typedef std::vector<LocaleConstant> LocalForIndex;
LocalForIndex m_LocalForIndex;
- int GetOrNewIndexForLocale(LocaleConstant loc);
int DBCLocaleIndex;
@@ -900,6 +890,9 @@ class ObjectMgr
void BuildPlayerLevelInfo(uint8 race, uint8 class_, uint8 level, PlayerLevelInfo* plinfo) const;
PlayerInfo playerInfo[MAX_RACES][MAX_CLASSES];
+ typedef std::vector<uint32> PlayerXPperLevel; // [level]
+ PlayerXPperLevel mPlayerXPperLevel;
+
typedef std::map<uint32,uint32> BaseXPMap; // [area level][base xp]
BaseXPMap mBaseXPTable;
diff --git a/src/game/ObjectPosSelector.cpp b/src/game/ObjectPosSelector.cpp
new file mode 100644
index 00000000000..899dfec3fdb
--- /dev/null
+++ b/src/game/ObjectPosSelector.cpp
@@ -0,0 +1,157 @@
+/*
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ObjectPosSelector.h"
+
+ObjectPosSelector::ObjectPosSelector(float x,float y,float size,float dist)
+: m_center_x(x),m_center_y(y),m_size(size),m_dist(dist)
+{
+ m_anglestep = acos(m_dist/(m_dist+2*m_size));
+
+ m_nextUsedPos[USED_POS_PLUS] = m_UsedPosLists[USED_POS_PLUS].end();
+ m_nextUsedPos[USED_POS_MINUS] = m_UsedPosLists[USED_POS_MINUS].end();
+
+ m_smallStepAngle[USED_POS_PLUS] = 0;
+ m_smallStepAngle[USED_POS_MINUS] = 0;
+
+ m_smallStepOk[USED_POS_PLUS] = false;
+ m_smallStepOk[USED_POS_MINUS] = false;
+
+ m_smallStepNextUsedPos[USED_POS_PLUS] = NULL;
+ m_smallStepNextUsedPos[USED_POS_MINUS] = NULL;
+}
+
+ObjectPosSelector::UsedPosList::value_type const* ObjectPosSelector::nextUsedPos(UsedPosType uptype)
+{
+ UsedPosList::const_iterator itr = m_nextUsedPos[uptype];
+ if(itr!=m_UsedPosLists[uptype].end())
+ ++itr;
+
+ if(itr==m_UsedPosLists[uptype].end())
+ {
+ if(!m_UsedPosLists[~uptype].empty())
+ return &*m_UsedPosLists[~uptype].rbegin();
+ else
+ return NULL;
+ }
+ else
+ return &*itr;
+}
+
+void ObjectPosSelector::AddUsedPos(float size,float angle,float dist)
+{
+ if(angle>=0)
+ m_UsedPosLists[USED_POS_PLUS].insert(UsedPosList::value_type(angle,UsedPos(1.0,size,dist)));
+ else
+ m_UsedPosLists[USED_POS_MINUS].insert(UsedPosList::value_type(-angle,UsedPos(-1.0,size,dist)));
+}
+
+void ObjectPosSelector::InitializeAngle()
+{
+ m_nextUsedPos[USED_POS_PLUS] = m_UsedPosLists[USED_POS_PLUS].begin();
+ m_nextUsedPos[USED_POS_MINUS] = m_UsedPosLists[USED_POS_MINUS].begin();
+
+ m_smallStepAngle[USED_POS_PLUS] = 0;
+ m_smallStepAngle[USED_POS_MINUS] = 0;
+
+ m_smallStepOk[USED_POS_PLUS] = true;
+ m_smallStepOk[USED_POS_MINUS] = true;
+}
+
+bool ObjectPosSelector::FirstAngle(float& angle)
+{
+ if(m_UsedPosLists[USED_POS_PLUS].empty() && !m_UsedPosLists[USED_POS_MINUS].empty() )
+ return NextAngleFor(*m_UsedPosLists[USED_POS_MINUS].begin(),1.0,USED_POS_PLUS,angle);
+ else if(m_UsedPosLists[USED_POS_MINUS].empty() && !m_UsedPosLists[USED_POS_PLUS].empty() )
+ return NextAngleFor(*m_UsedPosLists[USED_POS_PLUS].begin(),-1.0,USED_POS_MINUS,angle);
+
+ return false;
+}
+
+bool ObjectPosSelector::NextAngle(float& angle)
+{
+ while(m_nextUsedPos[USED_POS_PLUS]!=m_UsedPosLists[USED_POS_PLUS].end() ||
+ m_nextUsedPos[USED_POS_MINUS]!=m_UsedPosLists[USED_POS_MINUS].end() ||
+ m_smallStepOk[USED_POS_PLUS] || m_smallStepOk[USED_POS_MINUS] )
+ {
+ // calculate next possible angle
+ if(NextPosibleAngle(angle))
+ return true;
+ }
+
+ return false;
+}
+
+bool ObjectPosSelector::NextUsedAngle(float& angle)
+{
+ while(m_nextUsedPos[USED_POS_PLUS]!=m_UsedPosLists[USED_POS_PLUS].end() ||
+ m_nextUsedPos[USED_POS_MINUS]!=m_UsedPosLists[USED_POS_MINUS].end() )
+ {
+ // calculate next possible angle
+ if(!NextPosibleAngle(angle))
+ return true;
+ }
+
+ return false;
+}
+
+bool ObjectPosSelector::NextPosibleAngle( float& angle )
+{
+ // ++ direction less updated
+ if( m_nextUsedPos[USED_POS_PLUS]!=m_UsedPosLists[USED_POS_PLUS].end() &&
+ (m_nextUsedPos[USED_POS_MINUS]==m_UsedPosLists[USED_POS_MINUS].end() || m_nextUsedPos[USED_POS_PLUS]->first <= m_nextUsedPos[USED_POS_MINUS]->first) )
+ {
+ bool ok;
+ if(m_smallStepOk[USED_POS_PLUS])
+ ok = NextSmallStepAngle(1.0,USED_POS_PLUS,angle);
+ else
+ ok = NextAngleFor(*m_nextUsedPos[USED_POS_PLUS],1.0,USED_POS_PLUS,angle);
+
+ if(!ok)
+ ++m_nextUsedPos[USED_POS_PLUS]; // increase. only at fail (original or checked)
+ return ok;
+ }
+ // -- direction less updated
+ else if( m_nextUsedPos[USED_POS_MINUS]!=m_UsedPosLists[USED_POS_MINUS].end())
+ {
+ bool ok;
+ if(m_smallStepOk[USED_POS_MINUS])
+ ok = NextSmallStepAngle(-1.0,USED_POS_MINUS,angle);
+ else
+ ok = NextAngleFor(*m_nextUsedPos[USED_POS_MINUS],-1.0,USED_POS_MINUS,angle);
+
+ if(!ok)
+ ++m_nextUsedPos[USED_POS_MINUS];
+ return ok;
+ }
+ else // both list empty
+ {
+ if( m_smallStepOk[USED_POS_PLUS] && (!m_smallStepOk[USED_POS_MINUS] || m_smallStepAngle[USED_POS_PLUS] <= m_smallStepAngle[USED_POS_MINUS]) )
+ {
+ return NextSmallStepAngle(1.0,USED_POS_PLUS,angle);
+ }
+ // -- direction less updated
+ else if( m_smallStepOk[USED_POS_MINUS] )
+ {
+ return NextSmallStepAngle(-1.0,USED_POS_MINUS,angle);
+ }
+ }
+
+ // no angles
+ return false;
+}
diff --git a/src/game/ObjectPosSelector.h b/src/game/ObjectPosSelector.h
new file mode 100644
index 00000000000..84050611121
--- /dev/null
+++ b/src/game/ObjectPosSelector.h
@@ -0,0 +1,155 @@
+/*
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _OBJECT_POS_SELECTOR_H
+#define _OBJECT_POS_SELECTOR_H
+
+#include<Common.h>
+
+#include<map>
+
+enum UsedPosType { USED_POS_PLUS, USED_POS_MINUS };
+
+inline UsedPosType operator ~(UsedPosType uptype)
+{
+ return uptype==USED_POS_PLUS ? USED_POS_MINUS : USED_POS_PLUS;
+}
+
+struct ObjectPosSelector
+{
+ struct UsedPos
+ {
+ UsedPos(float sign_, float size_,float dist_) : sign(sign_), size(size_),dist(dist_) {}
+
+ float sign;
+
+ float size; // size of point
+ float dist; // dist to central point (including central point size)
+ };
+
+ typedef std::multimap<float,UsedPos> UsedPosList; // abs(angle)->Node
+
+ ObjectPosSelector(float x,float y,float size,float dist);
+
+ void AddUsedPos(float size,float angle,float dist);
+ void InitializeAngle();
+
+ bool FirstAngle(float& angle);
+ bool NextAngle(float& angle);
+ bool NextUsedAngle(float& angle);
+
+ bool NextPosibleAngle( float& angle );
+
+ bool CheckAngle(UsedPosList::value_type const& nextUsedPos, float sign, float angle ) const
+ {
+ float angle_step2 = GetAngle(nextUsedPos.second);
+
+ float next_angle = nextUsedPos.first;
+ if(nextUsedPos.second.sign * sign < 0) // last node from diff. list (-pi+alpha)
+ next_angle = 2*M_PI-next_angle; // move to positive
+
+ return fabs(angle)+angle_step2 <= next_angle;
+ }
+
+ bool CheckOriginal() const
+ {
+ return (m_UsedPosLists[USED_POS_PLUS].empty() || CheckAngle( *m_UsedPosLists[USED_POS_PLUS].begin(),1.0,0)) &&
+ (m_UsedPosLists[USED_POS_MINUS].empty() || CheckAngle( *m_UsedPosLists[USED_POS_MINUS].begin(),-1.0,0));
+ }
+
+ bool IsNonBalanced() const { return m_UsedPosLists[USED_POS_PLUS].empty() != m_UsedPosLists[USED_POS_MINUS].empty(); }
+
+ bool NextAngleFor( UsedPosList::value_type const& usedPos, float sign, UsedPosType uptype, float &angle )
+ {
+ float angle_step = GetAngle(usedPos.second);
+
+ // next possible angle
+ angle = usedPos.first * usedPos.second.sign + angle_step * sign;
+
+ UsedPosList::value_type const* nextNode = nextUsedPos(uptype);
+ if(nextNode)
+ {
+ // if next node permit use selected angle, then do it
+ if(!CheckAngle(*nextNode, sign, angle))
+ {
+ m_smallStepOk[uptype] = false;
+ return false;
+ }
+ }
+
+ // possible more points
+ m_smallStepOk[uptype] = true;
+ m_smallStepAngle[uptype] = angle;
+ m_smallStepNextUsedPos[uptype] = nextNode;
+
+ return true;
+ }
+
+ bool NextSmallStepAngle( float sign, UsedPosType uptype, float &angle )
+ {
+ // next possible angle
+ angle = m_smallStepAngle[uptype] + m_anglestep * sign;
+
+ if(fabs(angle) > M_PI)
+ {
+ m_smallStepOk[uptype] = false;
+ return false;
+ }
+
+ if(m_smallStepNextUsedPos[uptype])
+ {
+ if(fabs(angle) >= m_smallStepNextUsedPos[uptype]->first)
+ {
+ m_smallStepOk[uptype] = false;
+ return false;
+ }
+
+ // if next node permit use selected angle, then do it
+ if(!CheckAngle(*m_smallStepNextUsedPos[uptype], sign, angle))
+ {
+ m_smallStepOk[uptype] = false;
+ return false;
+ }
+ }
+
+ // possible more points
+ m_smallStepAngle[uptype] = angle;
+ return true;
+ }
+
+ // next used post for m_nextUsedPos[uptype]
+ UsedPosList::value_type const* nextUsedPos(UsedPosType uptype);
+
+ // angle from used pos to next possible free pos
+ float GetAngle(UsedPos const& usedPos) const { return acos(m_dist/(usedPos.dist+usedPos.size+m_size)); }
+
+ float m_center_x;
+ float m_center_y;
+ float m_size; // size of object in center
+ float m_dist; // distance for searching pos (including central object size)
+ float m_anglestep;
+
+ UsedPosList m_UsedPosLists[2];
+ UsedPosList::const_iterator m_nextUsedPos[2];
+
+ // field for small step from first after next used pos until next pos
+ float m_smallStepAngle[2];
+ bool m_smallStepOk[2];
+ UsedPosList::value_type const* m_smallStepNextUsedPos[2];
+};
+#endif
diff --git a/src/game/Opcodes.cpp b/src/game/Opcodes.cpp
index 7012ea04fb6..78fdeb8d0ce 100644
--- a/src/game/Opcodes.cpp
+++ b/src/game/Opcodes.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -28,1064 +28,1201 @@
/// Correspondence between opcodes and their names
OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
{
- /*0x000*/ { "MSG_NULL_ACTION", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x001*/ { "CMSG_BOOTME", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x002*/ { "CMSG_DBLOOKUP", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x003*/ { "SMSG_DBLOOKUP", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x004*/ { "CMSG_QUERY_OBJECT_POSITION", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x005*/ { "SMSG_QUERY_OBJECT_POSITION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x006*/ { "CMSG_QUERY_OBJECT_ROTATION", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x007*/ { "SMSG_QUERY_OBJECT_ROTATION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x008*/ { "CMSG_WORLD_TELEPORT", STATUS_LOGGEDIN, &WorldSession::HandleWorldTeleportOpcode },
- /*0x009*/ { "CMSG_TELEPORT_TO_UNIT", STATUS_LOGGEDIN, &WorldSession::Handle_NULL },
- /*0x00A*/ { "CMSG_ZONE_MAP", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x00B*/ { "SMSG_ZONE_MAP", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x00C*/ { "CMSG_DEBUG_CHANGECELLZONE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x00D*/ { "CMSG_EMBLAZON_TABARD_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x00E*/ { "CMSG_UNEMBLAZON_TABARD_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x00F*/ { "CMSG_RECHARGE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x010*/ { "CMSG_LEARN_SPELL", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x011*/ { "CMSG_CREATEMONSTER", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x012*/ { "CMSG_DESTROYMONSTER", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x013*/ { "CMSG_CREATEITEM", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x014*/ { "CMSG_CREATEGAMEOBJECT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x015*/ { "SMSG_CHECK_FOR_BOTS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x016*/ { "CMSG_MAKEMONSTERATTACKGUID", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x017*/ { "CMSG_BOT_DETECTED2", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x018*/ { "CMSG_FORCEACTION", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x019*/ { "CMSG_FORCEACTIONONOTHER", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x01A*/ { "CMSG_FORCEACTIONSHOW", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x01B*/ { "SMSG_FORCEACTIONSHOW", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x01C*/ { "CMSG_PETGODMODE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x01D*/ { "SMSG_PETGODMODE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x01E*/ { "SMSG_DEBUGINFOSPELLMISS_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x01F*/ { "CMSG_WEATHER_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x020*/ { "CMSG_UNDRESSPLAYER", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x021*/ { "CMSG_BEASTMASTER", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x022*/ { "CMSG_GODMODE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x023*/ { "SMSG_GODMODE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x024*/ { "CMSG_CHEAT_SETMONEY", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x025*/ { "CMSG_LEVEL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x026*/ { "CMSG_PET_LEVEL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x027*/ { "CMSG_SET_WORLDSTATE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x028*/ { "CMSG_COOLDOWN_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x029*/ { "CMSG_USE_SKILL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x02A*/ { "CMSG_FLAG_QUEST", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x02B*/ { "CMSG_FLAG_QUEST_FINISH", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x02C*/ { "CMSG_CLEAR_QUEST", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x02D*/ { "CMSG_SEND_EVENT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x02E*/ { "CMSG_DEBUG_AISTATE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x02F*/ { "SMSG_DEBUG_AISTATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x030*/ { "CMSG_DISABLE_PVP_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x031*/ { "CMSG_ADVANCE_SPAWN_TIME", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x032*/ { "CMSG_PVP_PORT_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x033*/ { "CMSG_AUTH_SRP6_BEGIN", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x034*/ { "CMSG_AUTH_SRP6_PROOF", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x035*/ { "CMSG_AUTH_SRP6_RECODE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x036*/ { "CMSG_CHAR_CREATE", STATUS_AUTHED, &WorldSession::HandleCharCreateOpcode },
- /*0x037*/ { "CMSG_CHAR_ENUM", STATUS_AUTHED, &WorldSession::HandleCharEnumOpcode },
- /*0x038*/ { "CMSG_CHAR_DELETE", STATUS_AUTHED, &WorldSession::HandleCharDeleteOpcode },
- /*0x039*/ { "SMSG_AUTH_SRP6_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x03A*/ { "SMSG_CHAR_CREATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x03B*/ { "SMSG_CHAR_ENUM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x03C*/ { "SMSG_CHAR_DELETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x03D*/ { "CMSG_PLAYER_LOGIN", STATUS_AUTHED, &WorldSession::HandlePlayerLoginOpcode },
- /*0x03E*/ { "SMSG_NEW_WORLD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x03F*/ { "SMSG_TRANSFER_PENDING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x040*/ { "SMSG_TRANSFER_ABORTED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x041*/ { "SMSG_CHARACTER_LOGIN_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x042*/ { "SMSG_LOGIN_SETTIMESPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x043*/ { "SMSG_GAMETIME_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x044*/ { "CMSG_GAMETIME_SET", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x045*/ { "SMSG_GAMETIME_SET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x046*/ { "CMSG_GAMESPEED_SET", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x047*/ { "SMSG_GAMESPEED_SET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x048*/ { "CMSG_SERVERTIME", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x049*/ { "SMSG_SERVERTIME", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x04A*/ { "CMSG_PLAYER_LOGOUT", STATUS_LOGGEDIN, &WorldSession::HandlePlayerLogoutOpcode },
- /*0x04B*/ { "CMSG_LOGOUT_REQUEST", STATUS_LOGGEDIN, &WorldSession::HandleLogoutRequestOpcode },
- /*0x04C*/ { "SMSG_LOGOUT_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x04D*/ { "SMSG_LOGOUT_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x04E*/ { "CMSG_LOGOUT_CANCEL", STATUS_LOGGEDIN, &WorldSession::HandleLogoutCancelOpcode },
- /*0x04F*/ { "SMSG_LOGOUT_CANCEL_ACK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x050*/ { "CMSG_NAME_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleNameQueryOpcode },
- /*0x051*/ { "SMSG_NAME_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x052*/ { "CMSG_PET_NAME_QUERY", STATUS_LOGGEDIN, &WorldSession::HandlePetNameQuery },
- /*0x053*/ { "SMSG_PET_NAME_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x054*/ { "CMSG_GUILD_QUERY", STATUS_AUTHED, &WorldSession::HandleGuildQueryOpcode },
- /*0x055*/ { "SMSG_GUILD_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x056*/ { "CMSG_ITEM_QUERY_SINGLE", STATUS_LOGGEDIN, &WorldSession::HandleItemQuerySingleOpcode },
- /*0x057*/ { "CMSG_ITEM_QUERY_MULTIPLE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x058*/ { "SMSG_ITEM_QUERY_SINGLE_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x059*/ { "SMSG_ITEM_QUERY_MULTIPLE_RESPONSE",STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x05A*/ { "CMSG_PAGE_TEXT_QUERY", STATUS_LOGGEDIN, &WorldSession::HandlePageQueryOpcode },
- /*0x05B*/ { "SMSG_PAGE_TEXT_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x05C*/ { "CMSG_QUEST_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleQuestQueryOpcode },
- /*0x05D*/ { "SMSG_QUEST_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x05E*/ { "CMSG_GAMEOBJECT_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleGameObjectQueryOpcode },
- /*0x05F*/ { "SMSG_GAMEOBJECT_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x060*/ { "CMSG_CREATURE_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleCreatureQueryOpcode },
- /*0x061*/ { "SMSG_CREATURE_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x062*/ { "CMSG_WHO", STATUS_LOGGEDIN, &WorldSession::HandleWhoOpcode },
- /*0x063*/ { "SMSG_WHO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x064*/ { "CMSG_WHOIS", STATUS_LOGGEDIN, &WorldSession::HandleWhoisOpcode },
- /*0x065*/ { "SMSG_WHOIS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x066*/ { "CMSG_CONTACT_LIST", STATUS_LOGGEDIN, &WorldSession::HandleFriendListOpcode },
- /*0x067*/ { "SMSG_CONTACT_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x068*/ { "SMSG_FRIEND_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x069*/ { "CMSG_ADD_FRIEND", STATUS_LOGGEDIN, &WorldSession::HandleAddFriendOpcode },
- /*0x06A*/ { "CMSG_DEL_FRIEND", STATUS_LOGGEDIN, &WorldSession::HandleDelFriendOpcode },
- /*0x06B*/ { "CMSG_SET_CONTACT_NOTES", STATUS_LOGGEDIN, &WorldSession::HandleSetFriendNoteOpcode },
- /*0x06C*/ { "CMSG_ADD_IGNORE", STATUS_LOGGEDIN, &WorldSession::HandleAddIgnoreOpcode },
- /*0x06D*/ { "CMSG_DEL_IGNORE", STATUS_LOGGEDIN, &WorldSession::HandleDelIgnoreOpcode },
- /*0x06E*/ { "CMSG_GROUP_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleGroupInviteOpcode },
- /*0x06F*/ { "SMSG_GROUP_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x070*/ { "CMSG_GROUP_CANCEL", STATUS_LOGGEDIN, &WorldSession::Handle_Deprecated },
- /*0x071*/ { "SMSG_GROUP_CANCEL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x072*/ { "CMSG_GROUP_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleGroupAcceptOpcode },
- /*0x073*/ { "CMSG_GROUP_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandleGroupDeclineOpcode },
- /*0x074*/ { "SMSG_GROUP_DECLINE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x075*/ { "CMSG_GROUP_UNINVITE", STATUS_LOGGEDIN, &WorldSession::HandleGroupUninviteNameOpcode },
- /*0x076*/ { "CMSG_GROUP_UNINVITE_GUID", STATUS_LOGGEDIN, &WorldSession::HandleGroupUninviteGuidOpcode },
- /*0x077*/ { "SMSG_GROUP_UNINVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x078*/ { "CMSG_GROUP_SET_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleGroupSetLeaderOpcode },
- /*0x079*/ { "SMSG_GROUP_SET_LEADER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x07A*/ { "CMSG_LOOT_METHOD", STATUS_LOGGEDIN, &WorldSession::HandleLootMethodOpcode },
- /*0x07B*/ { "CMSG_GROUP_DISBAND", STATUS_LOGGEDIN, &WorldSession::HandleGroupLeaveOpcode },
- /*0x07C*/ { "SMSG_GROUP_DESTROYED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x07D*/ { "SMSG_GROUP_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x07E*/ { "SMSG_PARTY_MEMBER_STATS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x07F*/ { "SMSG_PARTY_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x080*/ { "UMSG_UPDATE_GROUP_MEMBERS", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x081*/ { "CMSG_GUILD_CREATE", STATUS_LOGGEDIN, &WorldSession::HandleGuildCreateOpcode },
- /*0x082*/ { "CMSG_GUILD_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleGuildInviteOpcode },
- /*0x083*/ { "SMSG_GUILD_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x084*/ { "CMSG_GUILD_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleGuildAcceptOpcode },
- /*0x085*/ { "CMSG_GUILD_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandleGuildDeclineOpcode },
- /*0x086*/ { "SMSG_GUILD_DECLINE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x087*/ { "CMSG_GUILD_INFO", STATUS_LOGGEDIN, &WorldSession::HandleGuildInfoOpcode },
- /*0x088*/ { "SMSG_GUILD_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x089*/ { "CMSG_GUILD_ROSTER", STATUS_LOGGEDIN, &WorldSession::HandleGuildRosterOpcode },
- /*0x08A*/ { "SMSG_GUILD_ROSTER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x08B*/ { "CMSG_GUILD_PROMOTE", STATUS_LOGGEDIN, &WorldSession::HandleGuildPromoteOpcode },
- /*0x08C*/ { "CMSG_GUILD_DEMOTE", STATUS_LOGGEDIN, &WorldSession::HandleGuildDemoteOpcode },
- /*0x08D*/ { "CMSG_GUILD_LEAVE", STATUS_LOGGEDIN, &WorldSession::HandleGuildLeaveOpcode },
- /*0x08E*/ { "CMSG_GUILD_REMOVE", STATUS_LOGGEDIN, &WorldSession::HandleGuildRemoveOpcode },
- /*0x08F*/ { "CMSG_GUILD_DISBAND", STATUS_LOGGEDIN, &WorldSession::HandleGuildDisbandOpcode },
- /*0x090*/ { "CMSG_GUILD_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleGuildLeaderOpcode },
- /*0x091*/ { "CMSG_GUILD_MOTD", STATUS_LOGGEDIN, &WorldSession::HandleGuildMOTDOpcode },
- /*0x092*/ { "SMSG_GUILD_EVENT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x093*/ { "SMSG_GUILD_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x094*/ { "UMSG_UPDATE_GUILD", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x095*/ { "CMSG_MESSAGECHAT", STATUS_LOGGEDIN, &WorldSession::HandleMessagechatOpcode },
- /*0x096*/ { "SMSG_MESSAGECHAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x097*/ { "CMSG_JOIN_CHANNEL", STATUS_LOGGEDIN, &WorldSession::HandleChannelJoin },
- /*0x098*/ { "CMSG_LEAVE_CHANNEL", STATUS_LOGGEDIN, &WorldSession::HandleChannelLeave },
- /*0x099*/ { "SMSG_CHANNEL_NOTIFY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x09A*/ { "CMSG_CHANNEL_LIST", STATUS_LOGGEDIN, &WorldSession::HandleChannelList },
- /*0x09B*/ { "SMSG_CHANNEL_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x09C*/ { "CMSG_CHANNEL_PASSWORD", STATUS_LOGGEDIN, &WorldSession::HandleChannelPassword },
- /*0x09D*/ { "CMSG_CHANNEL_SET_OWNER", STATUS_LOGGEDIN, &WorldSession::HandleChannelSetOwner },
- /*0x09E*/ { "CMSG_CHANNEL_OWNER", STATUS_LOGGEDIN, &WorldSession::HandleChannelOwner },
- /*0x09F*/ { "CMSG_CHANNEL_MODERATOR", STATUS_LOGGEDIN, &WorldSession::HandleChannelModerator },
- /*0x0A0*/ { "CMSG_CHANNEL_UNMODERATOR", STATUS_LOGGEDIN, &WorldSession::HandleChannelUnmoderator },
- /*0x0A1*/ { "CMSG_CHANNEL_MUTE", STATUS_LOGGEDIN, &WorldSession::HandleChannelMute },
- /*0x0A2*/ { "CMSG_CHANNEL_UNMUTE", STATUS_LOGGEDIN, &WorldSession::HandleChannelUnmute },
- /*0x0A3*/ { "CMSG_CHANNEL_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleChannelInvite },
- /*0x0A4*/ { "CMSG_CHANNEL_KICK", STATUS_LOGGEDIN, &WorldSession::HandleChannelKick },
- /*0x0A5*/ { "CMSG_CHANNEL_BAN", STATUS_LOGGEDIN, &WorldSession::HandleChannelBan },
- /*0x0A6*/ { "CMSG_CHANNEL_UNBAN", STATUS_LOGGEDIN, &WorldSession::HandleChannelUnban },
- /*0x0A7*/ { "CMSG_CHANNEL_ANNOUNCEMENTS", STATUS_LOGGEDIN, &WorldSession::HandleChannelAnnounce },
- /*0x0A8*/ { "CMSG_CHANNEL_MODERATE", STATUS_LOGGEDIN, &WorldSession::HandleChannelModerate },
- /*0x0A9*/ { "SMSG_UPDATE_OBJECT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0AA*/ { "SMSG_DESTROY_OBJECT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0AB*/ { "CMSG_USE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleUseItemOpcode },
- /*0x0AC*/ { "CMSG_OPEN_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleOpenItemOpcode },
- /*0x0AD*/ { "CMSG_READ_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleReadItem },
- /*0x0AE*/ { "SMSG_READ_ITEM_OK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0AF*/ { "SMSG_READ_ITEM_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0B0*/ { "SMSG_ITEM_COOLDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0B1*/ { "CMSG_GAMEOBJ_USE", STATUS_LOGGEDIN, &WorldSession::HandleGameObjectUseOpcode },
- /*0x0B2*/ { "CMSG_GAMEOBJ_CHAIR_USE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0B3*/ { "SMSG_GAMEOBJECT_CUSTOM_ANIM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0B4*/ { "CMSG_AREATRIGGER", STATUS_LOGGEDIN, &WorldSession::HandleAreaTriggerOpcode },
- /*0x0B5*/ { "MSG_MOVE_START_FORWARD", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0B6*/ { "MSG_MOVE_START_BACKWARD", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0B7*/ { "MSG_MOVE_STOP", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0B8*/ { "MSG_MOVE_START_STRAFE_LEFT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0B9*/ { "MSG_MOVE_START_STRAFE_RIGHT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0BA*/ { "MSG_MOVE_STOP_STRAFE", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0BB*/ { "MSG_MOVE_JUMP", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0BC*/ { "MSG_MOVE_START_TURN_LEFT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0BD*/ { "MSG_MOVE_START_TURN_RIGHT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0BE*/ { "MSG_MOVE_STOP_TURN", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0BF*/ { "MSG_MOVE_START_PITCH_UP", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0C0*/ { "MSG_MOVE_START_PITCH_DOWN", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0C1*/ { "MSG_MOVE_STOP_PITCH", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0C2*/ { "MSG_MOVE_SET_RUN_MODE", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0C3*/ { "MSG_MOVE_SET_WALK_MODE", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0C4*/ { "MSG_MOVE_TOGGLE_LOGGING", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0C5*/ { "MSG_MOVE_TELEPORT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0C6*/ { "MSG_MOVE_TELEPORT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0C7*/ { "MSG_MOVE_TELEPORT_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveTeleportAck },
- /*0x0C8*/ { "MSG_MOVE_TOGGLE_FALL_LOGGING", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0C9*/ { "MSG_MOVE_FALL_LAND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0CA*/ { "MSG_MOVE_START_SWIM", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0CB*/ { "MSG_MOVE_STOP_SWIM", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0CC*/ { "MSG_MOVE_SET_RUN_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0CD*/ { "MSG_MOVE_SET_RUN_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0CE*/ { "MSG_MOVE_SET_RUN_BACK_SPEED_CHEAT",STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0CF*/ { "MSG_MOVE_SET_RUN_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0D0*/ { "MSG_MOVE_SET_WALK_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0D1*/ { "MSG_MOVE_SET_WALK_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0D2*/ { "MSG_MOVE_SET_SWIM_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0D3*/ { "MSG_MOVE_SET_SWIM_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0D4*/ { "MSG_MOVE_SET_SWIM_BACK_SPEED_CHEAT",STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0D5*/ { "MSG_MOVE_SET_SWIM_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0D6*/ { "MSG_MOVE_SET_ALL_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0D7*/ { "MSG_MOVE_SET_TURN_RATE_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0D8*/ { "MSG_MOVE_SET_TURN_RATE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0D9*/ { "MSG_MOVE_TOGGLE_COLLISION_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0DA*/ { "MSG_MOVE_SET_FACING", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0DB*/ { "MSG_MOVE_SET_PITCH", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0DC*/ { "MSG_MOVE_WORLDPORT_ACK", STATUS_TRANSFER_PENDING, &WorldSession::HandleMoveWorldportAckOpcode},
- /*0x0DD*/ { "SMSG_MONSTER_MOVE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0DE*/ { "SMSG_MOVE_WATER_WALK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0DF*/ { "SMSG_MOVE_LAND_WALK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0E0*/ { "MSG_MOVE_SET_RAW_POSITION_ACK", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0E1*/ { "CMSG_MOVE_SET_RAW_POSITION", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0E2*/ { "SMSG_FORCE_RUN_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0E3*/ { "CMSG_FORCE_RUN_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck },
- /*0x0E4*/ { "SMSG_FORCE_RUN_BACK_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0E5*/ { "CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK",STATUS_LOGGEDIN,&WorldSession::HandleForceSpeedChangeAck },
- /*0x0E6*/ { "SMSG_FORCE_SWIM_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0E7*/ { "CMSG_FORCE_SWIM_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck },
- /*0x0E8*/ { "SMSG_FORCE_MOVE_ROOT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0E9*/ { "CMSG_FORCE_MOVE_ROOT_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveRootAck },
- /*0x0EA*/ { "SMSG_FORCE_MOVE_UNROOT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0EB*/ { "CMSG_FORCE_MOVE_UNROOT_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveUnRootAck },
- /*0x0EC*/ { "MSG_MOVE_ROOT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0ED*/ { "MSG_MOVE_UNROOT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0EE*/ { "MSG_MOVE_HEARTBEAT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x0EF*/ { "SMSG_MOVE_KNOCK_BACK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0F0*/ { "CMSG_MOVE_KNOCK_BACK_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveKnockBackAck },
- /*0x0F1*/ { "MSG_MOVE_KNOCK_BACK", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0F2*/ { "SMSG_MOVE_FEATHER_FALL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0F3*/ { "SMSG_MOVE_NORMAL_FALL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0F4*/ { "SMSG_MOVE_SET_HOVER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0F5*/ { "SMSG_MOVE_UNSET_HOVER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0F6*/ { "CMSG_MOVE_HOVER_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveHoverAck },
- /*0x0F7*/ { "MSG_MOVE_HOVER", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0F8*/ { "CMSG_TRIGGER_CINEMATIC_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0F9*/ { "CMSG_OPENING_CINEMATIC", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x0FA*/ { "SMSG_TRIGGER_CINEMATIC", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0FB*/ { "CMSG_NEXT_CINEMATIC_CAMERA", STATUS_LOGGEDIN, &WorldSession::HandleNextCinematicCamera },
- /*0x0FC*/ { "CMSG_COMPLETE_CINEMATIC", STATUS_LOGGEDIN, &WorldSession::HandleCompleteCinema },
- /*0x0FD*/ { "SMSG_TUTORIAL_FLAGS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x0FE*/ { "CMSG_TUTORIAL_FLAG", STATUS_LOGGEDIN, &WorldSession::HandleTutorialFlag },
- /*0x0FF*/ { "CMSG_TUTORIAL_CLEAR", STATUS_LOGGEDIN, &WorldSession::HandleTutorialClear },
- /*0x100*/ { "CMSG_TUTORIAL_RESET", STATUS_LOGGEDIN, &WorldSession::HandleTutorialReset },
- /*0x101*/ { "CMSG_STANDSTATECHANGE", STATUS_LOGGEDIN, &WorldSession::HandleStandStateChangeOpcode },
- /*0x102*/ { "CMSG_EMOTE", STATUS_LOGGEDIN, &WorldSession::HandleEmoteOpcode },
- /*0x103*/ { "SMSG_EMOTE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x104*/ { "CMSG_TEXT_EMOTE", STATUS_LOGGEDIN, &WorldSession::HandleTextEmoteOpcode },
- /*0x105*/ { "SMSG_TEXT_EMOTE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x106*/ { "CMSG_AUTOEQUIP_GROUND_ITEM", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x107*/ { "CMSG_AUTOSTORE_GROUND_ITEM", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x108*/ { "CMSG_AUTOSTORE_LOOT_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutostoreLootItemOpcode },
- /*0x109*/ { "CMSG_STORE_LOOT_IN_SLOT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x10A*/ { "CMSG_AUTOEQUIP_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoEquipItemOpcode },
- /*0x10B*/ { "CMSG_AUTOSTORE_BAG_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoStoreBagItemOpcode },
- /*0x10C*/ { "CMSG_SWAP_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSwapItem },
- /*0x10D*/ { "CMSG_SWAP_INV_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSwapInvItemOpcode },
- /*0x10E*/ { "CMSG_SPLIT_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSplitItemOpcode },
- /*0x10F*/ { "CMSG_AUTOEQUIP_ITEM_SLOT", STATUS_LOGGEDIN, &WorldSession::HandleAutoEquipItemSlotOpcode },
- /*0x110*/ { "OBSOLETE_DROP_ITEM", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x111*/ { "CMSG_DESTROYITEM", STATUS_LOGGEDIN, &WorldSession::HandleDestroyItemOpcode },
- /*0x112*/ { "SMSG_INVENTORY_CHANGE_FAILURE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x113*/ { "SMSG_OPEN_CONTAINER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x114*/ { "CMSG_INSPECT", STATUS_LOGGEDIN, &WorldSession::HandleInspectOpcode },
- /*0x115*/ { "SMSG_INSPECT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x116*/ { "CMSG_INITIATE_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleInitiateTradeOpcode },
- /*0x117*/ { "CMSG_BEGIN_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleBeginTradeOpcode },
- /*0x118*/ { "CMSG_BUSY_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleBusyTradeOpcode },
- /*0x119*/ { "CMSG_IGNORE_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleIgnoreTradeOpcode },
- /*0x11A*/ { "CMSG_ACCEPT_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleAcceptTradeOpcode },
- /*0x11B*/ { "CMSG_UNACCEPT_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleUnacceptTradeOpcode },
- /*0x11C*/ { "CMSG_CANCEL_TRADE", STATUS_AUTHED, &WorldSession::HandleCancelTradeOpcode },
- /*0x11D*/ { "CMSG_SET_TRADE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSetTradeItemOpcode },
- /*0x11E*/ { "CMSG_CLEAR_TRADE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleClearTradeItemOpcode },
- /*0x11F*/ { "CMSG_SET_TRADE_GOLD", STATUS_LOGGEDIN, &WorldSession::HandleSetTradeGoldOpcode },
- /*0x120*/ { "SMSG_TRADE_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x121*/ { "SMSG_TRADE_STATUS_EXTENDED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x122*/ { "SMSG_INITIALIZE_FACTIONS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x123*/ { "SMSG_SET_FACTION_VISIBLE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x124*/ { "SMSG_SET_FACTION_STANDING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x125*/ { "CMSG_SET_FACTION_ATWAR", STATUS_LOGGEDIN, &WorldSession::HandleSetFactionAtWar },
- /*0x126*/ { "CMSG_SET_FACTION_CHEAT", STATUS_LOGGEDIN, &WorldSession::HandleSetFactionCheat },
- /*0x127*/ { "SMSG_SET_PROFICIENCY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x128*/ { "CMSG_SET_ACTION_BUTTON", STATUS_LOGGEDIN, &WorldSession::HandleSetActionButtonOpcode },
- /*0x129*/ { "SMSG_ACTION_BUTTONS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x12A*/ { "SMSG_INITIAL_SPELLS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x12B*/ { "SMSG_LEARNED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x12C*/ { "SMSG_SUPERCEDED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x12D*/ { "CMSG_NEW_SPELL_SLOT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x12E*/ { "CMSG_CAST_SPELL", STATUS_LOGGEDIN, &WorldSession::HandleCastSpellOpcode },
- /*0x12F*/ { "CMSG_CANCEL_CAST", STATUS_LOGGEDIN, &WorldSession::HandleCancelCastOpcode },
- /*0x130*/ { "SMSG_CAST_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x131*/ { "SMSG_SPELL_START", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x132*/ { "SMSG_SPELL_GO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x133*/ { "SMSG_SPELL_FAILURE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x134*/ { "SMSG_SPELL_COOLDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x135*/ { "SMSG_COOLDOWN_EVENT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x136*/ { "CMSG_CANCEL_AURA", STATUS_LOGGEDIN, &WorldSession::HandleCancelAuraOpcode },
- /*0x137*/ { "SMSG_UPDATE_AURA_DURATION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x138*/ { "SMSG_PET_CAST_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x139*/ { "MSG_CHANNEL_START", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x13A*/ { "MSG_CHANNEL_UPDATE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x13B*/ { "CMSG_CANCEL_CHANNELLING", STATUS_LOGGEDIN, &WorldSession::HandleCancelChanneling },
- /*0x13C*/ { "SMSG_AI_REACTION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x13D*/ { "CMSG_SET_SELECTION", STATUS_LOGGEDIN, &WorldSession::HandleSetSelectionOpcode },
- /*0x13E*/ { "CMSG_SET_TARGET_OBSOLETE", STATUS_LOGGEDIN, &WorldSession::HandleSetTargetOpcode },
- /*0x13F*/ { "CMSG_UNUSED", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x140*/ { "CMSG_UNUSED2", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x141*/ { "CMSG_ATTACKSWING", STATUS_LOGGEDIN, &WorldSession::HandleAttackSwingOpcode },
- /*0x142*/ { "CMSG_ATTACKSTOP", STATUS_LOGGEDIN, &WorldSession::HandleAttackStopOpcode },
- /*0x143*/ { "SMSG_ATTACKSTART", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x144*/ { "SMSG_ATTACKSTOP", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x145*/ { "SMSG_ATTACKSWING_NOTINRANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x146*/ { "SMSG_ATTACKSWING_BADFACING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x147*/ { "SMSG_ATTACKSWING_NOTSTANDING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x148*/ { "SMSG_ATTACKSWING_DEADTARGET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x149*/ { "SMSG_ATTACKSWING_CANT_ATTACK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x14A*/ { "SMSG_ATTACKERSTATEUPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x14B*/ { "SMSG_VICTIMSTATEUPDATE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x14C*/ { "SMSG_DAMAGE_DONE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x14D*/ { "SMSG_DAMAGE_TAKEN_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x14E*/ { "SMSG_CANCEL_COMBAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x14F*/ { "SMSG_PLAYER_COMBAT_XP_GAIN_OBSOLETE",STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x150*/ { "SMSG_SPELLHEALLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x151*/ { "SMSG_SPELLENERGIZELOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x152*/ { "CMSG_SHEATHE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x153*/ { "CMSG_SAVE_PLAYER", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x154*/ { "CMSG_SETDEATHBINDPOINT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x155*/ { "SMSG_BINDPOINTUPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x156*/ { "CMSG_GETDEATHBINDZONE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x157*/ { "SMSG_BINDZONEREPLY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x158*/ { "SMSG_PLAYERBOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x159*/ { "SMSG_CLIENT_CONTROL_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x15A*/ { "CMSG_REPOP_REQUEST", STATUS_LOGGEDIN, &WorldSession::HandleRepopRequestOpcode },
- /*0x15B*/ { "SMSG_RESURRECT_REQUEST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x15C*/ { "CMSG_RESURRECT_RESPONSE", STATUS_LOGGEDIN, &WorldSession::HandleResurrectResponseOpcode },
- /*0x15D*/ { "CMSG_LOOT", STATUS_LOGGEDIN, &WorldSession::HandleLootOpcode },
- /*0x15E*/ { "CMSG_LOOT_MONEY", STATUS_LOGGEDIN, &WorldSession::HandleLootMoneyOpcode },
- /*0x15F*/ { "CMSG_LOOT_RELEASE", STATUS_LOGGEDIN, &WorldSession::HandleLootReleaseOpcode },
- /*0x160*/ { "SMSG_LOOT_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x161*/ { "SMSG_LOOT_RELEASE_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x162*/ { "SMSG_LOOT_REMOVED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x163*/ { "SMSG_LOOT_MONEY_NOTIFY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x164*/ { "SMSG_LOOT_ITEM_NOTIFY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x165*/ { "SMSG_LOOT_CLEAR_MONEY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x166*/ { "SMSG_ITEM_PUSH_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x167*/ { "SMSG_DUEL_REQUESTED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x168*/ { "SMSG_DUEL_OUTOFBOUNDS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x169*/ { "SMSG_DUEL_INBOUNDS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x16A*/ { "SMSG_DUEL_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x16B*/ { "SMSG_DUEL_WINNER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x16C*/ { "CMSG_DUEL_ACCEPTED", STATUS_LOGGEDIN, &WorldSession::HandleDuelAcceptedOpcode },
- /*0x16D*/ { "CMSG_DUEL_CANCELLED", STATUS_LOGGEDIN, &WorldSession::HandleDuelCancelledOpcode },
- /*0x16E*/ { "SMSG_MOUNTRESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x16F*/ { "SMSG_DISMOUNTRESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x170*/ { "SMSG_PUREMOUNT_CANCELLED_OBSOLETE",STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x171*/ { "CMSG_MOUNTSPECIAL_ANIM", STATUS_LOGGEDIN, &WorldSession::HandleMountSpecialAnimOpcode },
- /*0x172*/ { "SMSG_MOUNTSPECIAL_ANIM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x173*/ { "SMSG_PET_TAME_FAILURE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x174*/ { "CMSG_PET_SET_ACTION", STATUS_LOGGEDIN, &WorldSession::HandlePetSetAction },
- /*0x175*/ { "CMSG_PET_ACTION", STATUS_LOGGEDIN, &WorldSession::HandlePetAction },
- /*0x176*/ { "CMSG_PET_ABANDON", STATUS_LOGGEDIN, &WorldSession::HandlePetAbandon },
- /*0x177*/ { "CMSG_PET_RENAME", STATUS_LOGGEDIN, &WorldSession::HandlePetRename },
- /*0x178*/ { "SMSG_PET_NAME_INVALID", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x179*/ { "SMSG_PET_SPELLS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x17A*/ { "SMSG_PET_MODE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x17B*/ { "CMSG_GOSSIP_HELLO", STATUS_LOGGEDIN, &WorldSession::HandleGossipHelloOpcode },
- /*0x17C*/ { "CMSG_GOSSIP_SELECT_OPTION", STATUS_LOGGEDIN, &WorldSession::HandleGossipSelectOptionOpcode },
- /*0x17D*/ { "SMSG_GOSSIP_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x17E*/ { "SMSG_GOSSIP_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x17F*/ { "CMSG_NPC_TEXT_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleNpcTextQueryOpcode },
- /*0x180*/ { "SMSG_NPC_TEXT_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x181*/ { "SMSG_NPC_WONT_TALK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x182*/ { "CMSG_QUESTGIVER_STATUS_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverStatusQueryOpcode},
- /*0x183*/ { "SMSG_QUESTGIVER_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x184*/ { "CMSG_QUESTGIVER_HELLO", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverHelloOpcode },
- /*0x185*/ { "SMSG_QUESTGIVER_QUEST_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x186*/ { "CMSG_QUESTGIVER_QUERY_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverQuestQueryOpcode},
- /*0x187*/ { "CMSG_QUESTGIVER_QUEST_AUTOLAUNCH", STATUS_LOGGEDIN, &WorldSession::HandleQuestAutoLaunch },
- /*0x188*/ { "SMSG_QUESTGIVER_QUEST_DETAILS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x189*/ { "CMSG_QUESTGIVER_ACCEPT_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverAcceptQuestOpcode},
- /*0x18A*/ { "CMSG_QUESTGIVER_COMPLETE_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestComplete },
- /*0x18B*/ { "SMSG_QUESTGIVER_REQUEST_ITEMS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x18C*/ { "CMSG_QUESTGIVER_REQUEST_REWARD", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverRequestRewardOpcode},
- /*0x18D*/ { "SMSG_QUESTGIVER_OFFER_REWARD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x18E*/ { "CMSG_QUESTGIVER_CHOOSE_REWARD", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverChooseRewardOpcode},
- /*0x18F*/ { "SMSG_QUESTGIVER_QUEST_INVALID", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x190*/ { "CMSG_QUESTGIVER_CANCEL", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverCancel },
- /*0x191*/ { "SMSG_QUESTGIVER_QUEST_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x192*/ { "SMSG_QUESTGIVER_QUEST_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x193*/ { "CMSG_QUESTLOG_SWAP_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestLogSwapQuest },
- /*0x194*/ { "CMSG_QUESTLOG_REMOVE_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestLogRemoveQuest },
- /*0x195*/ { "SMSG_QUESTLOG_FULL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x196*/ { "SMSG_QUESTUPDATE_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x197*/ { "SMSG_QUESTUPDATE_FAILEDTIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x198*/ { "SMSG_QUESTUPDATE_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x199*/ { "SMSG_QUESTUPDATE_ADD_KILL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x19A*/ { "SMSG_QUESTUPDATE_ADD_ITEM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x19B*/ { "CMSG_QUEST_CONFIRM_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleQuestConfirmAccept },
- /*0x19C*/ { "SMSG_QUEST_CONFIRM_ACCEPT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x19D*/ { "CMSG_PUSHQUESTTOPARTY", STATUS_LOGGEDIN, &WorldSession::HandleQuestPushToParty },
- /*0x19E*/ { "CMSG_LIST_INVENTORY", STATUS_LOGGEDIN, &WorldSession::HandleListInventoryOpcode },
- /*0x19F*/ { "SMSG_LIST_INVENTORY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1A0*/ { "CMSG_SELL_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSellItemOpcode },
- /*0x1A1*/ { "SMSG_SELL_ITEM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1A2*/ { "CMSG_BUY_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleBuyItemOpcode },
- /*0x1A3*/ { "CMSG_BUY_ITEM_IN_SLOT", STATUS_LOGGEDIN, &WorldSession::HandleBuyItemInSlotOpcode },
- /*0x1A4*/ { "SMSG_BUY_ITEM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1A5*/ { "SMSG_BUY_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1A6*/ { "CMSG_TAXICLEARALLNODES", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x1A7*/ { "CMSG_TAXIENABLEALLNODES", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x1A8*/ { "CMSG_TAXISHOWNODES", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x1A9*/ { "SMSG_SHOWTAXINODES", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1AA*/ { "CMSG_TAXINODE_STATUS_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleTaxiNodeStatusQueryOpcode },
- /*0x1AB*/ { "SMSG_TAXINODE_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1AC*/ { "CMSG_TAXIQUERYAVAILABLENODES", STATUS_LOGGEDIN, &WorldSession::HandleTaxiQueryAvailableNodesOpcode},
- /*0x1AD*/ { "CMSG_ACTIVATETAXI", STATUS_LOGGEDIN, &WorldSession::HandleActivateTaxiOpcode },
- /*0x1AE*/ { "SMSG_ACTIVATETAXIREPLY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1AF*/ { "SMSG_NEW_TAXI_PATH", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1B0*/ { "CMSG_TRAINER_LIST", STATUS_LOGGEDIN, &WorldSession::HandleTrainerListOpcode },
- /*0x1B1*/ { "SMSG_TRAINER_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1B2*/ { "CMSG_TRAINER_BUY_SPELL", STATUS_LOGGEDIN, &WorldSession::HandleTrainerBuySpellOpcode },
- /*0x1B3*/ { "SMSG_TRAINER_BUY_SUCCEEDED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1B4*/ { "SMSG_TRAINER_BUY_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1B5*/ { "CMSG_BINDER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleBinderActivateOpcode },
- /*0x1B6*/ { "SMSG_PLAYERBINDERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1B7*/ { "CMSG_BANKER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleBankerActivateOpcode },
- /*0x1B8*/ { "SMSG_SHOW_BANK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1B9*/ { "CMSG_BUY_BANK_SLOT", STATUS_LOGGEDIN, &WorldSession::HandleBuyBankSlotOpcode },
- /*0x1BA*/ { "SMSG_BUY_BANK_SLOT_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1BB*/ { "CMSG_PETITION_SHOWLIST", STATUS_LOGGEDIN, &WorldSession::HandlePetitionShowListOpcode },
- /*0x1BC*/ { "SMSG_PETITION_SHOWLIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1BD*/ { "CMSG_PETITION_BUY", STATUS_LOGGEDIN, &WorldSession::HandlePetitionBuyOpcode },
- /*0x1BE*/ { "CMSG_PETITION_SHOW_SIGNATURES", STATUS_LOGGEDIN, &WorldSession::HandlePetitionShowSignOpcode },
- /*0x1BF*/ { "SMSG_PETITION_SHOW_SIGNATURES", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1C0*/ { "CMSG_PETITION_SIGN", STATUS_LOGGEDIN, &WorldSession::HandlePetitionSignOpcode },
- /*0x1C1*/ { "SMSG_PETITION_SIGN_RESULTS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1C2*/ { "MSG_PETITION_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandlePetitionDeclineOpcode },
- /*0x1C3*/ { "CMSG_OFFER_PETITION", STATUS_LOGGEDIN, &WorldSession::HandleOfferPetitionOpcode },
- /*0x1C4*/ { "CMSG_TURN_IN_PETITION", STATUS_LOGGEDIN, &WorldSession::HandleTurnInPetitionOpcode },
- /*0x1C5*/ { "SMSG_TURN_IN_PETITION_RESULTS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1C6*/ { "CMSG_PETITION_QUERY", STATUS_LOGGEDIN, &WorldSession::HandlePetitionQueryOpcode },
- /*0x1C7*/ { "SMSG_PETITION_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1C8*/ { "SMSG_FISH_NOT_HOOKED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1C9*/ { "SMSG_FISH_ESCAPED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1CA*/ { "CMSG_BUG", STATUS_LOGGEDIN, &WorldSession::HandleBugOpcode },
- /*0x1CB*/ { "SMSG_NOTIFICATION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1CC*/ { "CMSG_PLAYED_TIME", STATUS_LOGGEDIN, &WorldSession::HandlePlayedTime },
- /*0x1CD*/ { "SMSG_PLAYED_TIME", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1CE*/ { "CMSG_QUERY_TIME", STATUS_LOGGEDIN, &WorldSession::HandleQueryTimeOpcode },
- /*0x1CF*/ { "SMSG_QUERY_TIME_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1D0*/ { "SMSG_LOG_XPGAIN", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1D1*/ { "SMSG_AURACASTLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1D2*/ { "CMSG_RECLAIM_CORPSE", STATUS_LOGGEDIN, &WorldSession::HandleCorpseReclaimOpcode },
- /*0x1D3*/ { "CMSG_WRAP_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleWrapItemOpcode },
- /*0x1D4*/ { "SMSG_LEVELUP_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1D5*/ { "MSG_MINIMAP_PING", STATUS_LOGGEDIN, &WorldSession::HandleMinimapPingOpcode },
- /*0x1D6*/ { "SMSG_RESISTLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1D7*/ { "SMSG_ENCHANTMENTLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1D8*/ { "CMSG_SET_SKILL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x1D9*/ { "SMSG_START_MIRROR_TIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1DA*/ { "SMSG_PAUSE_MIRROR_TIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1DB*/ { "SMSG_STOP_MIRROR_TIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1DC*/ { "CMSG_PING", STATUS_NEVER, &WorldSession::Handle_EarlyProccess },
- /*0x1DD*/ { "SMSG_PONG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1DE*/ { "SMSG_CLEAR_COOLDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1DF*/ { "SMSG_GAMEOBJECT_PAGETEXT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1E0*/ { "CMSG_SETSHEATHED", STATUS_LOGGEDIN, &WorldSession::HandleSetSheathedOpcode },
- /*0x1E1*/ { "SMSG_COOLDOWN_CHEAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1E2*/ { "SMSG_SPELL_DELAYED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1E3*/ { "CMSG_PLAYER_MACRO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x1E4*/ { "SMSG_PLAYER_MACRO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1E5*/ { "CMSG_GHOST", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x1E6*/ { "CMSG_GM_INVIS", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x1E7*/ { "SMSG_INVALID_PROMOTION_CODE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1E8*/ { "MSG_GM_BIND_OTHER", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x1E9*/ { "MSG_GM_SUMMON", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x1EA*/ { "SMSG_ITEM_TIME_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1EB*/ { "SMSG_ITEM_ENCHANT_TIME_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1EC*/ { "SMSG_AUTH_CHALLENGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1ED*/ { "CMSG_AUTH_SESSION", STATUS_NEVER, &WorldSession::Handle_EarlyProccess },
- /*0x1EE*/ { "SMSG_AUTH_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1EF*/ { "MSG_GM_SHOWLABEL", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x1F0*/ { "CMSG_PET_CAST_SPELL", STATUS_LOGGEDIN, &WorldSession::HandlePetCastSpellOpcode },
- /*0x1F1*/ { "MSG_SAVE_GUILD_EMBLEM", STATUS_LOGGEDIN, &WorldSession::HandleGuildSaveEmblemOpcode },
- /*0x1F2*/ { "MSG_TABARDVENDOR_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleTabardVendorActivateOpcode},
- /*0x1F3*/ { "SMSG_PLAY_SPELL_VISUAL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1F4*/ { "CMSG_ZONEUPDATE", STATUS_LOGGEDIN, &WorldSession::HandleZoneUpdateOpcode },
- /*0x1F5*/ { "SMSG_PARTYKILLLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1F6*/ { "SMSG_COMPRESSED_UPDATE_OBJECT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1F7*/ { "SMSG_PLAY_SPELL_IMPACT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1F8*/ { "SMSG_EXPLORATION_EXPERIENCE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1F9*/ { "CMSG_GM_SET_SECURITY_GROUP", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x1FA*/ { "CMSG_GM_NUKE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x1FB*/ { "MSG_RANDOM_ROLL", STATUS_LOGGEDIN, &WorldSession::HandleRandomRollOpcode },
- /*0x1FC*/ { "SMSG_ENVIRONMENTALDAMAGELOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1FD*/ { "CMSG_RWHOIS_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x1FE*/ { "SMSG_RWHOIS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1FF*/ { "MSG_LOOKING_FOR_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleLookingForGroup },
- /*0x200*/ { "CMSG_SET_LOOKING_FOR_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleSetLfgOpcode },
- /*0x201*/ { "CMSG_UNLEARN_SPELL", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x202*/ { "CMSG_UNLEARN_SKILL", STATUS_LOGGEDIN, &WorldSession::HandleUnlearnSkillOpcode },
- /*0x203*/ { "SMSG_REMOVED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x204*/ { "CMSG_DECHARGE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x205*/ { "CMSG_GMTICKET_CREATE", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketCreateOpcode },
- /*0x206*/ { "SMSG_GMTICKET_CREATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x000*/ { "MSG_NULL_ACTION", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x001*/ { "CMSG_BOOTME", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x002*/ { "CMSG_DBLOOKUP", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x003*/ { "SMSG_DBLOOKUP", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x004*/ { "CMSG_QUERY_OBJECT_POSITION", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x005*/ { "SMSG_QUERY_OBJECT_POSITION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x006*/ { "CMSG_QUERY_OBJECT_ROTATION", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x007*/ { "SMSG_QUERY_OBJECT_ROTATION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x008*/ { "CMSG_WORLD_TELEPORT", STATUS_LOGGEDIN, &WorldSession::HandleWorldTeleportOpcode },
+ /*0x009*/ { "CMSG_TELEPORT_TO_UNIT", STATUS_LOGGEDIN, &WorldSession::Handle_NULL },
+ /*0x00A*/ { "CMSG_ZONE_MAP", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x00B*/ { "SMSG_ZONE_MAP", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x00C*/ { "CMSG_DEBUG_CHANGECELLZONE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x00D*/ { "CMSG_MOVE_CHARACTER_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x00E*/ { "SMSG_MOVE_CHARACTER_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x00F*/ { "CMSG_RECHARGE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x010*/ { "CMSG_LEARN_SPELL", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x011*/ { "CMSG_CREATEMONSTER", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x012*/ { "CMSG_DESTROYMONSTER", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x013*/ { "CMSG_CREATEITEM", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x014*/ { "CMSG_CREATEGAMEOBJECT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x015*/ { "SMSG_CHECK_FOR_BOTS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x016*/ { "CMSG_MAKEMONSTERATTACKGUID", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x017*/ { "CMSG_BOT_DETECTED2", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x018*/ { "CMSG_FORCEACTION", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x019*/ { "CMSG_FORCEACTIONONOTHER", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x01A*/ { "CMSG_FORCEACTIONSHOW", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x01B*/ { "SMSG_FORCEACTIONSHOW", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x01C*/ { "CMSG_PETGODMODE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x01D*/ { "SMSG_PETGODMODE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x01E*/ { "SMSG_REFER_A_FRIEND_EXPIRED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x01F*/ { "CMSG_WEATHER_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x020*/ { "CMSG_UNDRESSPLAYER", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x021*/ { "CMSG_BEASTMASTER", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x022*/ { "CMSG_GODMODE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x023*/ { "SMSG_GODMODE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x024*/ { "CMSG_CHEAT_SETMONEY", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x025*/ { "CMSG_LEVEL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x026*/ { "CMSG_PET_LEVEL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x027*/ { "CMSG_SET_WORLDSTATE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x028*/ { "CMSG_COOLDOWN_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x029*/ { "CMSG_USE_SKILL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x02A*/ { "CMSG_FLAG_QUEST", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x02B*/ { "CMSG_FLAG_QUEST_FINISH", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x02C*/ { "CMSG_CLEAR_QUEST", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x02D*/ { "CMSG_SEND_EVENT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x02E*/ { "CMSG_DEBUG_AISTATE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x02F*/ { "SMSG_DEBUG_AISTATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x030*/ { "CMSG_DISABLE_PVP_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x031*/ { "CMSG_ADVANCE_SPAWN_TIME", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x032*/ { "SMSG_DESTRUCTIBLE_BUILDING_DAMAGE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x033*/ { "CMSG_AUTH_SRP6_BEGIN", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x034*/ { "CMSG_AUTH_SRP6_PROOF", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x035*/ { "CMSG_AUTH_SRP6_RECODE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x036*/ { "CMSG_CHAR_CREATE", STATUS_AUTHED, &WorldSession::HandleCharCreateOpcode },
+ /*0x037*/ { "CMSG_CHAR_ENUM", STATUS_AUTHED, &WorldSession::HandleCharEnumOpcode },
+ /*0x038*/ { "CMSG_CHAR_DELETE", STATUS_AUTHED, &WorldSession::HandleCharDeleteOpcode },
+ /*0x039*/ { "SMSG_AUTH_SRP6_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x03A*/ { "SMSG_CHAR_CREATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x03B*/ { "SMSG_CHAR_ENUM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x03C*/ { "SMSG_CHAR_DELETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x03D*/ { "CMSG_PLAYER_LOGIN", STATUS_AUTHED, &WorldSession::HandlePlayerLoginOpcode },
+ /*0x03E*/ { "SMSG_NEW_WORLD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x03F*/ { "SMSG_TRANSFER_PENDING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x040*/ { "SMSG_TRANSFER_ABORTED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x041*/ { "SMSG_CHARACTER_LOGIN_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x042*/ { "SMSG_LOGIN_SETTIMESPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x043*/ { "SMSG_GAMETIME_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x044*/ { "CMSG_GAMETIME_SET", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x045*/ { "SMSG_GAMETIME_SET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x046*/ { "CMSG_GAMESPEED_SET", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x047*/ { "SMSG_GAMESPEED_SET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x048*/ { "CMSG_SERVERTIME", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x049*/ { "SMSG_SERVERTIME", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x04A*/ { "CMSG_PLAYER_LOGOUT", STATUS_LOGGEDIN, &WorldSession::HandlePlayerLogoutOpcode },
+ /*0x04B*/ { "CMSG_LOGOUT_REQUEST", STATUS_LOGGEDIN, &WorldSession::HandleLogoutRequestOpcode },
+ /*0x04C*/ { "SMSG_LOGOUT_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x04D*/ { "SMSG_LOGOUT_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x04E*/ { "CMSG_LOGOUT_CANCEL", STATUS_LOGGEDIN, &WorldSession::HandleLogoutCancelOpcode },
+ /*0x04F*/ { "SMSG_LOGOUT_CANCEL_ACK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x050*/ { "CMSG_NAME_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleNameQueryOpcode },
+ /*0x051*/ { "SMSG_NAME_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x052*/ { "CMSG_PET_NAME_QUERY", STATUS_LOGGEDIN, &WorldSession::HandlePetNameQuery },
+ /*0x053*/ { "SMSG_PET_NAME_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x054*/ { "CMSG_GUILD_QUERY", STATUS_AUTHED, &WorldSession::HandleGuildQueryOpcode },
+ /*0x055*/ { "SMSG_GUILD_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x056*/ { "CMSG_ITEM_QUERY_SINGLE", STATUS_LOGGEDIN, &WorldSession::HandleItemQuerySingleOpcode },
+ /*0x057*/ { "CMSG_ITEM_QUERY_MULTIPLE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x058*/ { "SMSG_ITEM_QUERY_SINGLE_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x059*/ { "SMSG_ITEM_QUERY_MULTIPLE_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x05A*/ { "CMSG_PAGE_TEXT_QUERY", STATUS_LOGGEDIN, &WorldSession::HandlePageQueryOpcode },
+ /*0x05B*/ { "SMSG_PAGE_TEXT_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x05C*/ { "CMSG_QUEST_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleQuestQueryOpcode },
+ /*0x05D*/ { "SMSG_QUEST_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x05E*/ { "CMSG_GAMEOBJECT_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleGameObjectQueryOpcode },
+ /*0x05F*/ { "SMSG_GAMEOBJECT_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x060*/ { "CMSG_CREATURE_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleCreatureQueryOpcode },
+ /*0x061*/ { "SMSG_CREATURE_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x062*/ { "CMSG_WHO", STATUS_LOGGEDIN, &WorldSession::HandleWhoOpcode },
+ /*0x063*/ { "SMSG_WHO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x064*/ { "CMSG_WHOIS", STATUS_LOGGEDIN, &WorldSession::HandleWhoisOpcode },
+ /*0x065*/ { "SMSG_WHOIS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x066*/ { "CMSG_CONTACT_LIST", STATUS_LOGGEDIN, &WorldSession::HandleFriendListOpcode },
+ /*0x067*/ { "SMSG_CONTACT_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x068*/ { "SMSG_FRIEND_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x069*/ { "CMSG_ADD_FRIEND", STATUS_LOGGEDIN, &WorldSession::HandleAddFriendOpcode },
+ /*0x06A*/ { "CMSG_DEL_FRIEND", STATUS_LOGGEDIN, &WorldSession::HandleDelFriendOpcode },
+ /*0x06B*/ { "CMSG_SET_CONTACT_NOTES", STATUS_LOGGEDIN, &WorldSession::HandleSetFriendNoteOpcode },
+ /*0x06C*/ { "CMSG_ADD_IGNORE", STATUS_LOGGEDIN, &WorldSession::HandleAddIgnoreOpcode },
+ /*0x06D*/ { "CMSG_DEL_IGNORE", STATUS_LOGGEDIN, &WorldSession::HandleDelIgnoreOpcode },
+ /*0x06E*/ { "CMSG_GROUP_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleGroupInviteOpcode },
+ /*0x06F*/ { "SMSG_GROUP_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x070*/ { "CMSG_GROUP_CANCEL", STATUS_LOGGEDIN, &WorldSession::Handle_Deprecated },
+ /*0x071*/ { "SMSG_GROUP_CANCEL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x072*/ { "CMSG_GROUP_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleGroupAcceptOpcode },
+ /*0x073*/ { "CMSG_GROUP_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandleGroupDeclineOpcode },
+ /*0x074*/ { "SMSG_GROUP_DECLINE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x075*/ { "CMSG_GROUP_UNINVITE", STATUS_LOGGEDIN, &WorldSession::HandleGroupUninviteNameOpcode },
+ /*0x076*/ { "CMSG_GROUP_UNINVITE_GUID", STATUS_LOGGEDIN, &WorldSession::HandleGroupUninviteGuidOpcode },
+ /*0x077*/ { "SMSG_GROUP_UNINVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x078*/ { "CMSG_GROUP_SET_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleGroupSetLeaderOpcode },
+ /*0x079*/ { "SMSG_GROUP_SET_LEADER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x07A*/ { "CMSG_LOOT_METHOD", STATUS_LOGGEDIN, &WorldSession::HandleLootMethodOpcode },
+ /*0x07B*/ { "CMSG_GROUP_DISBAND", STATUS_LOGGEDIN, &WorldSession::HandleGroupLeaveOpcode },
+ /*0x07C*/ { "SMSG_GROUP_DESTROYED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x07D*/ { "SMSG_GROUP_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x07E*/ { "SMSG_PARTY_MEMBER_STATS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x07F*/ { "SMSG_PARTY_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x080*/ { "UMSG_UPDATE_GROUP_MEMBERS", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x081*/ { "CMSG_GUILD_CREATE", STATUS_LOGGEDIN, &WorldSession::HandleGuildCreateOpcode },
+ /*0x082*/ { "CMSG_GUILD_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleGuildInviteOpcode },
+ /*0x083*/ { "SMSG_GUILD_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x084*/ { "CMSG_GUILD_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleGuildAcceptOpcode },
+ /*0x085*/ { "CMSG_GUILD_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandleGuildDeclineOpcode },
+ /*0x086*/ { "SMSG_GUILD_DECLINE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x087*/ { "CMSG_GUILD_INFO", STATUS_LOGGEDIN, &WorldSession::HandleGuildInfoOpcode },
+ /*0x088*/ { "SMSG_GUILD_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x089*/ { "CMSG_GUILD_ROSTER", STATUS_LOGGEDIN, &WorldSession::HandleGuildRosterOpcode },
+ /*0x08A*/ { "SMSG_GUILD_ROSTER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x08B*/ { "CMSG_GUILD_PROMOTE", STATUS_LOGGEDIN, &WorldSession::HandleGuildPromoteOpcode },
+ /*0x08C*/ { "CMSG_GUILD_DEMOTE", STATUS_LOGGEDIN, &WorldSession::HandleGuildDemoteOpcode },
+ /*0x08D*/ { "CMSG_GUILD_LEAVE", STATUS_LOGGEDIN, &WorldSession::HandleGuildLeaveOpcode },
+ /*0x08E*/ { "CMSG_GUILD_REMOVE", STATUS_LOGGEDIN, &WorldSession::HandleGuildRemoveOpcode },
+ /*0x08F*/ { "CMSG_GUILD_DISBAND", STATUS_LOGGEDIN, &WorldSession::HandleGuildDisbandOpcode },
+ /*0x090*/ { "CMSG_GUILD_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleGuildLeaderOpcode },
+ /*0x091*/ { "CMSG_GUILD_MOTD", STATUS_LOGGEDIN, &WorldSession::HandleGuildMOTDOpcode },
+ /*0x092*/ { "SMSG_GUILD_EVENT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x093*/ { "SMSG_GUILD_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x094*/ { "UMSG_UPDATE_GUILD", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x095*/ { "CMSG_MESSAGECHAT", STATUS_LOGGEDIN, &WorldSession::HandleMessagechatOpcode },
+ /*0x096*/ { "SMSG_MESSAGECHAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x097*/ { "CMSG_JOIN_CHANNEL", STATUS_LOGGEDIN, &WorldSession::HandleChannelJoin },
+ /*0x098*/ { "CMSG_LEAVE_CHANNEL", STATUS_LOGGEDIN, &WorldSession::HandleChannelLeave },
+ /*0x099*/ { "SMSG_CHANNEL_NOTIFY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x09A*/ { "CMSG_CHANNEL_LIST", STATUS_LOGGEDIN, &WorldSession::HandleChannelList },
+ /*0x09B*/ { "SMSG_CHANNEL_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x09C*/ { "CMSG_CHANNEL_PASSWORD", STATUS_LOGGEDIN, &WorldSession::HandleChannelPassword },
+ /*0x09D*/ { "CMSG_CHANNEL_SET_OWNER", STATUS_LOGGEDIN, &WorldSession::HandleChannelSetOwner },
+ /*0x09E*/ { "CMSG_CHANNEL_OWNER", STATUS_LOGGEDIN, &WorldSession::HandleChannelOwner },
+ /*0x09F*/ { "CMSG_CHANNEL_MODERATOR", STATUS_LOGGEDIN, &WorldSession::HandleChannelModerator },
+ /*0x0A0*/ { "CMSG_CHANNEL_UNMODERATOR", STATUS_LOGGEDIN, &WorldSession::HandleChannelUnmoderator },
+ /*0x0A1*/ { "CMSG_CHANNEL_MUTE", STATUS_LOGGEDIN, &WorldSession::HandleChannelMute },
+ /*0x0A2*/ { "CMSG_CHANNEL_UNMUTE", STATUS_LOGGEDIN, &WorldSession::HandleChannelUnmute },
+ /*0x0A3*/ { "CMSG_CHANNEL_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleChannelInvite },
+ /*0x0A4*/ { "CMSG_CHANNEL_KICK", STATUS_LOGGEDIN, &WorldSession::HandleChannelKick },
+ /*0x0A5*/ { "CMSG_CHANNEL_BAN", STATUS_LOGGEDIN, &WorldSession::HandleChannelBan },
+ /*0x0A6*/ { "CMSG_CHANNEL_UNBAN", STATUS_LOGGEDIN, &WorldSession::HandleChannelUnban },
+ /*0x0A7*/ { "CMSG_CHANNEL_ANNOUNCEMENTS", STATUS_LOGGEDIN, &WorldSession::HandleChannelAnnounce },
+ /*0x0A8*/ { "CMSG_CHANNEL_MODERATE", STATUS_LOGGEDIN, &WorldSession::HandleChannelModerate },
+ /*0x0A9*/ { "SMSG_UPDATE_OBJECT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0AA*/ { "SMSG_DESTROY_OBJECT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0AB*/ { "CMSG_USE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleUseItemOpcode },
+ /*0x0AC*/ { "CMSG_OPEN_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleOpenItemOpcode },
+ /*0x0AD*/ { "CMSG_READ_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleReadItem },
+ /*0x0AE*/ { "SMSG_READ_ITEM_OK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0AF*/ { "SMSG_READ_ITEM_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0B0*/ { "SMSG_ITEM_COOLDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0B1*/ { "CMSG_GAMEOBJ_USE", STATUS_LOGGEDIN, &WorldSession::HandleGameObjectUseOpcode },
+ /*0x0B2*/ { "CMSG_DESTROY_ITEMS", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0B3*/ { "SMSG_GAMEOBJECT_CUSTOM_ANIM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0B4*/ { "CMSG_AREATRIGGER", STATUS_LOGGEDIN, &WorldSession::HandleAreaTriggerOpcode },
+ /*0x0B5*/ { "MSG_MOVE_START_FORWARD", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0B6*/ { "MSG_MOVE_START_BACKWARD", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0B7*/ { "MSG_MOVE_STOP", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0B8*/ { "MSG_MOVE_START_STRAFE_LEFT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0B9*/ { "MSG_MOVE_START_STRAFE_RIGHT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0BA*/ { "MSG_MOVE_STOP_STRAFE", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0BB*/ { "MSG_MOVE_JUMP", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0BC*/ { "MSG_MOVE_START_TURN_LEFT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0BD*/ { "MSG_MOVE_START_TURN_RIGHT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0BE*/ { "MSG_MOVE_STOP_TURN", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0BF*/ { "MSG_MOVE_START_PITCH_UP", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0C0*/ { "MSG_MOVE_START_PITCH_DOWN", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0C1*/ { "MSG_MOVE_STOP_PITCH", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0C2*/ { "MSG_MOVE_SET_RUN_MODE", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0C3*/ { "MSG_MOVE_SET_WALK_MODE", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0C4*/ { "MSG_MOVE_TOGGLE_LOGGING", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0C5*/ { "MSG_MOVE_TELEPORT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0C6*/ { "MSG_MOVE_TELEPORT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0C7*/ { "MSG_MOVE_TELEPORT_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveTeleportAck },
+ /*0x0C8*/ { "MSG_MOVE_TOGGLE_FALL_LOGGING", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0C9*/ { "MSG_MOVE_FALL_LAND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0CA*/ { "MSG_MOVE_START_SWIM", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0CB*/ { "MSG_MOVE_STOP_SWIM", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0CC*/ { "MSG_MOVE_SET_RUN_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0CD*/ { "MSG_MOVE_SET_RUN_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0CE*/ { "MSG_MOVE_SET_RUN_BACK_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0CF*/ { "MSG_MOVE_SET_RUN_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0D0*/ { "MSG_MOVE_SET_WALK_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0D1*/ { "MSG_MOVE_SET_WALK_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0D2*/ { "MSG_MOVE_SET_SWIM_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0D3*/ { "MSG_MOVE_SET_SWIM_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0D4*/ { "MSG_MOVE_SET_SWIM_BACK_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0D5*/ { "MSG_MOVE_SET_SWIM_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0D6*/ { "MSG_MOVE_SET_ALL_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0D7*/ { "MSG_MOVE_SET_TURN_RATE_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0D8*/ { "MSG_MOVE_SET_TURN_RATE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0D9*/ { "MSG_MOVE_TOGGLE_COLLISION_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0DA*/ { "MSG_MOVE_SET_FACING", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0DB*/ { "MSG_MOVE_SET_PITCH", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0DC*/ { "MSG_MOVE_WORLDPORT_ACK", STATUS_TRANSFER_PENDING,&WorldSession::HandleMoveWorldportAckOpcode},
+ /*0x0DD*/ { "SMSG_MONSTER_MOVE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0DE*/ { "SMSG_MOVE_WATER_WALK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0DF*/ { "SMSG_MOVE_LAND_WALK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0E0*/ { "MSG_MOVE_SET_RAW_POSITION_ACK", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0E1*/ { "CMSG_MOVE_SET_RAW_POSITION", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0E2*/ { "SMSG_FORCE_RUN_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0E3*/ { "CMSG_FORCE_RUN_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck },
+ /*0x0E4*/ { "SMSG_FORCE_RUN_BACK_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0E5*/ { "CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck },
+ /*0x0E6*/ { "SMSG_FORCE_SWIM_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0E7*/ { "CMSG_FORCE_SWIM_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck },
+ /*0x0E8*/ { "SMSG_FORCE_MOVE_ROOT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0E9*/ { "CMSG_FORCE_MOVE_ROOT_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveRootAck },
+ /*0x0EA*/ { "SMSG_FORCE_MOVE_UNROOT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0EB*/ { "CMSG_FORCE_MOVE_UNROOT_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveUnRootAck },
+ /*0x0EC*/ { "MSG_MOVE_ROOT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0ED*/ { "MSG_MOVE_UNROOT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0EE*/ { "MSG_MOVE_HEARTBEAT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x0EF*/ { "SMSG_MOVE_KNOCK_BACK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0F0*/ { "CMSG_MOVE_KNOCK_BACK_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveKnockBackAck },
+ /*0x0F1*/ { "MSG_MOVE_KNOCK_BACK", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0F2*/ { "SMSG_MOVE_FEATHER_FALL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0F3*/ { "SMSG_MOVE_NORMAL_FALL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0F4*/ { "SMSG_MOVE_SET_HOVER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0F5*/ { "SMSG_MOVE_UNSET_HOVER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0F6*/ { "CMSG_MOVE_HOVER_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveHoverAck },
+ /*0x0F7*/ { "MSG_MOVE_HOVER", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0F8*/ { "CMSG_TRIGGER_CINEMATIC_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0F9*/ { "CMSG_OPENING_CINEMATIC", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x0FA*/ { "SMSG_TRIGGER_CINEMATIC", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0FB*/ { "CMSG_NEXT_CINEMATIC_CAMERA", STATUS_LOGGEDIN, &WorldSession::HandleNextCinematicCamera },
+ /*0x0FC*/ { "CMSG_COMPLETE_CINEMATIC", STATUS_LOGGEDIN, &WorldSession::HandleCompleteCinema },
+ /*0x0FD*/ { "SMSG_TUTORIAL_FLAGS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x0FE*/ { "CMSG_TUTORIAL_FLAG", STATUS_LOGGEDIN, &WorldSession::HandleTutorialFlag },
+ /*0x0FF*/ { "CMSG_TUTORIAL_CLEAR", STATUS_LOGGEDIN, &WorldSession::HandleTutorialClear },
+ /*0x100*/ { "CMSG_TUTORIAL_RESET", STATUS_LOGGEDIN, &WorldSession::HandleTutorialReset },
+ /*0x101*/ { "CMSG_STANDSTATECHANGE", STATUS_LOGGEDIN, &WorldSession::HandleStandStateChangeOpcode },
+ /*0x102*/ { "CMSG_EMOTE", STATUS_LOGGEDIN, &WorldSession::HandleEmoteOpcode },
+ /*0x103*/ { "SMSG_EMOTE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x104*/ { "CMSG_TEXT_EMOTE", STATUS_LOGGEDIN, &WorldSession::HandleTextEmoteOpcode },
+ /*0x105*/ { "SMSG_TEXT_EMOTE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x106*/ { "CMSG_AUTOEQUIP_GROUND_ITEM", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x107*/ { "CMSG_AUTOSTORE_GROUND_ITEM", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x108*/ { "CMSG_AUTOSTORE_LOOT_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutostoreLootItemOpcode },
+ /*0x109*/ { "CMSG_STORE_LOOT_IN_SLOT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x10A*/ { "CMSG_AUTOEQUIP_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoEquipItemOpcode },
+ /*0x10B*/ { "CMSG_AUTOSTORE_BAG_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoStoreBagItemOpcode },
+ /*0x10C*/ { "CMSG_SWAP_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSwapItem },
+ /*0x10D*/ { "CMSG_SWAP_INV_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSwapInvItemOpcode },
+ /*0x10E*/ { "CMSG_SPLIT_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSplitItemOpcode },
+ /*0x10F*/ { "CMSG_AUTOEQUIP_ITEM_SLOT", STATUS_LOGGEDIN, &WorldSession::HandleAutoEquipItemSlotOpcode },
+ /*0x110*/ { "OBSOLETE_DROP_ITEM", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x111*/ { "CMSG_DESTROYITEM", STATUS_LOGGEDIN, &WorldSession::HandleDestroyItemOpcode },
+ /*0x112*/ { "SMSG_INVENTORY_CHANGE_FAILURE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x113*/ { "SMSG_OPEN_CONTAINER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x114*/ { "CMSG_INSPECT", STATUS_LOGGEDIN, &WorldSession::HandleInspectOpcode },
+ /*0x115*/ { "SMSG_INSPECT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x116*/ { "CMSG_INITIATE_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleInitiateTradeOpcode },
+ /*0x117*/ { "CMSG_BEGIN_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleBeginTradeOpcode },
+ /*0x118*/ { "CMSG_BUSY_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleBusyTradeOpcode },
+ /*0x119*/ { "CMSG_IGNORE_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleIgnoreTradeOpcode },
+ /*0x11A*/ { "CMSG_ACCEPT_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleAcceptTradeOpcode },
+ /*0x11B*/ { "CMSG_UNACCEPT_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleUnacceptTradeOpcode },
+ /*0x11C*/ { "CMSG_CANCEL_TRADE", STATUS_AUTHED, &WorldSession::HandleCancelTradeOpcode },
+ /*0x11D*/ { "CMSG_SET_TRADE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSetTradeItemOpcode },
+ /*0x11E*/ { "CMSG_CLEAR_TRADE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleClearTradeItemOpcode },
+ /*0x11F*/ { "CMSG_SET_TRADE_GOLD", STATUS_LOGGEDIN, &WorldSession::HandleSetTradeGoldOpcode },
+ /*0x120*/ { "SMSG_TRADE_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x121*/ { "SMSG_TRADE_STATUS_EXTENDED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x122*/ { "SMSG_INITIALIZE_FACTIONS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x123*/ { "SMSG_SET_FACTION_VISIBLE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x124*/ { "SMSG_SET_FACTION_STANDING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x125*/ { "CMSG_SET_FACTION_ATWAR", STATUS_LOGGEDIN, &WorldSession::HandleSetFactionAtWar },
+ /*0x126*/ { "CMSG_SET_FACTION_CHEAT", STATUS_LOGGEDIN, &WorldSession::HandleSetFactionCheat },
+ /*0x127*/ { "SMSG_SET_PROFICIENCY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x128*/ { "CMSG_SET_ACTION_BUTTON", STATUS_LOGGEDIN, &WorldSession::HandleSetActionButtonOpcode },
+ /*0x129*/ { "SMSG_ACTION_BUTTONS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x12A*/ { "SMSG_INITIAL_SPELLS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x12B*/ { "SMSG_LEARNED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x12C*/ { "SMSG_SUPERCEDED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x12D*/ { "CMSG_NEW_SPELL_SLOT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x12E*/ { "CMSG_CAST_SPELL", STATUS_LOGGEDIN, &WorldSession::HandleCastSpellOpcode },
+ /*0x12F*/ { "CMSG_CANCEL_CAST", STATUS_LOGGEDIN, &WorldSession::HandleCancelCastOpcode },
+ /*0x130*/ { "SMSG_CAST_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x131*/ { "SMSG_SPELL_START", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x132*/ { "SMSG_SPELL_GO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x133*/ { "SMSG_SPELL_FAILURE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x134*/ { "SMSG_SPELL_COOLDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x135*/ { "SMSG_COOLDOWN_EVENT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x136*/ { "CMSG_CANCEL_AURA", STATUS_LOGGEDIN, &WorldSession::HandleCancelAuraOpcode },
+ /*0x137*/ { "SMSG_UPDATE_AURA_DURATION_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x138*/ { "SMSG_PET_CAST_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x139*/ { "MSG_CHANNEL_START", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x13A*/ { "MSG_CHANNEL_UPDATE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x13B*/ { "CMSG_CANCEL_CHANNELLING", STATUS_LOGGEDIN, &WorldSession::HandleCancelChanneling },
+ /*0x13C*/ { "SMSG_AI_REACTION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x13D*/ { "CMSG_SET_SELECTION", STATUS_LOGGEDIN, &WorldSession::HandleSetSelectionOpcode },
+ /*0x13E*/ { "CMSG_SET_TARGET_OBSOLETE", STATUS_LOGGEDIN, &WorldSession::HandleSetTargetOpcode },
+ /*0x13F*/ { "CMSG_UNUSED", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x140*/ { "CMSG_UNUSED2", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x141*/ { "CMSG_ATTACKSWING", STATUS_LOGGEDIN, &WorldSession::HandleAttackSwingOpcode },
+ /*0x142*/ { "CMSG_ATTACKSTOP", STATUS_LOGGEDIN, &WorldSession::HandleAttackStopOpcode },
+ /*0x143*/ { "SMSG_ATTACKSTART", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x144*/ { "SMSG_ATTACKSTOP", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x145*/ { "SMSG_ATTACKSWING_NOTINRANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x146*/ { "SMSG_ATTACKSWING_BADFACING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x147*/ { "SMSG_ATTACKSWING_NOTSTANDING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x148*/ { "SMSG_ATTACKSWING_DEADTARGET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x149*/ { "SMSG_ATTACKSWING_CANT_ATTACK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x14A*/ { "SMSG_ATTACKERSTATEUPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x14B*/ { "SMSG_VICTIMSTATEUPDATE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x14C*/ { "SMSG_DAMAGE_DONE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x14D*/ { "SMSG_DAMAGE_TAKEN_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x14E*/ { "SMSG_CANCEL_COMBAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x14F*/ { "SMSG_SPELLBREAKLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x150*/ { "SMSG_SPELLHEALLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x151*/ { "SMSG_SPELLENERGIZELOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x152*/ { "SMSG_BREAK_TARGET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x153*/ { "CMSG_SAVE_PLAYER", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x154*/ { "CMSG_SETDEATHBINDPOINT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x155*/ { "SMSG_BINDPOINTUPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x156*/ { "CMSG_GETDEATHBINDZONE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x157*/ { "SMSG_BINDZONEREPLY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x158*/ { "SMSG_PLAYERBOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x159*/ { "SMSG_CLIENT_CONTROL_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x15A*/ { "CMSG_REPOP_REQUEST", STATUS_LOGGEDIN, &WorldSession::HandleRepopRequestOpcode },
+ /*0x15B*/ { "SMSG_RESURRECT_REQUEST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x15C*/ { "CMSG_RESURRECT_RESPONSE", STATUS_LOGGEDIN, &WorldSession::HandleResurrectResponseOpcode },
+ /*0x15D*/ { "CMSG_LOOT", STATUS_LOGGEDIN, &WorldSession::HandleLootOpcode },
+ /*0x15E*/ { "CMSG_LOOT_MONEY", STATUS_LOGGEDIN, &WorldSession::HandleLootMoneyOpcode },
+ /*0x15F*/ { "CMSG_LOOT_RELEASE", STATUS_LOGGEDIN, &WorldSession::HandleLootReleaseOpcode },
+ /*0x160*/ { "SMSG_LOOT_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x161*/ { "SMSG_LOOT_RELEASE_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x162*/ { "SMSG_LOOT_REMOVED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x163*/ { "SMSG_LOOT_MONEY_NOTIFY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x164*/ { "SMSG_LOOT_ITEM_NOTIFY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x165*/ { "SMSG_LOOT_CLEAR_MONEY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x166*/ { "SMSG_ITEM_PUSH_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x167*/ { "SMSG_DUEL_REQUESTED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x168*/ { "SMSG_DUEL_OUTOFBOUNDS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x169*/ { "SMSG_DUEL_INBOUNDS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x16A*/ { "SMSG_DUEL_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x16B*/ { "SMSG_DUEL_WINNER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x16C*/ { "CMSG_DUEL_ACCEPTED", STATUS_LOGGEDIN, &WorldSession::HandleDuelAcceptedOpcode },
+ /*0x16D*/ { "CMSG_DUEL_CANCELLED", STATUS_LOGGEDIN, &WorldSession::HandleDuelCancelledOpcode },
+ /*0x16E*/ { "SMSG_MOUNTRESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x16F*/ { "SMSG_DISMOUNTRESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x170*/ { "SMSG_PUREMOUNT_CANCELLED_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x171*/ { "CMSG_MOUNTSPECIAL_ANIM", STATUS_LOGGEDIN, &WorldSession::HandleMountSpecialAnimOpcode },
+ /*0x172*/ { "SMSG_MOUNTSPECIAL_ANIM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x173*/ { "SMSG_PET_TAME_FAILURE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x174*/ { "CMSG_PET_SET_ACTION", STATUS_LOGGEDIN, &WorldSession::HandlePetSetAction },
+ /*0x175*/ { "CMSG_PET_ACTION", STATUS_LOGGEDIN, &WorldSession::HandlePetAction },
+ /*0x176*/ { "CMSG_PET_ABANDON", STATUS_LOGGEDIN, &WorldSession::HandlePetAbandon },
+ /*0x177*/ { "CMSG_PET_RENAME", STATUS_LOGGEDIN, &WorldSession::HandlePetRename },
+ /*0x178*/ { "SMSG_PET_NAME_INVALID", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x179*/ { "SMSG_PET_SPELLS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x17A*/ { "SMSG_PET_MODE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x17B*/ { "CMSG_GOSSIP_HELLO", STATUS_LOGGEDIN, &WorldSession::HandleGossipHelloOpcode },
+ /*0x17C*/ { "CMSG_GOSSIP_SELECT_OPTION", STATUS_LOGGEDIN, &WorldSession::HandleGossipSelectOptionOpcode },
+ /*0x17D*/ { "SMSG_GOSSIP_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x17E*/ { "SMSG_GOSSIP_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x17F*/ { "CMSG_NPC_TEXT_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleNpcTextQueryOpcode },
+ /*0x180*/ { "SMSG_NPC_TEXT_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x181*/ { "SMSG_NPC_WONT_TALK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x182*/ { "CMSG_QUESTGIVER_STATUS_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverStatusQueryOpcode},
+ /*0x183*/ { "SMSG_QUESTGIVER_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x184*/ { "CMSG_QUESTGIVER_HELLO", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverHelloOpcode },
+ /*0x185*/ { "SMSG_QUESTGIVER_QUEST_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x186*/ { "CMSG_QUESTGIVER_QUERY_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverQuestQueryOpcode},
+ /*0x187*/ { "CMSG_QUESTGIVER_QUEST_AUTOLAUNCH", STATUS_LOGGEDIN, &WorldSession::HandleQuestAutoLaunch },
+ /*0x188*/ { "SMSG_QUESTGIVER_QUEST_DETAILS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x189*/ { "CMSG_QUESTGIVER_ACCEPT_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverAcceptQuestOpcode},
+ /*0x18A*/ { "CMSG_QUESTGIVER_COMPLETE_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestComplete },
+ /*0x18B*/ { "SMSG_QUESTGIVER_REQUEST_ITEMS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x18C*/ { "CMSG_QUESTGIVER_REQUEST_REWARD", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverRequestRewardOpcode},
+ /*0x18D*/ { "SMSG_QUESTGIVER_OFFER_REWARD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x18E*/ { "CMSG_QUESTGIVER_CHOOSE_REWARD", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverChooseRewardOpcode},
+ /*0x18F*/ { "SMSG_QUESTGIVER_QUEST_INVALID", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x190*/ { "CMSG_QUESTGIVER_CANCEL", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverCancel },
+ /*0x191*/ { "SMSG_QUESTGIVER_QUEST_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x192*/ { "SMSG_QUESTGIVER_QUEST_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x193*/ { "CMSG_QUESTLOG_SWAP_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestLogSwapQuest },
+ /*0x194*/ { "CMSG_QUESTLOG_REMOVE_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestLogRemoveQuest },
+ /*0x195*/ { "SMSG_QUESTLOG_FULL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x196*/ { "SMSG_QUESTUPDATE_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x197*/ { "SMSG_QUESTUPDATE_FAILEDTIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x198*/ { "SMSG_QUESTUPDATE_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x199*/ { "SMSG_QUESTUPDATE_ADD_KILL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x19A*/ { "SMSG_QUESTUPDATE_ADD_ITEM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x19B*/ { "CMSG_QUEST_CONFIRM_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleQuestConfirmAccept },
+ /*0x19C*/ { "SMSG_QUEST_CONFIRM_ACCEPT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x19D*/ { "CMSG_PUSHQUESTTOPARTY", STATUS_LOGGEDIN, &WorldSession::HandleQuestPushToParty },
+ /*0x19E*/ { "CMSG_LIST_INVENTORY", STATUS_LOGGEDIN, &WorldSession::HandleListInventoryOpcode },
+ /*0x19F*/ { "SMSG_LIST_INVENTORY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1A0*/ { "CMSG_SELL_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSellItemOpcode },
+ /*0x1A1*/ { "SMSG_SELL_ITEM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1A2*/ { "CMSG_BUY_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleBuyItemOpcode },
+ /*0x1A3*/ { "CMSG_BUY_ITEM_IN_SLOT", STATUS_LOGGEDIN, &WorldSession::HandleBuyItemInSlotOpcode },
+ /*0x1A4*/ { "SMSG_BUY_ITEM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1A5*/ { "SMSG_BUY_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1A6*/ { "CMSG_TAXICLEARALLNODES", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x1A7*/ { "CMSG_TAXIENABLEALLNODES", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x1A8*/ { "CMSG_TAXISHOWNODES", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x1A9*/ { "SMSG_SHOWTAXINODES", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1AA*/ { "CMSG_TAXINODE_STATUS_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleTaxiNodeStatusQueryOpcode },
+ /*0x1AB*/ { "SMSG_TAXINODE_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1AC*/ { "CMSG_TAXIQUERYAVAILABLENODES", STATUS_LOGGEDIN, &WorldSession::HandleTaxiQueryAvailableNodes },
+ /*0x1AD*/ { "CMSG_ACTIVATETAXI", STATUS_LOGGEDIN, &WorldSession::HandleActivateTaxiOpcode },
+ /*0x1AE*/ { "SMSG_ACTIVATETAXIREPLY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1AF*/ { "SMSG_NEW_TAXI_PATH", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1B0*/ { "CMSG_TRAINER_LIST", STATUS_LOGGEDIN, &WorldSession::HandleTrainerListOpcode },
+ /*0x1B1*/ { "SMSG_TRAINER_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1B2*/ { "CMSG_TRAINER_BUY_SPELL", STATUS_LOGGEDIN, &WorldSession::HandleTrainerBuySpellOpcode },
+ /*0x1B3*/ { "SMSG_TRAINER_BUY_SUCCEEDED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1B4*/ { "SMSG_TRAINER_BUY_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1B5*/ { "CMSG_BINDER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleBinderActivateOpcode },
+ /*0x1B6*/ { "SMSG_PLAYERBINDERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1B7*/ { "CMSG_BANKER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleBankerActivateOpcode },
+ /*0x1B8*/ { "SMSG_SHOW_BANK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1B9*/ { "CMSG_BUY_BANK_SLOT", STATUS_LOGGEDIN, &WorldSession::HandleBuyBankSlotOpcode },
+ /*0x1BA*/ { "SMSG_BUY_BANK_SLOT_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1BB*/ { "CMSG_PETITION_SHOWLIST", STATUS_LOGGEDIN, &WorldSession::HandlePetitionShowListOpcode },
+ /*0x1BC*/ { "SMSG_PETITION_SHOWLIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1BD*/ { "CMSG_PETITION_BUY", STATUS_LOGGEDIN, &WorldSession::HandlePetitionBuyOpcode },
+ /*0x1BE*/ { "CMSG_PETITION_SHOW_SIGNATURES", STATUS_LOGGEDIN, &WorldSession::HandlePetitionShowSignOpcode },
+ /*0x1BF*/ { "SMSG_PETITION_SHOW_SIGNATURES", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1C0*/ { "CMSG_PETITION_SIGN", STATUS_LOGGEDIN, &WorldSession::HandlePetitionSignOpcode },
+ /*0x1C1*/ { "SMSG_PETITION_SIGN_RESULTS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1C2*/ { "MSG_PETITION_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandlePetitionDeclineOpcode },
+ /*0x1C3*/ { "CMSG_OFFER_PETITION", STATUS_LOGGEDIN, &WorldSession::HandleOfferPetitionOpcode },
+ /*0x1C4*/ { "CMSG_TURN_IN_PETITION", STATUS_LOGGEDIN, &WorldSession::HandleTurnInPetitionOpcode },
+ /*0x1C5*/ { "SMSG_TURN_IN_PETITION_RESULTS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1C6*/ { "CMSG_PETITION_QUERY", STATUS_LOGGEDIN, &WorldSession::HandlePetitionQueryOpcode },
+ /*0x1C7*/ { "SMSG_PETITION_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1C8*/ { "SMSG_FISH_NOT_HOOKED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1C9*/ { "SMSG_FISH_ESCAPED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1CA*/ { "CMSG_BUG", STATUS_LOGGEDIN, &WorldSession::HandleBugOpcode },
+ /*0x1CB*/ { "SMSG_NOTIFICATION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1CC*/ { "CMSG_PLAYED_TIME", STATUS_LOGGEDIN, &WorldSession::HandlePlayedTime },
+ /*0x1CD*/ { "SMSG_PLAYED_TIME", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1CE*/ { "CMSG_QUERY_TIME", STATUS_LOGGEDIN, &WorldSession::HandleQueryTimeOpcode },
+ /*0x1CF*/ { "SMSG_QUERY_TIME_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1D0*/ { "SMSG_LOG_XPGAIN", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1D1*/ { "SMSG_AURACASTLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1D2*/ { "CMSG_RECLAIM_CORPSE", STATUS_LOGGEDIN, &WorldSession::HandleCorpseReclaimOpcode },
+ /*0x1D3*/ { "CMSG_WRAP_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleWrapItemOpcode },
+ /*0x1D4*/ { "SMSG_LEVELUP_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1D5*/ { "MSG_MINIMAP_PING", STATUS_LOGGEDIN, &WorldSession::HandleMinimapPingOpcode },
+ /*0x1D6*/ { "SMSG_RESISTLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1D7*/ { "SMSG_ENCHANTMENTLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1D8*/ { "CMSG_SET_SKILL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x1D9*/ { "SMSG_START_MIRROR_TIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1DA*/ { "SMSG_PAUSE_MIRROR_TIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1DB*/ { "SMSG_STOP_MIRROR_TIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1DC*/ { "CMSG_PING", STATUS_NEVER, &WorldSession::Handle_EarlyProccess },
+ /*0x1DD*/ { "SMSG_PONG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1DE*/ { "SMSG_CLEAR_COOLDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1DF*/ { "SMSG_GAMEOBJECT_PAGETEXT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1E0*/ { "CMSG_SETSHEATHED", STATUS_LOGGEDIN, &WorldSession::HandleSetSheathedOpcode },
+ /*0x1E1*/ { "SMSG_COOLDOWN_CHEAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1E2*/ { "SMSG_SPELL_DELAYED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1E3*/ { "CMSG_PLAYER_MACRO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x1E4*/ { "SMSG_PLAYER_MACRO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1E5*/ { "CMSG_GHOST", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x1E6*/ { "CMSG_GM_INVIS", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x1E7*/ { "SMSG_INVALID_PROMOTION_CODE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1E8*/ { "MSG_GM_BIND_OTHER", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x1E9*/ { "MSG_GM_SUMMON", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x1EA*/ { "SMSG_ITEM_TIME_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1EB*/ { "SMSG_ITEM_ENCHANT_TIME_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1EC*/ { "SMSG_AUTH_CHALLENGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1ED*/ { "CMSG_AUTH_SESSION", STATUS_NEVER, &WorldSession::Handle_EarlyProccess },
+ /*0x1EE*/ { "SMSG_AUTH_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1EF*/ { "MSG_GM_SHOWLABEL", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x1F0*/ { "CMSG_PET_CAST_SPELL", STATUS_LOGGEDIN, &WorldSession::HandlePetCastSpellOpcode },
+ /*0x1F1*/ { "MSG_SAVE_GUILD_EMBLEM", STATUS_LOGGEDIN, &WorldSession::HandleGuildSaveEmblemOpcode },
+ /*0x1F2*/ { "MSG_TABARDVENDOR_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleTabardVendorActivateOpcode},
+ /*0x1F3*/ { "SMSG_PLAY_SPELL_VISUAL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1F4*/ { "CMSG_ZONEUPDATE", STATUS_LOGGEDIN, &WorldSession::HandleZoneUpdateOpcode },
+ /*0x1F5*/ { "SMSG_PARTYKILLLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1F6*/ { "SMSG_COMPRESSED_UPDATE_OBJECT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1F7*/ { "SMSG_PLAY_SPELL_IMPACT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1F8*/ { "SMSG_EXPLORATION_EXPERIENCE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1F9*/ { "CMSG_GM_SET_SECURITY_GROUP", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x1FA*/ { "CMSG_GM_NUKE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x1FB*/ { "MSG_RANDOM_ROLL", STATUS_LOGGEDIN, &WorldSession::HandleRandomRollOpcode },
+ /*0x1FC*/ { "SMSG_ENVIRONMENTALDAMAGELOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1FD*/ { "CMSG_RWHOIS_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x1FE*/ { "SMSG_RWHOIS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1FF*/ { "MSG_LOOKING_FOR_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleLookingForGroup },
+ /*0x200*/ { "CMSG_SET_LOOKING_FOR_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleSetLfgOpcode },
+ /*0x201*/ { "CMSG_UNLEARN_SPELL", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x202*/ { "CMSG_UNLEARN_SKILL", STATUS_LOGGEDIN, &WorldSession::HandleUnlearnSkillOpcode },
+ /*0x203*/ { "SMSG_REMOVED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x204*/ { "CMSG_DECHARGE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x205*/ { "CMSG_GMTICKET_CREATE", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketCreateOpcode },
+ /*0x206*/ { "SMSG_GMTICKET_CREATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x207*/ { "CMSG_GMTICKET_UPDATETEXT", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketUpdateOpcode },
- /*0x208*/ { "SMSG_GMTICKET_UPDATETEXT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x209*/ { "SMSG_ACCOUNT_DATA_TIMES", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x20A*/ { "CMSG_REQUEST_ACCOUNT_DATA", STATUS_LOGGEDIN, &WorldSession::HandleRequestAccountData },
- /*0x20B*/ { "CMSG_UPDATE_ACCOUNT_DATA", STATUS_LOGGEDIN, &WorldSession::HandleUpdateAccountData },
- /*0x20C*/ { "SMSG_UPDATE_ACCOUNT_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x20D*/ { "SMSG_CLEAR_FAR_SIGHT_IMMEDIATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x20E*/ { "SMSG_POWERGAINLOG_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x20F*/ { "CMSG_GM_TEACH", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x210*/ { "CMSG_GM_CREATE_ITEM_TARGET", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x211*/ { "CMSG_GMTICKET_GETTICKET", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketGetTicketOpcode },
- /*0x212*/ { "SMSG_GMTICKET_GETTICKET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x213*/ { "CMSG_UNLEARN_TALENTS", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x214*/ { "SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE",STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x215*/ { "SMSG_GAMEOBJECT_DESPAWN_ANIM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x216*/ { "MSG_CORPSE_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleCorpseQueryOpcode },
- /*0x217*/ { "CMSG_GMTICKET_DELETETICKET", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketDeleteOpcode },
- /*0x218*/ { "SMSG_GMTICKET_DELETETICKET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x219*/ { "SMSG_CHAT_WRONG_FACTION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x21A*/ { "CMSG_GMTICKET_SYSTEMSTATUS", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketSystemStatusOpcode},
- /*0x21B*/ { "SMSG_GMTICKET_SYSTEMSTATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x21C*/ { "CMSG_SPIRIT_HEALER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleSpiritHealerActivateOpcode},
- /*0x21D*/ { "CMSG_SET_STAT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x21E*/ { "SMSG_SET_REST_START", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x21F*/ { "CMSG_SKILL_BUY_STEP", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x220*/ { "CMSG_SKILL_BUY_RANK", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x221*/ { "CMSG_XP_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x222*/ { "SMSG_SPIRIT_HEALER_CONFIRM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x223*/ { "CMSG_CHARACTER_POINT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x224*/ { "SMSG_GOSSIP_POI", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x225*/ { "CMSG_CHAT_IGNORED", STATUS_LOGGEDIN, &WorldSession::HandleChatIgnoredOpcode },
- /*0x226*/ { "CMSG_GM_VISION", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x227*/ { "CMSG_SERVER_COMMAND", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x228*/ { "CMSG_GM_SILENCE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x229*/ { "CMSG_GM_REVEALTO", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x22A*/ { "CMSG_GM_RESURRECT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x22B*/ { "CMSG_GM_SUMMONMOB", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x22C*/ { "CMSG_GM_MOVECORPSE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x22D*/ { "CMSG_GM_FREEZE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x22E*/ { "CMSG_GM_UBERINVIS", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x22F*/ { "CMSG_GM_REQUEST_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x230*/ { "SMSG_GM_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x231*/ { "CMSG_GUILD_RANK", STATUS_LOGGEDIN, &WorldSession::HandleGuildRankOpcode },
- /*0x232*/ { "CMSG_GUILD_ADD_RANK", STATUS_LOGGEDIN, &WorldSession::HandleGuildAddRankOpcode },
- /*0x233*/ { "CMSG_GUILD_DEL_RANK", STATUS_LOGGEDIN, &WorldSession::HandleGuildDelRankOpcode },
- /*0x234*/ { "CMSG_GUILD_SET_PUBLIC_NOTE", STATUS_LOGGEDIN, &WorldSession::HandleGuildSetPublicNoteOpcode },
- /*0x235*/ { "CMSG_GUILD_SET_OFFICER_NOTE", STATUS_LOGGEDIN, &WorldSession::HandleGuildSetOfficerNoteOpcode },
- /*0x236*/ { "SMSG_LOGIN_VERIFY_WORLD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x237*/ { "CMSG_CLEAR_EXPLORATION", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x238*/ { "CMSG_SEND_MAIL", STATUS_LOGGEDIN, &WorldSession::HandleSendMail },
- /*0x239*/ { "SMSG_SEND_MAIL_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x23A*/ { "CMSG_GET_MAIL_LIST", STATUS_LOGGEDIN, &WorldSession::HandleGetMail },
- /*0x23B*/ { "SMSG_MAIL_LIST_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x23C*/ { "CMSG_BATTLEFIELD_LIST", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundListOpcode },
- /*0x23D*/ { "SMSG_BATTLEFIELD_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x23E*/ { "CMSG_BATTLEFIELD_JOIN", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x23F*/ { "SMSG_BATTLEFIELD_WIN_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x240*/ { "SMSG_BATTLEFIELD_LOSE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x241*/ { "CMSG_TAXICLEARNODE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x242*/ { "CMSG_TAXIENABLENODE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x243*/ { "CMSG_ITEM_TEXT_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleItemTextQuery },
- /*0x244*/ { "SMSG_ITEM_TEXT_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x245*/ { "CMSG_MAIL_TAKE_MONEY", STATUS_LOGGEDIN, &WorldSession::HandleTakeMoney },
- /*0x246*/ { "CMSG_MAIL_TAKE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleTakeItem },
- /*0x247*/ { "CMSG_MAIL_MARK_AS_READ", STATUS_LOGGEDIN, &WorldSession::HandleMarkAsRead },
- /*0x248*/ { "CMSG_MAIL_RETURN_TO_SENDER", STATUS_LOGGEDIN, &WorldSession::HandleReturnToSender },
- /*0x249*/ { "CMSG_MAIL_DELETE", STATUS_LOGGEDIN, &WorldSession::HandleMailDelete },
- /*0x24A*/ { "CMSG_MAIL_CREATE_TEXT_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleMailCreateTextItem },
- /*0x24B*/ { "SMSG_SPELLLOGMISS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x24C*/ { "SMSG_SPELLLOGEXECUTE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x24D*/ { "SMSG_DEBUGAURAPROC", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x24E*/ { "SMSG_PERIODICAURALOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x24F*/ { "SMSG_SPELLDAMAGESHIELD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x250*/ { "SMSG_SPELLNONMELEEDAMAGELOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x251*/ { "CMSG_LEARN_TALENT", STATUS_LOGGEDIN, &WorldSession::HandleLearnTalentOpcode },
- /*0x252*/ { "SMSG_RESURRECT_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x253*/ { "CMSG_TOGGLE_PVP", STATUS_LOGGEDIN, &WorldSession::HandleTogglePvP },
- /*0x254*/ { "SMSG_ZONE_UNDER_ATTACK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x255*/ { "MSG_AUCTION_HELLO", STATUS_LOGGEDIN, &WorldSession::HandleAuctionHelloOpcode },
- /*0x256*/ { "CMSG_AUCTION_SELL_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAuctionSellItem },
- /*0x257*/ { "CMSG_AUCTION_REMOVE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAuctionRemoveItem },
- /*0x258*/ { "CMSG_AUCTION_LIST_ITEMS", STATUS_LOGGEDIN, &WorldSession::HandleAuctionListItems },
- /*0x259*/ { "CMSG_AUCTION_LIST_OWNER_ITEMS", STATUS_LOGGEDIN, &WorldSession::HandleAuctionListOwnerItems },
- /*0x25A*/ { "CMSG_AUCTION_PLACE_BID", STATUS_LOGGEDIN, &WorldSession::HandleAuctionPlaceBid },
- /*0x25B*/ { "SMSG_AUCTION_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x25C*/ { "SMSG_AUCTION_LIST_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x25D*/ { "SMSG_AUCTION_OWNER_LIST_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x25E*/ { "SMSG_AUCTION_BIDDER_NOTIFICATION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x25F*/ { "SMSG_AUCTION_OWNER_NOTIFICATION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x260*/ { "SMSG_PROCRESIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x261*/ { "SMSG_STANDSTATE_CHANGE_FAILURE_OBSOLETE",STATUS_NEVER,&WorldSession::Handle_ServerSide },
- /*0x262*/ { "SMSG_DISPEL_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x263*/ { "SMSG_SPELLORDAMAGE_IMMUNE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x264*/ { "CMSG_AUCTION_LIST_BIDDER_ITEMS", STATUS_LOGGEDIN, &WorldSession::HandleAuctionListBidderItems },
- /*0x265*/ { "SMSG_AUCTION_BIDDER_LIST_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x266*/ { "SMSG_SET_FLAT_SPELL_MODIFIER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x267*/ { "SMSG_SET_PCT_SPELL_MODIFIER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x268*/ { "CMSG_SET_AMMO", STATUS_LOGGEDIN, &WorldSession::HandleSetAmmoOpcode },
- /*0x269*/ { "SMSG_CORPSE_RECLAIM_DELAY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x26A*/ { "CMSG_SET_ACTIVE_MOVER", STATUS_LOGGEDIN, &WorldSession::HandleSetActiveMoverOpcode },
- /*0x26B*/ { "CMSG_PET_CANCEL_AURA", STATUS_LOGGEDIN, &WorldSession::HandlePetCancelAuraOpcode },
- /*0x26C*/ { "CMSG_PLAYER_AI_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x26D*/ { "CMSG_CANCEL_AUTO_REPEAT_SPELL", STATUS_LOGGEDIN, &WorldSession::HandleCancelAutoRepeatSpellOpcode},
- /*0x26E*/ { "MSG_GM_ACCOUNT_ONLINE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x26F*/ { "MSG_LIST_STABLED_PETS", STATUS_LOGGEDIN, &WorldSession::HandleListStabledPetsOpcode },
- /*0x270*/ { "CMSG_STABLE_PET", STATUS_LOGGEDIN, &WorldSession::HandleStablePet },
- /*0x271*/ { "CMSG_UNSTABLE_PET", STATUS_LOGGEDIN, &WorldSession::HandleUnstablePet },
- /*0x272*/ { "CMSG_BUY_STABLE_SLOT", STATUS_LOGGEDIN, &WorldSession::HandleBuyStableSlot },
- /*0x273*/ { "SMSG_STABLE_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x274*/ { "CMSG_STABLE_REVIVE_PET", STATUS_LOGGEDIN, &WorldSession::HandleStableRevivePet },
- /*0x275*/ { "CMSG_STABLE_SWAP_PET", STATUS_LOGGEDIN, &WorldSession::HandleStableSwapPet },
- /*0x276*/ { "MSG_QUEST_PUSH_RESULT", STATUS_LOGGEDIN, &WorldSession::HandleQuestPushResult },
- /*0x277*/ { "SMSG_PLAY_MUSIC", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x278*/ { "SMSG_PLAY_OBJECT_SOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x279*/ { "CMSG_REQUEST_PET_INFO", STATUS_LOGGEDIN, &WorldSession::HandleRequestPetInfoOpcode },
- /*0x27A*/ { "CMSG_FAR_SIGHT", STATUS_LOGGEDIN, &WorldSession::HandleFarSightOpcode },
- /*0x27B*/ { "SMSG_SPELLDISPELLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x27C*/ { "SMSG_DAMAGE_CALC_LOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x27D*/ { "CMSG_ENABLE_DAMAGE_LOG", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x27E*/ { "CMSG_GROUP_CHANGE_SUB_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleGroupChangeSubGroupOpcode },
- /*0x27F*/ { "CMSG_REQUEST_PARTY_MEMBER_STATS", STATUS_LOGGEDIN, &WorldSession::HandleRequestPartyMemberStatsOpcode},
- /*0x280*/ { "CMSG_GROUP_SWAP_SUB_GROUP", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x281*/ { "CMSG_RESET_FACTION_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x282*/ { "CMSG_AUTOSTORE_BANK_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoStoreBankItemOpcode },
- /*0x283*/ { "CMSG_AUTOBANK_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoBankItemOpcode },
- /*0x284*/ { "MSG_QUERY_NEXT_MAIL_TIME", STATUS_LOGGEDIN, &WorldSession::HandleMsgQueryNextMailtime },
- /*0x285*/ { "SMSG_RECEIVED_MAIL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x286*/ { "SMSG_RAID_GROUP_ONLY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x287*/ { "CMSG_SET_DURABILITY_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x288*/ { "CMSG_SET_PVP_RANK_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x289*/ { "CMSG_ADD_PVP_MEDAL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x28A*/ { "CMSG_DEL_PVP_MEDAL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x28B*/ { "CMSG_SET_PVP_TITLE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x28C*/ { "SMSG_PVP_CREDIT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x28D*/ { "SMSG_AUCTION_REMOVED_NOTIFICATION",STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x28E*/ { "CMSG_GROUP_RAID_CONVERT", STATUS_LOGGEDIN, &WorldSession::HandleRaidConvertOpcode },
- /*0x28F*/ { "CMSG_GROUP_ASSISTANT_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleGroupAssistantOpcode },
- /*0x290*/ { "CMSG_BUYBACK_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleBuybackItem },
- /*0x291*/ { "SMSG_SERVER_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x292*/ { "CMSG_MEETINGSTONE_JOIN", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x293*/ { "CMSG_MEETINGSTONE_LEAVE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x294*/ { "CMSG_MEETINGSTONE_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x295*/ { "SMSG_MEETINGSTONE_SETQUEUE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x296*/ { "CMSG_MEETINGSTONE_INFO", STATUS_LOGGEDIN, &WorldSession::HandleMeetingStoneInfo },
- /*0x297*/ { "SMSG_MEETINGSTONE_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x298*/ { "SMSG_MEETINGSTONE_IN_PROGRESS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x299*/ { "SMSG_MEETINGSTONE_MEMBER_ADDED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x29A*/ { "CMSG_GMTICKETSYSTEM_TOGGLE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x29B*/ { "CMSG_CANCEL_GROWTH_AURA", STATUS_LOGGEDIN, &WorldSession::HandleCancelGrowthAuraOpcode },
- /*0x29C*/ { "SMSG_CANCEL_AUTO_REPEAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x29D*/ { "SMSG_STANDSTATE_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x29E*/ { "SMSG_LOOT_ALL_PASSED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x29F*/ { "SMSG_LOOT_ROLL_WON", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2A0*/ { "CMSG_LOOT_ROLL", STATUS_LOGGEDIN, &WorldSession::HandleLootRoll },
- /*0x2A1*/ { "SMSG_LOOT_START_ROLL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2A2*/ { "SMSG_LOOT_ROLL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2A3*/ { "CMSG_LOOT_MASTER_GIVE", STATUS_LOGGEDIN, &WorldSession::HandleLootMasterGiveOpcode },
- /*0x2A4*/ { "SMSG_LOOT_MASTER_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2A5*/ { "SMSG_SET_FORCED_REACTIONS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2A6*/ { "SMSG_SPELL_FAILED_OTHER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2A7*/ { "SMSG_GAMEOBJECT_RESET_STATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2A8*/ { "CMSG_REPAIR_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleRepairItemOpcode },
- /*0x2A9*/ { "SMSG_CHAT_PLAYER_NOT_FOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2AA*/ { "MSG_TALENT_WIPE_CONFIRM", STATUS_LOGGEDIN, &WorldSession::HandleTalentWipeOpcode },
- /*0x2AB*/ { "SMSG_SUMMON_REQUEST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2AC*/ { "CMSG_SUMMON_RESPONSE", STATUS_LOGGEDIN, &WorldSession::HandleSummonResponseOpcode },
- /*0x2AD*/ { "MSG_MOVE_TOGGLE_GRAVITY_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x2AE*/ { "SMSG_MONSTER_MOVE_TRANSPORT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2AF*/ { "SMSG_PET_BROKEN", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2B0*/ { "MSG_MOVE_FEATHER_FALL", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x2B1*/ { "MSG_MOVE_WATER_WALK", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x2B2*/ { "CMSG_SERVER_BROADCAST", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x2B3*/ { "CMSG_SELF_RES", STATUS_LOGGEDIN, &WorldSession::HandleSelfResOpcode },
- /*0x2B4*/ { "SMSG_FEIGN_DEATH_RESISTED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2B5*/ { "CMSG_RUN_SCRIPT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x2B6*/ { "SMSG_SCRIPT_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2B7*/ { "SMSG_DUEL_COUNTDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2B8*/ { "SMSG_AREA_TRIGGER_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2B9*/ { "CMSG_TOGGLE_HELM", STATUS_LOGGEDIN, &WorldSession::HandleToggleHelmOpcode },
- /*0x2BA*/ { "CMSG_TOGGLE_CLOAK", STATUS_LOGGEDIN, &WorldSession::HandleToggleCloakOpcode },
- /*0x2BB*/ { "SMSG_MEETINGSTONE_JOINFAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2BC*/ { "SMSG_PLAYER_SKINNED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2BD*/ { "SMSG_DURABILITY_DAMAGE_DEATH", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2BE*/ { "CMSG_SET_EXPLORATION", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x2BF*/ { "CMSG_SET_ACTIONBAR_TOGGLES", STATUS_AUTHED, &WorldSession::HandleSetActionBar },
- /*0x2C0*/ { "UMSG_DELETE_GUILD_CHARTER", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x2C1*/ { "MSG_PETITION_RENAME", STATUS_LOGGEDIN, &WorldSession::HandlePetitionRenameOpcode },
- /*0x2C2*/ { "SMSG_INIT_WORLD_STATES", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2C3*/ { "SMSG_UPDATE_WORLD_STATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2C4*/ { "CMSG_ITEM_NAME_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleItemNameQueryOpcode },
- /*0x2C5*/ { "SMSG_ITEM_NAME_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2C6*/ { "SMSG_PET_ACTION_FEEDBACK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2C7*/ { "CMSG_CHAR_RENAME", STATUS_AUTHED, &WorldSession::HandleChangePlayerNameOpcode },
- /*0x2C8*/ { "SMSG_CHAR_RENAME", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2C9*/ { "CMSG_MOVE_SPLINE_DONE", STATUS_LOGGEDIN, &WorldSession::HandleTaxiNextDestinationOpcode },
- /*0x2CA*/ { "CMSG_MOVE_FALL_RESET", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x2CB*/ { "SMSG_INSTANCE_SAVE_CREATED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2CC*/ { "SMSG_RAID_INSTANCE_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2CD*/ { "CMSG_REQUEST_RAID_INFO", STATUS_LOGGEDIN, &WorldSession::HandleRequestRaidInfoOpcode },
- /*0x2CE*/ { "CMSG_MOVE_TIME_SKIPPED", STATUS_LOGGEDIN, &WorldSession::HandleMoveTimeSkippedOpcode },
- /*0x2CF*/ { "CMSG_MOVE_FEATHER_FALL_ACK", STATUS_LOGGEDIN, &WorldSession::HandleFeatherFallAck },
- /*0x2D0*/ { "CMSG_MOVE_WATER_WALK_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveWaterWalkAck },
- /*0x2D1*/ { "CMSG_MOVE_NOT_ACTIVE_MOVER", STATUS_LOGGEDIN, &WorldSession::HandleNotActiveMoverOpcode },
- /*0x2D2*/ { "SMSG_PLAY_SOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2D3*/ { "CMSG_BATTLEFIELD_STATUS", STATUS_LOGGEDIN, &WorldSession::HandleBattlefieldStatusOpcode },
- /*0x2D4*/ { "SMSG_BATTLEFIELD_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2D5*/ { "CMSG_BATTLEFIELD_PORT", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundPlayerPortOpcode},
- /*0x2D6*/ { "MSG_INSPECT_HONOR_STATS", STATUS_LOGGEDIN, &WorldSession::HandleInspectHonorStatsOpcode },
- /*0x2D7*/ { "CMSG_BATTLEMASTER_HELLO", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundHelloOpcode },
- /*0x2D8*/ { "CMSG_MOVE_START_SWIM_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x2D9*/ { "CMSG_MOVE_STOP_SWIM_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x2DA*/ { "SMSG_FORCE_WALK_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2DB*/ { "CMSG_FORCE_WALK_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck },
- /*0x2DC*/ { "SMSG_FORCE_SWIM_BACK_SPEED_CHANGE",STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2DD*/ { "CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK",STATUS_LOGGEDIN,&WorldSession::HandleForceSpeedChangeAck },
- /*0x2DE*/ { "SMSG_FORCE_TURN_RATE_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2DF*/ { "CMSG_FORCE_TURN_RATE_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck },
- /*0x2E0*/ { "MSG_PVP_LOG_DATA", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundPVPlogdataOpcode},
- /*0x2E1*/ { "CMSG_LEAVE_BATTLEFIELD", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundLeaveOpcode },
- /*0x2E2*/ { "CMSG_AREA_SPIRIT_HEALER_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleAreaSpiritHealerQueryOpcode},
- /*0x2E3*/ { "CMSG_AREA_SPIRIT_HEALER_QUEUE", STATUS_LOGGEDIN, &WorldSession::HandleAreaSpiritHealerQueueOpcode},
- /*0x2E4*/ { "SMSG_AREA_SPIRIT_HEALER_TIME", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2E5*/ { "CMSG_GM_UNTEACH", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x2E6*/ { "SMSG_WARDEN_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2E7*/ { "CMSG_WARDEN_DATA", STATUS_LOGGEDIN, &WorldSession::HandleWardenDataOpcode },
- /*0x2E8*/ { "SMSG_GROUP_JOINED_BATTLEGROUND", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2E9*/ { "MSG_BATTLEGROUND_PLAYER_POSITIONS",STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundPlayerPositionsOpcode},
- /*0x2EA*/ { "CMSG_PET_STOP_ATTACK", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x2EB*/ { "SMSG_BINDER_CONFIRM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2EC*/ { "SMSG_BATTLEGROUND_PLAYER_JOINED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2ED*/ { "SMSG_BATTLEGROUND_PLAYER_LEFT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2EE*/ { "CMSG_BATTLEMASTER_JOIN", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundJoinOpcode },
- /*0x2EF*/ { "SMSG_ADDON_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2F0*/ { "CMSG_PET_UNLEARN", STATUS_LOGGEDIN, &WorldSession::HandlePetUnlearnOpcode },
- /*0x2F1*/ { "SMSG_PET_UNLEARN_CONFIRM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2F2*/ { "SMSG_PARTY_MEMBER_STATS_FULL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2F3*/ { "CMSG_PET_SPELL_AUTOCAST", STATUS_LOGGEDIN, &WorldSession::HandlePetSpellAutocastOpcode },
- /*0x2F4*/ { "SMSG_WEATHER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2F5*/ { "SMSG_PLAY_TIME_WARNING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2F6*/ { "SMSG_MINIGAME_SETUP", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2F7*/ { "SMSG_MINIGAME_STATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2F8*/ { "CMSG_MINIGAME_MOVE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x2F9*/ { "SMSG_MINIGAME_MOVE_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2FA*/ { "SMSG_RAID_INSTANCE_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2FB*/ { "SMSG_COMPRESSED_MOVES", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2FC*/ { "CMSG_GUILD_INFO_TEXT", STATUS_LOGGEDIN, &WorldSession::HandleGuildChangeInfoOpcode },
- /*0x2FD*/ { "SMSG_CHAT_RESTRICTED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2FE*/ { "SMSG_SPLINE_SET_RUN_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x2FF*/ { "SMSG_SPLINE_SET_RUN_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x300*/ { "SMSG_SPLINE_SET_SWIM_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x301*/ { "SMSG_SPLINE_SET_WALK_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x302*/ { "SMSG_SPLINE_SET_SWIM_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x303*/ { "SMSG_SPLINE_SET_TURN_RATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x304*/ { "SMSG_SPLINE_MOVE_UNROOT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x305*/ { "SMSG_SPLINE_MOVE_FEATHER_FALL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x306*/ { "SMSG_SPLINE_MOVE_NORMAL_FALL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x307*/ { "SMSG_SPLINE_MOVE_SET_HOVER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x308*/ { "SMSG_SPLINE_MOVE_UNSET_HOVER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x309*/ { "SMSG_SPLINE_MOVE_WATER_WALK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x30A*/ { "SMSG_SPLINE_MOVE_LAND_WALK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x30B*/ { "SMSG_SPLINE_MOVE_START_SWIM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x30C*/ { "SMSG_SPLINE_MOVE_STOP_SWIM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x30D*/ { "SMSG_SPLINE_MOVE_SET_RUN_MODE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x30E*/ { "SMSG_SPLINE_MOVE_SET_WALK_MODE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x30F*/ { "CMSG_GM_NUKE_ACCOUNT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x310*/ { "MSG_GM_DESTROY_CORPSE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x311*/ { "CMSG_GM_DESTROY_ONLINE_CORPSE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x312*/ { "CMSG_ACTIVATETAXIEXPRESS", STATUS_LOGGEDIN, &WorldSession::HandleActivateTaxiFarOpcode },
- /*0x313*/ { "SMSG_SET_FACTION_ATWAR", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x314*/ { "SMSG_GAMETIMEBIAS_SET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x315*/ { "CMSG_DEBUG_ACTIONS_START", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x316*/ { "CMSG_DEBUG_ACTIONS_STOP", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x317*/ { "CMSG_SET_FACTION_INACTIVE", STATUS_LOGGEDIN, &WorldSession::HandleSetWatchedFactionInactiveOpcode},
- /*0x318*/ { "CMSG_SET_WATCHED_FACTION", STATUS_LOGGEDIN, &WorldSession::HandleSetWatchedFactionIndexOpcode},
- /*0x319*/ { "MSG_MOVE_TIME_SKIPPED", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x31A*/ { "SMSG_SPLINE_MOVE_ROOT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x31B*/ { "CMSG_SET_EXPLORATION_ALL", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x31C*/ { "SMSG_INVALIDATE_PLAYER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x31D*/ { "CMSG_RESET_INSTANCES", STATUS_LOGGEDIN, &WorldSession::HandleResetInstancesOpcode },
- /*0x31E*/ { "SMSG_INSTANCE_RESET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x31F*/ { "SMSG_INSTANCE_RESET_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x320*/ { "SMSG_UPDATE_LAST_INSTANCE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x321*/ { "MSG_RAID_TARGET_UPDATE", STATUS_LOGGEDIN, &WorldSession::HandleRaidIconTargetOpcode },
- /*0x322*/ { "MSG_RAID_READY_CHECK", STATUS_LOGGEDIN, &WorldSession::HandleRaidReadyCheckOpcode },
- /*0x323*/ { "CMSG_LUA_USAGE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x324*/ { "SMSG_PET_ACTION_SOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x325*/ { "SMSG_PET_DISMISS_SOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x326*/ { "SMSG_GHOSTEE_GONE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x327*/ { "CMSG_GM_UPDATE_TICKET_STATUS", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x328*/ { "SMSG_GM_TICKET_STATUS_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x329*/ { "MSG_SET_DUNGEON_DIFFICULTY", STATUS_LOGGEDIN, &WorldSession::HandleDungeonDifficultyOpcode },
- /*0x32A*/ { "CMSG_GMSURVEY_SUBMIT", STATUS_LOGGEDIN, &WorldSession::Handle_NULL },//&WorldSession::HandleGMSurveySubmit
- /*0x32B*/ { "SMSG_UPDATE_INSTANCE_OWNERSHIP", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x32C*/ { "CMSG_IGNORE_KNOCKBACK_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x32D*/ { "SMSG_CHAT_PLAYER_AMBIGUOUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x32E*/ { "MSG_DELAY_GHOST_TELEPORT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x32F*/ { "SMSG_SPELLINSTAKILLLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x330*/ { "SMSG_SPELL_UPDATE_CHAIN_TARGETS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x331*/ { "CMSG_CHAT_FILTERED", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x332*/ { "SMSG_EXPECTED_SPAM_RECORDS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x333*/ { "SMSG_SPELLSTEALLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x334*/ { "CMSG_LOTTERY_QUERY_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x335*/ { "SMSG_LOTTERY_QUERY_RESULT_OBSOLETE",STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x336*/ { "CMSG_BUY_LOTTERY_TICKET_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x337*/ { "SMSG_LOTTERY_RESULT_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x338*/ { "SMSG_CHARACTER_PROFILE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x339*/ { "SMSG_CHARACTER_PROFILE_REALM_CONNECTED",STATUS_NEVER,&WorldSession::Handle_ServerSide },
- /*0x33A*/ { "SMSG_DEFENSE_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x33B*/ { "SMSG_INSTANCE_DIFFICULTY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x33C*/ { "MSG_GM_RESETINSTANCELIMIT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x33D*/ { "SMSG_MOTD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x33E*/ { "SMSG_MOVE_SET_FLIGHT_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x33F*/ { "SMSG_MOVE_UNSET_FLIGHT_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x340*/ { "CMSG_MOVE_FLIGHT_ACK_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x341*/ { "MSG_MOVE_START_SWIM_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x342*/ { "MSG_MOVE_STOP_SWIM_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x343*/ { "SMSG_MOVE_SET_CAN_FLY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x344*/ { "SMSG_MOVE_UNSET_CAN_FLY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x345*/ { "CMSG_MOVE_SET_CAN_FLY_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveFlyModeChangeAckOpcode},
- /*0x346*/ { "CMSG_MOVE_SET_FLY", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x347*/ { "CMSG_SOCKET_GEMS", STATUS_LOGGEDIN, &WorldSession::HandleSocketOpcode },
- /*0x348*/ { "CMSG_ARENA_TEAM_CREATE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x349*/ { "SMSG_ARENA_TEAM_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x34A*/ { "UMSG_UPDATE_ARENA_TEAM_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x34B*/ { "CMSG_ARENA_TEAM_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamQueryOpcode },
- /*0x34C*/ { "SMSG_ARENA_TEAM_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x34D*/ { "CMSG_ARENA_TEAM_ROSTER", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamRosterOpcode },
- /*0x34E*/ { "SMSG_ARENA_TEAM_ROSTER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x34F*/ { "CMSG_ARENA_TEAM_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamAddMemberOpcode },
- /*0x350*/ { "SMSG_ARENA_TEAM_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x351*/ { "CMSG_ARENA_TEAM_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamInviteAcceptOpcode},
- /*0x352*/ { "CMSG_ARENA_TEAM_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamInviteDeclineOpcode},
- /*0x353*/ { "CMSG_ARENA_TEAM_LEAVE", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamLeaveOpcode },
- /*0x354*/ { "CMSG_ARENA_TEAM_REMOVE", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamRemoveFromTeamOpcode},
- /*0x355*/ { "CMSG_ARENA_TEAM_DISBAND", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamDisbandOpcode },
- /*0x356*/ { "CMSG_ARENA_TEAM_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamPromoteToCaptainOpcode},
- /*0x357*/ { "SMSG_ARENA_TEAM_EVENT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x358*/ { "CMSG_BATTLEMASTER_JOIN_ARENA", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundArenaJoin },
- /*0x359*/ { "MSG_MOVE_START_ASCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x35A*/ { "MSG_MOVE_STOP_ASCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x35B*/ { "SMSG_ARENA_TEAM_STATS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x35C*/ { "CMSG_LFG_SET_AUTOJOIN", STATUS_AUTHED, &WorldSession::HandleLfgAutoJoinOpcode },
- /*0x35D*/ { "CMSG_LFG_CLEAR_AUTOJOIN", STATUS_LOGGEDIN, &WorldSession::HandleLfgCancelAutoJoinOpcode },
- /*0x35E*/ { "CMSG_LFM_SET_AUTOFILL", STATUS_AUTHED, &WorldSession::HandleLfmAutoAddMembersOpcode },
- /*0x35F*/ { "CMSG_LFM_CLEAR_AUTOFILL", STATUS_LOGGEDIN, &WorldSession::HandleLfmCancelAutoAddmembersOpcode},
- /*0x360*/ { "CMSG_ACCEPT_LFG_MATCH", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x361*/ { "CMSG_DECLINE_LFG_MATCH", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x362*/ { "CMSG_CANCEL_PENDING_LFG", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x363*/ { "CMSG_CLEAR_LOOKING_FOR_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleLfgClearOpcode },
- /*0x364*/ { "CMSG_CLEAR_LOOKING_FOR_MORE", STATUS_LOGGEDIN, &WorldSession::HandleLfmSetNoneOpcode },
- /*0x365*/ { "CMSG_SET_LOOKING_FOR_MORE", STATUS_LOGGEDIN, &WorldSession::HandleLfmSetOpcode },
- /*0x366*/ { "CMSG_SET_LFG_COMMENT", STATUS_LOGGEDIN, &WorldSession::HandleLfgSetCommentOpcode },
- /*0x367*/ { "SMSG_LFG_TIMEDOUT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x368*/ { "SMSG_LFG_OTHER_TIMEDOUT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x369*/ { "SMSG_LFG_AUTOJOIN_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x36A*/ { "SMSG_LFG_AUTOJOIN_FAILED_NO_PLAYER",STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x36B*/ { "SMSG_LFG_LEADER_IS_LFM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x36C*/ { "SMSG_LFG_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x36D*/ { "SMSG_LFG_UPDATE_LFM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x36E*/ { "SMSG_LFG_UPDATE_LFG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x36F*/ { "SMSG_LFG_UPDATE_QUEUED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x370*/ { "SMSG_LFG_PENDING_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x371*/ { "SMSG_LFG_PENDING_MATCH", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x372*/ { "SMSG_LFG_PENDING_MATCH_DONE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x373*/ { "SMSG_TITLE_EARNED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x374*/ { "CMSG_SET_TITLE", STATUS_LOGGEDIN, &WorldSession::HandleChooseTitleOpcode },
- /*0x375*/ { "CMSG_CANCEL_MOUNT_AURA", STATUS_LOGGEDIN, &WorldSession::HandleDismountOpcode },
- /*0x376*/ { "SMSG_ARENA_ERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x377*/ { "MSG_INSPECT_ARENA_TEAMS", STATUS_LOGGEDIN, &WorldSession::HandleInspectArenaStatsOpcode },
- /*0x378*/ { "SMSG_DEATH_RELEASE_LOC", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x379*/ { "CMSG_CANCEL_TEMP_ENCHANTMENT", STATUS_LOGGEDIN, &WorldSession::HandleCancelTempItemEnchantmentOpcode},
- /*0x37A*/ { "SMSG_FORCED_DEATH_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x37B*/ { "CMSG_CHEAT_SET_HONOR_CURRENCY", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x37C*/ { "CMSG_CHEAT_SET_ARENA_CURRENCY", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x37D*/ { "MSG_MOVE_SET_FLIGHT_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x37E*/ { "MSG_MOVE_SET_FLIGHT_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x37F*/ { "MSG_MOVE_SET_FLIGHT_BACK_SPEED_CHEAT",STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x380*/ { "MSG_MOVE_SET_FLIGHT_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x381*/ { "SMSG_FORCE_FLIGHT_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x382*/ { "CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK",STATUS_LOGGEDIN,&WorldSession::HandleForceSpeedChangeAck },
- /*0x383*/ { "SMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE",STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x384*/ { "CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK",STATUS_LOGGEDIN,&WorldSession::HandleForceSpeedChangeAck },
- /*0x385*/ { "SMSG_SPLINE_SET_FLIGHT_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x386*/ { "SMSG_SPLINE_SET_FLIGHT_BACK_SPEED",STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x387*/ { "CMSG_MAELSTROM_INVALIDATE_CACHE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x388*/ { "SMSG_FLIGHT_SPLINE_SYNC", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x389*/ { "CMSG_SET_TAXI_BENCHMARK_MODE", STATUS_AUTHED, &WorldSession::HandleSetTaxiBenchmarkOpcode },
- /*0x38A*/ { "SMSG_JOINED_BATTLEGROUND_QUEUE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x38B*/ { "SMSG_REALM_SPLIT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x38C*/ { "CMSG_REALM_SPLIT", STATUS_AUTHED, &WorldSession::HandleRealmStateRequestOpcode },
- /*0x38D*/ { "CMSG_MOVE_CHNG_TRANSPORT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x38E*/ { "MSG_PARTY_ASSIGNMENT", STATUS_LOGGEDIN, &WorldSession::HandleGroupPromoteOpcode },
- /*0x38F*/ { "SMSG_OFFER_PETITION_ERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x390*/ { "SMSG_TIME_SYNC_REQ", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x391*/ { "CMSG_TIME_SYNC_RESP", STATUS_LOGGEDIN, &WorldSession::HandleAllowMoveAckOpcode },
- /*0x392*/ { "CMSG_SEND_LOCAL_EVENT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x393*/ { "CMSG_SEND_GENERAL_TRIGGER", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x394*/ { "CMSG_SEND_COMBAT_TRIGGER", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x395*/ { "CMSG_MAELSTROM_GM_SENT_MAIL", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x396*/ { "SMSG_RESET_FAILED_NOTIFY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x397*/ { "SMSG_REAL_GROUP_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x398*/ { "SMSG_LFG_DISABLED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x399*/ { "CMSG_ACTIVE_PVP_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x39A*/ { "CMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x39B*/ { "SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE",STATUS_NEVER,&WorldSession::Handle_ServerSide },
- /*0x39C*/ { "SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE_WRITE_FILE",STATUS_NEVER,&WorldSession::Handle_ServerSide},
- /*0x39D*/ { "SMSG_UPDATE_COMBO_POINTS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x39E*/ { "SMSG_VOICE_SESSION_ROSTER_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x39F*/ { "SMSG_VOICE_SESSION_LEAVE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3A0*/ { "SMSG_VOICE_SESSION_ADJUST_PRIORITY",STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3A1*/ { "CMSG_VOICE_SET_TALKER_MUTED_REQUEST",STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3A2*/ { "SMSG_VOICE_SET_TALKER_MUTED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3A3*/ { "SMSG_INIT_EXTRA_AURA_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3A4*/ { "SMSG_SET_EXTRA_AURA_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3A5*/ { "SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE",STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3A6*/ { "SMSG_CLEAR_EXTRA_AURA_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3A7*/ { "MSG_MOVE_START_DESCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
- /*0x3A8*/ { "CMSG_IGNORE_REQUIREMENTS_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3A9*/ { "SMSG_IGNORE_REQUIREMENTS_CHEAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3AA*/ { "SMSG_SPELL_CHANCE_PROC_LOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3AB*/ { "CMSG_MOVE_SET_RUN_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3AC*/ { "SMSG_DISMOUNT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3AD*/ { "MSG_MOVE_UPDATE_CAN_FLY", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3AE*/ { "MSG_RAID_READY_CHECK_CONFIRM", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3AF*/ { "CMSG_VOICE_SESSION_ENABLE", STATUS_AUTHED, &WorldSession::HandleVoiceSettingsOpcode },
- /*0x3B0*/ { "SMSG_VOICE_PARENTAL_CONTROLS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3B1*/ { "CMSG_GM_WHISPER", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3B2*/ { "SMSG_GM_MESSAGECHAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3B3*/ { "MSG_GM_GEARRATING", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3B4*/ { "CMSG_COMMENTATOR_ENABLE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3B5*/ { "SMSG_COMMENTATOR_STATE_CHANGED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3B6*/ { "CMSG_COMMENTATOR_GET_MAP_INFO", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3B7*/ { "SMSG_COMMENTATOR_MAP_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3B8*/ { "CMSG_COMMENTATOR_GET_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3B9*/ { "SMSG_COMMENTATOR_GET_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3BA*/ { "SMSG_COMMENTATOR_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3BB*/ { "CMSG_COMMENTATOR_ENTER_INSTANCE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3BC*/ { "CMSG_COMMENTATOR_EXIT_INSTANCE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3BD*/ { "CMSG_COMMENTATOR_INSTANCE_COMMAND",STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3BE*/ { "SMSG_CLEAR_TARGET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3BF*/ { "CMSG_BOT_DETECTED", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3C0*/ { "SMSG_CROSSED_INEBRIATION_THRESHOLD",STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3C1*/ { "CMSG_CHEAT_PLAYER_LOGIN", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3C2*/ { "CMSG_CHEAT_PLAYER_LOOKUP", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3C3*/ { "SMSG_CHEAT_PLAYER_LOOKUP", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3C4*/ { "SMSG_KICK_REASON", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3C5*/ { "MSG_RAID_READY_CHECK_FINISHED", STATUS_LOGGEDIN, &WorldSession::HandleRaidReadyCheckFinishOpcode},
- /*0x3C6*/ { "CMSG_COMPLAIN", STATUS_LOGGEDIN, &WorldSession::HandleReportSpamOpcode },
- /*0x3C7*/ { "SMSG_COMPLAIN_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3C8*/ { "SMSG_FEATURE_SYSTEM_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3C9*/ { "CMSG_GM_SHOW_COMPLAINTS", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3CA*/ { "CMSG_GM_UNSQUELCH", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3CB*/ { "CMSG_CHANNEL_SILENCE_VOICE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3CC*/ { "CMSG_CHANNEL_SILENCE_ALL", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3CD*/ { "CMSG_CHANNEL_UNSILENCE_VOICE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3CE*/ { "CMSG_CHANNEL_UNSILENCE_ALL", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3CF*/ { "CMSG_TARGET_CAST", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3D0*/ { "CMSG_TARGET_SCRIPT_CAST", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3D1*/ { "CMSG_CHANNEL_DISPLAY_LIST", STATUS_LOGGEDIN, &WorldSession::HandleChannelRosterQuery },
- /*0x3D2*/ { "CMSG_SET_ACTIVE_VOICE_CHANNEL", STATUS_AUTHED, &WorldSession::HandleChannelVoiceChatQuery },
- /*0x3D3*/ { "CMSG_GET_CHANNEL_MEMBER_COUNT", STATUS_LOGGEDIN, &WorldSession::HandleChannelInfoQuery },
- /*0x3D4*/ { "SMSG_CHANNEL_MEMBER_COUNT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3D5*/ { "CMSG_CHANNEL_VOICE_ON", STATUS_LOGGEDIN, &WorldSession::HandleChannelEnableVoiceOpcode },
- /*0x3D6*/ { "CMSG_CHANNEL_VOICE_OFF", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3D7*/ { "CMSG_DEBUG_LIST_TARGETS", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3D8*/ { "SMSG_DEBUG_LIST_TARGETS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3D9*/ { "SMSG_AVAILABLE_VOICE_CHANNEL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3DA*/ { "CMSG_ADD_VOICE_IGNORE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3DB*/ { "CMSG_DEL_VOICE_IGNORE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3DC*/ { "CMSG_PARTY_SILENCE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3DD*/ { "CMSG_PARTY_UNSILENCE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3DE*/ { "MSG_NOTIFY_PARTY_SQUELCH", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3DF*/ { "SMSG_COMSAT_RECONNECT_TRY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3E0*/ { "SMSG_COMSAT_DISCONNECT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3E1*/ { "SMSG_COMSAT_CONNECT_FAIL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3E2*/ { "SMSG_VOICE_CHAT_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3E3*/ { "CMSG_REPORT_PVP_AFK", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundReportAFK },
- /*0x3E4*/ { "CMSG_REPORT_PVP_AFK_RESULT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3E5*/ { "CMSG_GUILD_BANKER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankQuery },
- /*0x3E6*/ { "CMSG_GUILD_BANK_QUERY_TAB", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankTabColon },
- /*0x3E7*/ { "SMSG_GUILD_BANK_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3E8*/ { "CMSG_GUILD_BANK_SWAP_ITEMS", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankDepositItem },
- /*0x3E9*/ { "CMSG_GUILD_BANK_BUY_TAB", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankBuyTab },
- /*0x3EA*/ { "CMSG_GUILD_BANK_UPDATE_TAB", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankModifyTab },
- /*0x3EB*/ { "CMSG_GUILD_BANK_DEPOSIT_MONEY", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankDeposit },
- /*0x3EC*/ { "CMSG_GUILD_BANK_WITHDRAW_MONEY", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankWithdraw },
- /*0x3ED*/ { "MSG_GUILD_BANK_LOG_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankLog },
- /*0x3EE*/ { "CMSG_SET_CHANNEL_WATCH", STATUS_LOGGEDIN, &WorldSession::HandleChannelJoinNotify },
- /*0x3EF*/ { "SMSG_USERLIST_ADD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3F0*/ { "SMSG_USERLIST_REMOVE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3F1*/ { "SMSG_USERLIST_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3F2*/ { "CMSG_CLEAR_CHANNEL_WATCH", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3F3*/ { "SMSG_INSPECT_TALENT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3F4*/ { "SMSG_GOGOGO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3F5*/ { "SMSG_ECHO_PARTY_SQUELCH", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3F6*/ { "CMSG_SET_TITLE_SUFFIX", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3F7*/ { "CMSG_SPELLCLICK", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3F8*/ { "SMSG_LOOT_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3F9*/ { "CMSG_GM_CHARACTER_RESTORE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3FA*/ { "CMSG_GM_CHARACTER_SAVE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x3FB*/ { "SMSG_VOICESESSION_FULL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x3FC*/ { "MSG_GUILD_PERMISSIONS", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankGetRights },
- /*0x3FD*/ { "MSG_GUILD_BANK_MONEY_WITHDRAWN", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankGetMoneyAmount },
- /*0x3FE*/ { "MSG_GUILD_EVENT_LOG_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleGuildEventLogOpcode },
- /*0x3FF*/ { "CMSG_MAELSTROM_RENAME_GUILD", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x400*/ { "CMSG_GET_MIRRORIMAGE_DATA", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x401*/ { "SMSG_MIRRORIMAGE_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x402*/ { "SMSG_FORCE_DISPLAY_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x403*/ { "SMSG_SPELL_CHANCE_RESIST_PUSHBACK",STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x404*/ { "CMSG_IGNORE_DIMINISHING_RETURNS_CHEAT",STATUS_NEVER,&WorldSession::Handle_NULL },
- /*0x405*/ { "SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT",STATUS_NEVER,&WorldSession::Handle_ServerSide },
- /*0x406*/ { "CMSG_KEEP_ALIVE", STATUS_NEVER, &WorldSession::Handle_EarlyProccess },
- /*0x407*/ { "SMSG_RAID_READY_CHECK_ERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x408*/ { "CMSG_OPT_OUT_OF_LOOT", STATUS_AUTHED, &WorldSession::HandleGroupPassOnLootOpcode },
- /*0x409*/ { "MSG_QUERY_GUILD_BANK_TEXT", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankTabText },
- /*0x40A*/ { "CMSG_SET_GUILD_BANK_TEXT", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankSetTabText },
- /*0x40B*/ { "CMSG_SET_GRANTABLE_LEVELS", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x40C*/ { "CMSG_GRANT_LEVEL", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x40D*/ { "CMSG_REFER_A_FRIEND", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x40E*/ { "MSG_GM_CHANGE_ARENA_RATING", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x208*/ { "SMSG_GMTICKET_UPDATETEXT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x209*/ { "SMSG_ACCOUNT_DATA_TIMES", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x20A*/ { "CMSG_REQUEST_ACCOUNT_DATA", STATUS_LOGGEDIN, &WorldSession::HandleRequestAccountData },
+ /*0x20B*/ { "CMSG_UPDATE_ACCOUNT_DATA", STATUS_AUTHED, &WorldSession::HandleUpdateAccountData },
+ /*0x20C*/ { "SMSG_UPDATE_ACCOUNT_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x20D*/ { "SMSG_CLEAR_FAR_SIGHT_IMMEDIATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x20E*/ { "SMSG_POWERGAINLOG_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x20F*/ { "CMSG_GM_TEACH", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x210*/ { "CMSG_GM_CREATE_ITEM_TARGET", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x211*/ { "CMSG_GMTICKET_GETTICKET", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketGetTicketOpcode },
+ /*0x212*/ { "SMSG_GMTICKET_GETTICKET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x213*/ { "CMSG_UNLEARN_TALENTS", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x214*/ { "SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x215*/ { "SMSG_GAMEOBJECT_DESPAWN_ANIM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x216*/ { "MSG_CORPSE_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleCorpseQueryOpcode },
+ /*0x217*/ { "CMSG_GMTICKET_DELETETICKET", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketDeleteOpcode },
+ /*0x218*/ { "SMSG_GMTICKET_DELETETICKET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x219*/ { "SMSG_CHAT_WRONG_FACTION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x21A*/ { "CMSG_GMTICKET_SYSTEMSTATUS", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketSystemStatusOpcode},
+ /*0x21B*/ { "SMSG_GMTICKET_SYSTEMSTATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x21C*/ { "CMSG_SPIRIT_HEALER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleSpiritHealerActivateOpcode},
+ /*0x21D*/ { "CMSG_SET_STAT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x21E*/ { "SMSG_SET_REST_START_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x21F*/ { "CMSG_SKILL_BUY_STEP", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x220*/ { "CMSG_SKILL_BUY_RANK", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x221*/ { "CMSG_XP_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x222*/ { "SMSG_SPIRIT_HEALER_CONFIRM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x223*/ { "CMSG_CHARACTER_POINT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x224*/ { "SMSG_GOSSIP_POI", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x225*/ { "CMSG_CHAT_IGNORED", STATUS_LOGGEDIN, &WorldSession::HandleChatIgnoredOpcode },
+ /*0x226*/ { "CMSG_GM_VISION", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x227*/ { "CMSG_SERVER_COMMAND", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x228*/ { "CMSG_GM_SILENCE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x229*/ { "CMSG_GM_REVEALTO", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x22A*/ { "CMSG_GM_RESURRECT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x22B*/ { "CMSG_GM_SUMMONMOB", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x22C*/ { "CMSG_GM_MOVECORPSE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x22D*/ { "CMSG_GM_FREEZE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x22E*/ { "CMSG_GM_UBERINVIS", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x22F*/ { "CMSG_GM_REQUEST_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x230*/ { "SMSG_GM_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x231*/ { "CMSG_GUILD_RANK", STATUS_LOGGEDIN, &WorldSession::HandleGuildRankOpcode },
+ /*0x232*/ { "CMSG_GUILD_ADD_RANK", STATUS_LOGGEDIN, &WorldSession::HandleGuildAddRankOpcode },
+ /*0x233*/ { "CMSG_GUILD_DEL_RANK", STATUS_LOGGEDIN, &WorldSession::HandleGuildDelRankOpcode },
+ /*0x234*/ { "CMSG_GUILD_SET_PUBLIC_NOTE", STATUS_LOGGEDIN, &WorldSession::HandleGuildSetPublicNoteOpcode },
+ /*0x235*/ { "CMSG_GUILD_SET_OFFICER_NOTE", STATUS_LOGGEDIN, &WorldSession::HandleGuildSetOfficerNoteOpcode },
+ /*0x236*/ { "SMSG_LOGIN_VERIFY_WORLD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x237*/ { "CMSG_CLEAR_EXPLORATION", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x238*/ { "CMSG_SEND_MAIL", STATUS_LOGGEDIN, &WorldSession::HandleSendMail },
+ /*0x239*/ { "SMSG_SEND_MAIL_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x23A*/ { "CMSG_GET_MAIL_LIST", STATUS_LOGGEDIN, &WorldSession::HandleGetMail },
+ /*0x23B*/ { "SMSG_MAIL_LIST_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x23C*/ { "CMSG_BATTLEFIELD_LIST", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundListOpcode },
+ /*0x23D*/ { "SMSG_BATTLEFIELD_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x23E*/ { "CMSG_BATTLEFIELD_JOIN", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x23F*/ { "SMSG_BATTLEFIELD_WIN_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x240*/ { "SMSG_BATTLEFIELD_LOSE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x241*/ { "CMSG_TAXICLEARNODE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x242*/ { "CMSG_TAXIENABLENODE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x243*/ { "CMSG_ITEM_TEXT_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleItemTextQuery },
+ /*0x244*/ { "SMSG_ITEM_TEXT_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x245*/ { "CMSG_MAIL_TAKE_MONEY", STATUS_LOGGEDIN, &WorldSession::HandleTakeMoney },
+ /*0x246*/ { "CMSG_MAIL_TAKE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleTakeItem },
+ /*0x247*/ { "CMSG_MAIL_MARK_AS_READ", STATUS_LOGGEDIN, &WorldSession::HandleMarkAsRead },
+ /*0x248*/ { "CMSG_MAIL_RETURN_TO_SENDER", STATUS_LOGGEDIN, &WorldSession::HandleReturnToSender },
+ /*0x249*/ { "CMSG_MAIL_DELETE", STATUS_LOGGEDIN, &WorldSession::HandleMailDelete },
+ /*0x24A*/ { "CMSG_MAIL_CREATE_TEXT_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleMailCreateTextItem },
+ /*0x24B*/ { "SMSG_SPELLLOGMISS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x24C*/ { "SMSG_SPELLLOGEXECUTE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x24D*/ { "SMSG_DEBUGAURAPROC", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x24E*/ { "SMSG_PERIODICAURALOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x24F*/ { "SMSG_SPELLDAMAGESHIELD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x250*/ { "SMSG_SPELLNONMELEEDAMAGELOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x251*/ { "CMSG_LEARN_TALENT", STATUS_LOGGEDIN, &WorldSession::HandleLearnTalentOpcode },
+ /*0x252*/ { "SMSG_RESURRECT_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x253*/ { "CMSG_TOGGLE_PVP", STATUS_LOGGEDIN, &WorldSession::HandleTogglePvP },
+ /*0x254*/ { "SMSG_ZONE_UNDER_ATTACK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x255*/ { "MSG_AUCTION_HELLO", STATUS_LOGGEDIN, &WorldSession::HandleAuctionHelloOpcode },
+ /*0x256*/ { "CMSG_AUCTION_SELL_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAuctionSellItem },
+ /*0x257*/ { "CMSG_AUCTION_REMOVE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAuctionRemoveItem },
+ /*0x258*/ { "CMSG_AUCTION_LIST_ITEMS", STATUS_LOGGEDIN, &WorldSession::HandleAuctionListItems },
+ /*0x259*/ { "CMSG_AUCTION_LIST_OWNER_ITEMS", STATUS_LOGGEDIN, &WorldSession::HandleAuctionListOwnerItems },
+ /*0x25A*/ { "CMSG_AUCTION_PLACE_BID", STATUS_LOGGEDIN, &WorldSession::HandleAuctionPlaceBid },
+ /*0x25B*/ { "SMSG_AUCTION_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x25C*/ { "SMSG_AUCTION_LIST_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x25D*/ { "SMSG_AUCTION_OWNER_LIST_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x25E*/ { "SMSG_AUCTION_BIDDER_NOTIFICATION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x25F*/ { "SMSG_AUCTION_OWNER_NOTIFICATION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x260*/ { "SMSG_PROCRESIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x261*/ { "SMSG_STANDSTATE_CHANGE_FAILURE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x262*/ { "SMSG_DISPEL_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x263*/ { "SMSG_SPELLORDAMAGE_IMMUNE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x264*/ { "CMSG_AUCTION_LIST_BIDDER_ITEMS", STATUS_LOGGEDIN, &WorldSession::HandleAuctionListBidderItems },
+ /*0x265*/ { "SMSG_AUCTION_BIDDER_LIST_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x266*/ { "SMSG_SET_FLAT_SPELL_MODIFIER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x267*/ { "SMSG_SET_PCT_SPELL_MODIFIER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x268*/ { "CMSG_SET_AMMO", STATUS_LOGGEDIN, &WorldSession::HandleSetAmmoOpcode },
+ /*0x269*/ { "SMSG_CORPSE_RECLAIM_DELAY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x26A*/ { "CMSG_SET_ACTIVE_MOVER", STATUS_LOGGEDIN, &WorldSession::HandleSetActiveMoverOpcode },
+ /*0x26B*/ { "CMSG_PET_CANCEL_AURA", STATUS_LOGGEDIN, &WorldSession::HandlePetCancelAuraOpcode },
+ /*0x26C*/ { "CMSG_PLAYER_AI_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x26D*/ { "CMSG_CANCEL_AUTO_REPEAT_SPELL", STATUS_LOGGEDIN, &WorldSession::HandleCancelAutoRepeatSpellOpcode},
+ /*0x26E*/ { "MSG_GM_ACCOUNT_ONLINE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x26F*/ { "MSG_LIST_STABLED_PETS", STATUS_LOGGEDIN, &WorldSession::HandleListStabledPetsOpcode },
+ /*0x270*/ { "CMSG_STABLE_PET", STATUS_LOGGEDIN, &WorldSession::HandleStablePet },
+ /*0x271*/ { "CMSG_UNSTABLE_PET", STATUS_LOGGEDIN, &WorldSession::HandleUnstablePet },
+ /*0x272*/ { "CMSG_BUY_STABLE_SLOT", STATUS_LOGGEDIN, &WorldSession::HandleBuyStableSlot },
+ /*0x273*/ { "SMSG_STABLE_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x274*/ { "CMSG_STABLE_REVIVE_PET", STATUS_LOGGEDIN, &WorldSession::HandleStableRevivePet },
+ /*0x275*/ { "CMSG_STABLE_SWAP_PET", STATUS_LOGGEDIN, &WorldSession::HandleStableSwapPet },
+ /*0x276*/ { "MSG_QUEST_PUSH_RESULT", STATUS_LOGGEDIN, &WorldSession::HandleQuestPushResult },
+ /*0x277*/ { "SMSG_PLAY_MUSIC", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x278*/ { "SMSG_PLAY_OBJECT_SOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x279*/ { "CMSG_REQUEST_PET_INFO", STATUS_LOGGEDIN, &WorldSession::HandleRequestPetInfoOpcode },
+ /*0x27A*/ { "CMSG_FAR_SIGHT", STATUS_LOGGEDIN, &WorldSession::HandleFarSightOpcode },
+ /*0x27B*/ { "SMSG_SPELLDISPELLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x27C*/ { "SMSG_DAMAGE_CALC_LOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x27D*/ { "CMSG_ENABLE_DAMAGE_LOG", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x27E*/ { "CMSG_GROUP_CHANGE_SUB_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleGroupChangeSubGroupOpcode },
+ /*0x27F*/ { "CMSG_REQUEST_PARTY_MEMBER_STATS", STATUS_LOGGEDIN, &WorldSession::HandleRequestPartyMemberStatsOpcode},
+ /*0x280*/ { "CMSG_GROUP_SWAP_SUB_GROUP", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x281*/ { "CMSG_RESET_FACTION_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x282*/ { "CMSG_AUTOSTORE_BANK_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoStoreBankItemOpcode },
+ /*0x283*/ { "CMSG_AUTOBANK_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoBankItemOpcode },
+ /*0x284*/ { "MSG_QUERY_NEXT_MAIL_TIME", STATUS_LOGGEDIN, &WorldSession::HandleMsgQueryNextMailtime },
+ /*0x285*/ { "SMSG_RECEIVED_MAIL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x286*/ { "SMSG_RAID_GROUP_ONLY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x287*/ { "CMSG_SET_DURABILITY_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x288*/ { "CMSG_SET_PVP_RANK_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x289*/ { "CMSG_ADD_PVP_MEDAL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x28A*/ { "CMSG_DEL_PVP_MEDAL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x28B*/ { "CMSG_SET_PVP_TITLE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x28C*/ { "SMSG_PVP_CREDIT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x28D*/ { "SMSG_AUCTION_REMOVED_NOTIFICATION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x28E*/ { "CMSG_GROUP_RAID_CONVERT", STATUS_LOGGEDIN, &WorldSession::HandleRaidConvertOpcode },
+ /*0x28F*/ { "CMSG_GROUP_ASSISTANT_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleGroupAssistantOpcode },
+ /*0x290*/ { "CMSG_BUYBACK_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleBuybackItem },
+ /*0x291*/ { "SMSG_SERVER_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x292*/ { "CMSG_MEETINGSTONE_JOIN", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x293*/ { "CMSG_MEETINGSTONE_LEAVE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x294*/ { "CMSG_MEETINGSTONE_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x295*/ { "SMSG_MEETINGSTONE_SETQUEUE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x296*/ { "CMSG_MEETINGSTONE_INFO", STATUS_LOGGEDIN, &WorldSession::HandleMeetingStoneInfo },
+ /*0x297*/ { "SMSG_MEETINGSTONE_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x298*/ { "SMSG_MEETINGSTONE_IN_PROGRESS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x299*/ { "SMSG_MEETINGSTONE_MEMBER_ADDED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x29A*/ { "CMSG_GMTICKETSYSTEM_TOGGLE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x29B*/ { "CMSG_CANCEL_GROWTH_AURA", STATUS_LOGGEDIN, &WorldSession::HandleCancelGrowthAuraOpcode },
+ /*0x29C*/ { "SMSG_CANCEL_AUTO_REPEAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x29D*/ { "SMSG_STANDSTATE_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x29E*/ { "SMSG_LOOT_ALL_PASSED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x29F*/ { "SMSG_LOOT_ROLL_WON", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2A0*/ { "CMSG_LOOT_ROLL", STATUS_LOGGEDIN, &WorldSession::HandleLootRoll },
+ /*0x2A1*/ { "SMSG_LOOT_START_ROLL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2A2*/ { "SMSG_LOOT_ROLL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2A3*/ { "CMSG_LOOT_MASTER_GIVE", STATUS_LOGGEDIN, &WorldSession::HandleLootMasterGiveOpcode },
+ /*0x2A4*/ { "SMSG_LOOT_MASTER_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2A5*/ { "SMSG_SET_FORCED_REACTIONS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2A6*/ { "SMSG_SPELL_FAILED_OTHER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2A7*/ { "SMSG_GAMEOBJECT_RESET_STATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2A8*/ { "CMSG_REPAIR_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleRepairItemOpcode },
+ /*0x2A9*/ { "SMSG_CHAT_PLAYER_NOT_FOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2AA*/ { "MSG_TALENT_WIPE_CONFIRM", STATUS_LOGGEDIN, &WorldSession::HandleTalentWipeOpcode },
+ /*0x2AB*/ { "SMSG_SUMMON_REQUEST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2AC*/ { "CMSG_SUMMON_RESPONSE", STATUS_LOGGEDIN, &WorldSession::HandleSummonResponseOpcode },
+ /*0x2AD*/ { "MSG_MOVE_TOGGLE_GRAVITY_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x2AE*/ { "SMSG_MONSTER_MOVE_TRANSPORT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2AF*/ { "SMSG_PET_BROKEN", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2B0*/ { "MSG_MOVE_FEATHER_FALL", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x2B1*/ { "MSG_MOVE_WATER_WALK", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x2B2*/ { "CMSG_SERVER_BROADCAST", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x2B3*/ { "CMSG_SELF_RES", STATUS_LOGGEDIN, &WorldSession::HandleSelfResOpcode },
+ /*0x2B4*/ { "SMSG_FEIGN_DEATH_RESISTED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2B5*/ { "CMSG_RUN_SCRIPT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x2B6*/ { "SMSG_SCRIPT_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2B7*/ { "SMSG_DUEL_COUNTDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2B8*/ { "SMSG_AREA_TRIGGER_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2B9*/ { "CMSG_SHOWING_HELM", STATUS_LOGGEDIN, &WorldSession::HandleToggleHelmOpcode },
+ /*0x2BA*/ { "CMSG_SHOWING_CLOAK", STATUS_LOGGEDIN, &WorldSession::HandleToggleCloakOpcode },
+ /*0x2BB*/ { "SMSG_MEETINGSTONE_JOINFAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2BC*/ { "SMSG_PLAYER_SKINNED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2BD*/ { "SMSG_DURABILITY_DAMAGE_DEATH", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2BE*/ { "CMSG_SET_EXPLORATION", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x2BF*/ { "CMSG_SET_ACTIONBAR_TOGGLES", STATUS_AUTHED, &WorldSession::HandleSetActionBar },
+ /*0x2C0*/ { "UMSG_DELETE_GUILD_CHARTER", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x2C1*/ { "MSG_PETITION_RENAME", STATUS_LOGGEDIN, &WorldSession::HandlePetitionRenameOpcode },
+ /*0x2C2*/ { "SMSG_INIT_WORLD_STATES", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2C3*/ { "SMSG_UPDATE_WORLD_STATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2C4*/ { "CMSG_ITEM_NAME_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleItemNameQueryOpcode },
+ /*0x2C5*/ { "SMSG_ITEM_NAME_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2C6*/ { "SMSG_PET_ACTION_FEEDBACK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2C7*/ { "CMSG_CHAR_RENAME", STATUS_AUTHED, &WorldSession::HandleChangePlayerNameOpcode },
+ /*0x2C8*/ { "SMSG_CHAR_RENAME", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2C9*/ { "CMSG_MOVE_SPLINE_DONE", STATUS_LOGGEDIN, &WorldSession::HandleTaxiNextDestinationOpcode },
+ /*0x2CA*/ { "CMSG_MOVE_FALL_RESET", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x2CB*/ { "SMSG_INSTANCE_SAVE_CREATED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2CC*/ { "SMSG_RAID_INSTANCE_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2CD*/ { "CMSG_REQUEST_RAID_INFO", STATUS_LOGGEDIN, &WorldSession::HandleRequestRaidInfoOpcode },
+ /*0x2CE*/ { "CMSG_MOVE_TIME_SKIPPED", STATUS_LOGGEDIN, &WorldSession::HandleMoveTimeSkippedOpcode },
+ /*0x2CF*/ { "CMSG_MOVE_FEATHER_FALL_ACK", STATUS_LOGGEDIN, &WorldSession::HandleFeatherFallAck },
+ /*0x2D0*/ { "CMSG_MOVE_WATER_WALK_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveWaterWalkAck },
+ /*0x2D1*/ { "CMSG_MOVE_NOT_ACTIVE_MOVER", STATUS_LOGGEDIN, &WorldSession::HandleMoveNotActiveMover },
+ /*0x2D2*/ { "SMSG_PLAY_SOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2D3*/ { "CMSG_BATTLEFIELD_STATUS", STATUS_LOGGEDIN, &WorldSession::HandleBattlefieldStatusOpcode },
+ /*0x2D4*/ { "SMSG_BATTLEFIELD_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2D5*/ { "CMSG_BATTLEFIELD_PORT", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundPlayerPortOpcode},
+ /*0x2D6*/ { "MSG_INSPECT_HONOR_STATS", STATUS_LOGGEDIN, &WorldSession::HandleInspectHonorStatsOpcode },
+ /*0x2D7*/ { "CMSG_BATTLEMASTER_HELLO", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundHelloOpcode },
+ /*0x2D8*/ { "CMSG_MOVE_START_SWIM_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x2D9*/ { "CMSG_MOVE_STOP_SWIM_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x2DA*/ { "SMSG_FORCE_WALK_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2DB*/ { "CMSG_FORCE_WALK_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck },
+ /*0x2DC*/ { "SMSG_FORCE_SWIM_BACK_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2DD*/ { "CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck },
+ /*0x2DE*/ { "SMSG_FORCE_TURN_RATE_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2DF*/ { "CMSG_FORCE_TURN_RATE_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck },
+ /*0x2E0*/ { "MSG_PVP_LOG_DATA", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundPVPlogdataOpcode},
+ /*0x2E1*/ { "CMSG_LEAVE_BATTLEFIELD", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundLeaveOpcode },
+ /*0x2E2*/ { "CMSG_AREA_SPIRIT_HEALER_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleAreaSpiritHealerQueryOpcode},
+ /*0x2E3*/ { "CMSG_AREA_SPIRIT_HEALER_QUEUE", STATUS_LOGGEDIN, &WorldSession::HandleAreaSpiritHealerQueueOpcode},
+ /*0x2E4*/ { "SMSG_AREA_SPIRIT_HEALER_TIME", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2E5*/ { "CMSG_GM_UNTEACH", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x2E6*/ { "SMSG_WARDEN_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2E7*/ { "CMSG_WARDEN_DATA", STATUS_LOGGEDIN, &WorldSession::HandleWardenDataOpcode },
+ /*0x2E8*/ { "SMSG_GROUP_JOINED_BATTLEGROUND", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2E9*/ { "MSG_BATTLEGROUND_PLAYER_POSITIONS", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundPlayerPositionsOpcode},
+ /*0x2EA*/ { "CMSG_PET_STOP_ATTACK", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x2EB*/ { "SMSG_BINDER_CONFIRM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2EC*/ { "SMSG_BATTLEGROUND_PLAYER_JOINED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2ED*/ { "SMSG_BATTLEGROUND_PLAYER_LEFT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2EE*/ { "CMSG_BATTLEMASTER_JOIN", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundJoinOpcode },
+ /*0x2EF*/ { "SMSG_ADDON_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2F0*/ { "CMSG_PET_UNLEARN", STATUS_LOGGEDIN, &WorldSession::HandlePetUnlearnOpcode },
+ /*0x2F1*/ { "SMSG_PET_UNLEARN_CONFIRM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2F2*/ { "SMSG_PARTY_MEMBER_STATS_FULL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2F3*/ { "CMSG_PET_SPELL_AUTOCAST", STATUS_LOGGEDIN, &WorldSession::HandlePetSpellAutocastOpcode },
+ /*0x2F4*/ { "SMSG_WEATHER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2F5*/ { "SMSG_PLAY_TIME_WARNING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2F6*/ { "SMSG_MINIGAME_SETUP", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2F7*/ { "SMSG_MINIGAME_STATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2F8*/ { "CMSG_MINIGAME_MOVE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x2F9*/ { "SMSG_MINIGAME_MOVE_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2FA*/ { "SMSG_RAID_INSTANCE_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2FB*/ { "SMSG_COMPRESSED_MOVES", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2FC*/ { "CMSG_GUILD_INFO_TEXT", STATUS_LOGGEDIN, &WorldSession::HandleGuildChangeInfoOpcode },
+ /*0x2FD*/ { "SMSG_CHAT_RESTRICTED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2FE*/ { "SMSG_SPLINE_SET_RUN_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2FF*/ { "SMSG_SPLINE_SET_RUN_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x300*/ { "SMSG_SPLINE_SET_SWIM_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x301*/ { "SMSG_SPLINE_SET_WALK_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x302*/ { "SMSG_SPLINE_SET_SWIM_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x303*/ { "SMSG_SPLINE_SET_TURN_RATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x304*/ { "SMSG_SPLINE_MOVE_UNROOT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x305*/ { "SMSG_SPLINE_MOVE_FEATHER_FALL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x306*/ { "SMSG_SPLINE_MOVE_NORMAL_FALL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x307*/ { "SMSG_SPLINE_MOVE_SET_HOVER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x308*/ { "SMSG_SPLINE_MOVE_UNSET_HOVER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x309*/ { "SMSG_SPLINE_MOVE_WATER_WALK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x30A*/ { "SMSG_SPLINE_MOVE_LAND_WALK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x30B*/ { "SMSG_SPLINE_MOVE_START_SWIM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x30C*/ { "SMSG_SPLINE_MOVE_STOP_SWIM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x30D*/ { "SMSG_SPLINE_MOVE_SET_RUN_MODE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x30E*/ { "SMSG_SPLINE_MOVE_SET_WALK_MODE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x30F*/ { "CMSG_GM_NUKE_ACCOUNT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x310*/ { "MSG_GM_DESTROY_CORPSE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x311*/ { "CMSG_GM_DESTROY_ONLINE_CORPSE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x312*/ { "CMSG_ACTIVATETAXIEXPRESS", STATUS_LOGGEDIN, &WorldSession::HandleActivateTaxiFarOpcode },
+ /*0x313*/ { "SMSG_SET_FACTION_ATWAR", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x314*/ { "SMSG_GAMETIMEBIAS_SET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x315*/ { "CMSG_DEBUG_ACTIONS_START", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x316*/ { "CMSG_DEBUG_ACTIONS_STOP", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x317*/ { "CMSG_SET_FACTION_INACTIVE", STATUS_LOGGEDIN, &WorldSession::HandleSetWatchedFactionInactiveOpcode},
+ /*0x318*/ { "CMSG_SET_WATCHED_FACTION", STATUS_LOGGEDIN, &WorldSession::HandleSetWatchedFactionIndexOpcode},
+ /*0x319*/ { "MSG_MOVE_TIME_SKIPPED", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x31A*/ { "SMSG_SPLINE_MOVE_ROOT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x31B*/ { "CMSG_SET_EXPLORATION_ALL", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x31C*/ { "SMSG_INVALIDATE_PLAYER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x31D*/ { "CMSG_RESET_INSTANCES", STATUS_LOGGEDIN, &WorldSession::HandleResetInstancesOpcode },
+ /*0x31E*/ { "SMSG_INSTANCE_RESET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x31F*/ { "SMSG_INSTANCE_RESET_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x320*/ { "SMSG_UPDATE_LAST_INSTANCE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x321*/ { "MSG_RAID_TARGET_UPDATE", STATUS_LOGGEDIN, &WorldSession::HandleRaidIconTargetOpcode },
+ /*0x322*/ { "MSG_RAID_READY_CHECK", STATUS_LOGGEDIN, &WorldSession::HandleRaidReadyCheckOpcode },
+ /*0x323*/ { "CMSG_LUA_USAGE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x324*/ { "SMSG_PET_ACTION_SOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x325*/ { "SMSG_PET_DISMISS_SOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x326*/ { "SMSG_GHOSTEE_GONE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x327*/ { "CMSG_GM_UPDATE_TICKET_STATUS", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x328*/ { "SMSG_GM_TICKET_STATUS_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x329*/ { "MSG_SET_DUNGEON_DIFFICULTY", STATUS_LOGGEDIN, &WorldSession::HandleDungeonDifficultyOpcode },
+ /*0x32A*/ { "CMSG_GMSURVEY_SUBMIT", STATUS_NEVER, &WorldSession::Handle_NULL },//LOGGEDIN, &WorldSession::HandleGMSurveySubmit },
+ /*0x32B*/ { "SMSG_UPDATE_INSTANCE_OWNERSHIP", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x32C*/ { "CMSG_IGNORE_KNOCKBACK_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x32D*/ { "SMSG_CHAT_PLAYER_AMBIGUOUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x32E*/ { "MSG_DELAY_GHOST_TELEPORT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x32F*/ { "SMSG_SPELLINSTAKILLLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x330*/ { "SMSG_SPELL_UPDATE_CHAIN_TARGETS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x331*/ { "CMSG_CHAT_FILTERED", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x332*/ { "SMSG_EXPECTED_SPAM_RECORDS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x333*/ { "SMSG_SPELLSTEALLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x334*/ { "CMSG_LOTTERY_QUERY_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x335*/ { "SMSG_LOTTERY_QUERY_RESULT_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x336*/ { "CMSG_BUY_LOTTERY_TICKET_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x337*/ { "SMSG_LOTTERY_RESULT_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x338*/ { "SMSG_CHARACTER_PROFILE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x339*/ { "SMSG_CHARACTER_PROFILE_REALM_CONNECTED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x33A*/ { "SMSG_DEFENSE_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x33B*/ { "SMSG_INSTANCE_DIFFICULTY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x33C*/ { "MSG_GM_RESETINSTANCELIMIT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x33D*/ { "SMSG_MOTD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x33E*/ { "SMSG_MOVE_SET_FLIGHT_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x33F*/ { "SMSG_MOVE_UNSET_FLIGHT_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x340*/ { "CMSG_MOVE_FLIGHT_ACK_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x341*/ { "MSG_MOVE_START_SWIM_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x342*/ { "MSG_MOVE_STOP_SWIM_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x343*/ { "SMSG_MOVE_SET_CAN_FLY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x344*/ { "SMSG_MOVE_UNSET_CAN_FLY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x345*/ { "CMSG_MOVE_SET_CAN_FLY_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveFlyModeChangeAckOpcode},
+ /*0x346*/ { "CMSG_MOVE_SET_FLY", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x347*/ { "CMSG_SOCKET_GEMS", STATUS_LOGGEDIN, &WorldSession::HandleSocketOpcode },
+ /*0x348*/ { "CMSG_ARENA_TEAM_CREATE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x349*/ { "SMSG_ARENA_TEAM_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x34A*/ { "UMSG_UPDATE_ARENA_TEAM_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x34B*/ { "CMSG_ARENA_TEAM_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamQueryOpcode },
+ /*0x34C*/ { "SMSG_ARENA_TEAM_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x34D*/ { "CMSG_ARENA_TEAM_ROSTER", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamRosterOpcode },
+ /*0x34E*/ { "SMSG_ARENA_TEAM_ROSTER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x34F*/ { "CMSG_ARENA_TEAM_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamAddMemberOpcode },
+ /*0x350*/ { "SMSG_ARENA_TEAM_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x351*/ { "CMSG_ARENA_TEAM_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamInviteAcceptOpcode},
+ /*0x352*/ { "CMSG_ARENA_TEAM_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamInviteDeclineOpcode},
+ /*0x353*/ { "CMSG_ARENA_TEAM_LEAVE", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamLeaveOpcode },
+ /*0x354*/ { "CMSG_ARENA_TEAM_REMOVE", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamRemoveFromTeamOpcode},
+ /*0x355*/ { "CMSG_ARENA_TEAM_DISBAND", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamDisbandOpcode },
+ /*0x356*/ { "CMSG_ARENA_TEAM_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamPromoteToCaptainOpcode},
+ /*0x357*/ { "SMSG_ARENA_TEAM_EVENT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x358*/ { "CMSG_BATTLEMASTER_JOIN_ARENA", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundArenaJoin },
+ /*0x359*/ { "MSG_MOVE_START_ASCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x35A*/ { "MSG_MOVE_STOP_ASCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x35B*/ { "SMSG_ARENA_TEAM_STATS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x35C*/ { "CMSG_LFG_SET_AUTOJOIN", STATUS_AUTHED, &WorldSession::HandleLfgAutoJoinOpcode },
+ /*0x35D*/ { "CMSG_LFG_CLEAR_AUTOJOIN", STATUS_LOGGEDIN, &WorldSession::HandleLfgCancelAutoJoinOpcode },
+ /*0x35E*/ { "CMSG_LFM_SET_AUTOFILL", STATUS_AUTHED, &WorldSession::HandleLfmAutoAddMembersOpcode },
+ /*0x35F*/ { "CMSG_LFM_CLEAR_AUTOFILL", STATUS_LOGGEDIN, &WorldSession::HandleLfmCancelAutoAddmembersOpcode},
+ /*0x360*/ { "CMSG_ACCEPT_LFG_MATCH", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x361*/ { "CMSG_DECLINE_LFG_MATCH", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x362*/ { "CMSG_CANCEL_PENDING_LFG", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x363*/ { "CMSG_CLEAR_LOOKING_FOR_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleLfgClearOpcode },
+ /*0x364*/ { "CMSG_CLEAR_LOOKING_FOR_MORE", STATUS_LOGGEDIN, &WorldSession::HandleLfmSetNoneOpcode },
+ /*0x365*/ { "CMSG_SET_LOOKING_FOR_MORE", STATUS_LOGGEDIN, &WorldSession::HandleLfmSetOpcode },
+ /*0x366*/ { "CMSG_SET_LFG_COMMENT", STATUS_LOGGEDIN, &WorldSession::HandleLfgSetCommentOpcode },
+ /*0x367*/ { "SMSG_LFG_TIMEDOUT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x368*/ { "SMSG_LFG_OTHER_TIMEDOUT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x369*/ { "SMSG_LFG_AUTOJOIN_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x36A*/ { "SMSG_LFG_AUTOJOIN_FAILED_NO_PLAYER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x36B*/ { "SMSG_LFG_LEADER_IS_LFM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x36C*/ { "SMSG_LFG_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x36D*/ { "SMSG_LFG_UPDATE_LFM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x36E*/ { "SMSG_LFG_UPDATE_LFG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x36F*/ { "SMSG_LFG_UPDATE_QUEUED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x370*/ { "SMSG_LFG_PENDING_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x371*/ { "SMSG_LFG_PENDING_MATCH", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x372*/ { "SMSG_LFG_PENDING_MATCH_DONE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x373*/ { "SMSG_TITLE_EARNED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x374*/ { "CMSG_SET_TITLE", STATUS_LOGGEDIN, &WorldSession::HandleChooseTitleOpcode },
+ /*0x375*/ { "CMSG_CANCEL_MOUNT_AURA", STATUS_LOGGEDIN, &WorldSession::HandleDismountOpcode },
+ /*0x376*/ { "SMSG_ARENA_ERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x377*/ { "MSG_INSPECT_ARENA_TEAMS", STATUS_LOGGEDIN, &WorldSession::HandleInspectArenaStatsOpcode },
+ /*0x378*/ { "SMSG_DEATH_RELEASE_LOC", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x379*/ { "CMSG_CANCEL_TEMP_ENCHANTMENT", STATUS_LOGGEDIN, &WorldSession::HandleCancelTempItemEnchantmentOpcode},
+ /*0x37A*/ { "SMSG_FORCED_DEATH_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x37B*/ { "CMSG_CHEAT_SET_HONOR_CURRENCY", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x37C*/ { "CMSG_CHEAT_SET_ARENA_CURRENCY", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x37D*/ { "MSG_MOVE_SET_FLIGHT_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x37E*/ { "MSG_MOVE_SET_FLIGHT_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x37F*/ { "MSG_MOVE_SET_FLIGHT_BACK_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x380*/ { "MSG_MOVE_SET_FLIGHT_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x381*/ { "SMSG_FORCE_FLIGHT_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x382*/ { "CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck },
+ /*0x383*/ { "SMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x384*/ { "CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck },
+ /*0x385*/ { "SMSG_SPLINE_SET_FLIGHT_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x386*/ { "SMSG_SPLINE_SET_FLIGHT_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x387*/ { "CMSG_MAELSTROM_INVALIDATE_CACHE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x388*/ { "SMSG_FLIGHT_SPLINE_SYNC", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x389*/ { "CMSG_SET_TAXI_BENCHMARK_MODE", STATUS_AUTHED, &WorldSession::HandleSetTaxiBenchmarkOpcode },
+ /*0x38A*/ { "SMSG_JOINED_BATTLEGROUND_QUEUE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x38B*/ { "SMSG_REALM_SPLIT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x38C*/ { "CMSG_REALM_SPLIT", STATUS_AUTHED, &WorldSession::HandleRealmStateRequestOpcode },
+ /*0x38D*/ { "CMSG_MOVE_CHNG_TRANSPORT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x38E*/ { "MSG_PARTY_ASSIGNMENT", STATUS_LOGGEDIN, &WorldSession::HandleGroupPromoteOpcode },
+ /*0x38F*/ { "SMSG_OFFER_PETITION_ERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x390*/ { "SMSG_TIME_SYNC_REQ", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x391*/ { "CMSG_TIME_SYNC_RESP", STATUS_LOGGEDIN, &WorldSession::HandleTimeSyncResp },
+ /*0x392*/ { "CMSG_SEND_LOCAL_EVENT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x393*/ { "CMSG_SEND_GENERAL_TRIGGER", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x394*/ { "CMSG_SEND_COMBAT_TRIGGER", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x395*/ { "CMSG_MAELSTROM_GM_SENT_MAIL", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x396*/ { "SMSG_RESET_FAILED_NOTIFY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x397*/ { "SMSG_REAL_GROUP_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x398*/ { "SMSG_LFG_DISABLED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x399*/ { "CMSG_ACTIVE_PVP_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x39A*/ { "CMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x39B*/ { "SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x39C*/ { "SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE_WRITE_FILE",STATUS_NEVER,&WorldSession::Handle_ServerSide },
+ /*0x39D*/ { "SMSG_UPDATE_COMBO_POINTS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x39E*/ { "SMSG_VOICE_SESSION_ROSTER_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x39F*/ { "SMSG_VOICE_SESSION_LEAVE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3A0*/ { "SMSG_VOICE_SESSION_ADJUST_PRIORITY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3A1*/ { "CMSG_VOICE_SET_TALKER_MUTED_REQUEST", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3A2*/ { "SMSG_VOICE_SET_TALKER_MUTED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3A3*/ { "SMSG_INIT_EXTRA_AURA_INFO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3A4*/ { "SMSG_SET_EXTRA_AURA_INFO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3A5*/ { "SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE_OBSOLETE",STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3A6*/ { "SMSG_CLEAR_EXTRA_AURA_INFO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3A7*/ { "MSG_MOVE_START_DESCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
+ /*0x3A8*/ { "CMSG_IGNORE_REQUIREMENTS_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3A9*/ { "SMSG_IGNORE_REQUIREMENTS_CHEAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3AA*/ { "SMSG_SPELL_CHANCE_PROC_LOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3AB*/ { "CMSG_MOVE_SET_RUN_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3AC*/ { "SMSG_DISMOUNT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3AD*/ { "MSG_MOVE_UPDATE_CAN_FLY", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3AE*/ { "MSG_RAID_READY_CHECK_CONFIRM", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3AF*/ { "CMSG_VOICE_SESSION_ENABLE", STATUS_AUTHED, &WorldSession::HandleVoiceSettingsOpcode },
+ /*0x3B0*/ { "SMSG_VOICE_SESSION_ENABLE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3B1*/ { "SMSG_VOICE_PARENTAL_CONTROLS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3B2*/ { "CMSG_GM_WHISPER", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3B3*/ { "SMSG_GM_MESSAGECHAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3B4*/ { "MSG_GM_GEARRATING", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3B5*/ { "CMSG_COMMENTATOR_ENABLE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3B6*/ { "SMSG_COMMENTATOR_STATE_CHANGED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3B7*/ { "CMSG_COMMENTATOR_GET_MAP_INFO", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3B8*/ { "SMSG_COMMENTATOR_MAP_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3B9*/ { "CMSG_COMMENTATOR_GET_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3BA*/ { "SMSG_COMMENTATOR_GET_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3BB*/ { "SMSG_COMMENTATOR_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3BC*/ { "CMSG_COMMENTATOR_ENTER_INSTANCE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3BD*/ { "CMSG_COMMENTATOR_EXIT_INSTANCE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3BE*/ { "CMSG_COMMENTATOR_INSTANCE_COMMAND", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3BF*/ { "SMSG_CLEAR_TARGET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3C0*/ { "CMSG_BOT_DETECTED", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3C1*/ { "SMSG_CROSSED_INEBRIATION_THRESHOLD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3C2*/ { "CMSG_CHEAT_PLAYER_LOGIN", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3C3*/ { "CMSG_CHEAT_PLAYER_LOOKUP", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3C4*/ { "SMSG_CHEAT_PLAYER_LOOKUP", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3C5*/ { "SMSG_KICK_REASON", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3C6*/ { "MSG_RAID_READY_CHECK_FINISHED", STATUS_LOGGEDIN, &WorldSession::HandleRaidReadyCheckFinishOpcode},
+ /*0x3C7*/ { "CMSG_COMPLAIN", STATUS_LOGGEDIN, &WorldSession::HandleReportSpamOpcode },
+ /*0x3C8*/ { "SMSG_COMPLAIN_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3C9*/ { "SMSG_FEATURE_SYSTEM_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3CA*/ { "CMSG_GM_SHOW_COMPLAINTS", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3CB*/ { "CMSG_GM_UNSQUELCH", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3CC*/ { "CMSG_CHANNEL_SILENCE_VOICE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3CD*/ { "CMSG_CHANNEL_SILENCE_ALL", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3CE*/ { "CMSG_CHANNEL_UNSILENCE_VOICE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3CF*/ { "CMSG_CHANNEL_UNSILENCE_ALL", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3D0*/ { "CMSG_TARGET_CAST", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3D1*/ { "CMSG_TARGET_SCRIPT_CAST", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3D2*/ { "CMSG_CHANNEL_DISPLAY_LIST", STATUS_LOGGEDIN, &WorldSession::HandleChannelRosterQuery },
+ /*0x3D3*/ { "CMSG_SET_ACTIVE_VOICE_CHANNEL", STATUS_AUTHED, &WorldSession::HandleChannelVoiceChatQuery },
+ /*0x3D4*/ { "CMSG_GET_CHANNEL_MEMBER_COUNT", STATUS_LOGGEDIN, &WorldSession::HandleChannelInfoQuery },
+ /*0x3D5*/ { "SMSG_CHANNEL_MEMBER_COUNT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3D6*/ { "CMSG_CHANNEL_VOICE_ON", STATUS_LOGGEDIN, &WorldSession::HandleChannelEnableVoiceOpcode },
+ /*0x3D7*/ { "CMSG_CHANNEL_VOICE_OFF", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3D8*/ { "CMSG_DEBUG_LIST_TARGETS", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3D9*/ { "SMSG_DEBUG_LIST_TARGETS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3DA*/ { "SMSG_AVAILABLE_VOICE_CHANNEL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3DB*/ { "CMSG_ADD_VOICE_IGNORE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3DC*/ { "CMSG_DEL_VOICE_IGNORE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3DD*/ { "CMSG_PARTY_SILENCE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3DE*/ { "CMSG_PARTY_UNSILENCE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3DF*/ { "MSG_NOTIFY_PARTY_SQUELCH", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3E0*/ { "SMSG_COMSAT_RECONNECT_TRY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3E1*/ { "SMSG_COMSAT_DISCONNECT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3E2*/ { "SMSG_COMSAT_CONNECT_FAIL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3E3*/ { "SMSG_VOICE_CHAT_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3E4*/ { "CMSG_REPORT_PVP_AFK", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundReportAFK },
+ /*0x3E5*/ { "CMSG_REPORT_PVP_AFK_RESULT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3E6*/ { "CMSG_GUILD_BANKER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankQuery },
+ /*0x3E7*/ { "CMSG_GUILD_BANK_QUERY_TAB", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankTabColon },
+ /*0x3E8*/ { "SMSG_GUILD_BANK_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3E9*/ { "CMSG_GUILD_BANK_SWAP_ITEMS", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankDepositItem },
+ /*0x3EA*/ { "CMSG_GUILD_BANK_BUY_TAB", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankBuyTab },
+ /*0x3EB*/ { "CMSG_GUILD_BANK_UPDATE_TAB", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankModifyTab },
+ /*0x3EC*/ { "CMSG_GUILD_BANK_DEPOSIT_MONEY", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankDeposit },
+ /*0x3ED*/ { "CMSG_GUILD_BANK_WITHDRAW_MONEY", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankWithdraw },
+ /*0x3EE*/ { "MSG_GUILD_BANK_LOG_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankLog },
+ /*0x3EF*/ { "CMSG_SET_CHANNEL_WATCH", STATUS_LOGGEDIN, &WorldSession::HandleChannelJoinNotify },
+ /*0x3F0*/ { "SMSG_USERLIST_ADD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3F1*/ { "SMSG_USERLIST_REMOVE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3F2*/ { "SMSG_USERLIST_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3F3*/ { "CMSG_CLEAR_CHANNEL_WATCH", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3F4*/ { "SMSG_INSPECT_TALENT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3F5*/ { "SMSG_GOGOGO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3F6*/ { "SMSG_ECHO_PARTY_SQUELCH", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3F7*/ { "CMSG_SET_TITLE_SUFFIX", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3F8*/ { "CMSG_SPELLCLICK", STATUS_LOGGEDIN, &WorldSession::HandleSpellClick },
+ /*0x3F9*/ { "SMSG_LOOT_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3FA*/ { "CMSG_GM_CHARACTER_RESTORE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3FB*/ { "CMSG_GM_CHARACTER_SAVE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x3FC*/ { "SMSG_VOICESESSION_FULL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x3FD*/ { "MSG_GUILD_PERMISSIONS", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankGetRights },
+ /*0x3FE*/ { "MSG_GUILD_BANK_MONEY_WITHDRAWN", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankGetMoneyAmount },
+ /*0x3FF*/ { "MSG_GUILD_EVENT_LOG_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleGuildEventLogOpcode },
+ /*0x400*/ { "CMSG_MAELSTROM_RENAME_GUILD", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x401*/ { "CMSG_GET_MIRRORIMAGE_DATA", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x402*/ { "SMSG_MIRRORIMAGE_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x403*/ { "SMSG_FORCE_DISPLAY_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x404*/ { "SMSG_SPELL_CHANCE_RESIST_PUSHBACK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x405*/ { "CMSG_IGNORE_DIMINISHING_RETURNS_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x406*/ { "SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x407*/ { "CMSG_KEEP_ALIVE", STATUS_NEVER, &WorldSession::Handle_EarlyProccess },
+ /*0x408*/ { "SMSG_RAID_READY_CHECK_ERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x409*/ { "CMSG_OPT_OUT_OF_LOOT", STATUS_AUTHED, &WorldSession::HandleGroupPassOnLootOpcode },
+ /*0x40A*/ { "MSG_QUERY_GUILD_BANK_TEXT", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankTabText },
+ /*0x40B*/ { "CMSG_SET_GUILD_BANK_TEXT", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankSetTabText },
+ /*0x40C*/ { "CMSG_SET_GRANTABLE_LEVELS", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x40D*/ { "CMSG_GRANT_LEVEL", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x40E*/ { "CMSG_REFER_A_FRIEND", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x40F*/ { "CMSG_DECLINE_CHANNEL_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleChannelDeclineInvite },
- /*0x410*/ { "CMSG_GROUPACTION_THROTTLED", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x411*/ { "SMSG_OVERRIDE_LIGHT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x412*/ { "SMSG_TOTEM_CREATED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x413*/ { "CMSG_TOTEM_DESTROYED", STATUS_LOGGEDIN, &WorldSession::HandleTotemDestroy },
- /*0x414*/ { "CMSG_EXPIRE_RAID_INSTANCE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x415*/ { "CMSG_NO_SPELL_VARIANCE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x416*/ { "CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY",STATUS_LOGGEDIN,&WorldSession::HandleQuestgiverStatusQueryMultipleOpcode},
- /*0x417*/ { "SMSG_QUESTGIVER_STATUS_MULTIPLE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x418*/ { "CMSG_SET_PLAYER_DECLINED_NAMES", STATUS_AUTHED, &WorldSession::HandleDeclinedPlayerNameOpcode },
- /*0x419*/ { "SMSG_SET_PLAYER_DECLINED_NAMES_RESULT",STATUS_NEVER,&WorldSession::Handle_ServerSide },
- /*0x41A*/ { "CMSG_QUERY_SERVER_BUCK_DATA", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x41B*/ { "CMSG_CLEAR_SERVER_BUCK_DATA", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x41C*/ { "SMSG_SERVER_BUCK_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x41D*/ { "SMSG_SEND_UNLEARN_SPELLS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x41E*/ { "SMSG_PROPOSE_LEVEL_GRANT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x41F*/ { "CMSG_ACCEPT_LEVEL_GRANT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x420*/ { "SMSG_REFER_A_FRIEND_FAILURE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x421*/ { "SMSG_SPLINE_MOVE_SET_FLYING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x422*/ { "SMSG_SPLINE_MOVE_UNSET_FLYING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x423*/ { "SMSG_SUMMON_CANCEL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x410*/ { "CMSG_DECLINE_CHANNEL_INVITE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x411*/ { "CMSG_GROUPACTION_THROTTLED", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x412*/ { "SMSG_OVERRIDE_LIGHT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x413*/ { "SMSG_TOTEM_CREATED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x414*/ { "CMSG_TOTEM_DESTROYED", STATUS_LOGGEDIN, &WorldSession::HandleTotemDestroy },
+ /*0x415*/ { "CMSG_EXPIRE_RAID_INSTANCE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x416*/ { "CMSG_NO_SPELL_VARIANCE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x417*/ { "CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverStatusQueryMultipleOpcode},
+ /*0x418*/ { "SMSG_QUESTGIVER_STATUS_MULTIPLE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x419*/ { "CMSG_SET_PLAYER_DECLINED_NAMES", STATUS_AUTHED, &WorldSession::HandleDeclinedPlayerNameOpcode },
+ /*0x41A*/ { "SMSG_SET_PLAYER_DECLINED_NAMES_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x41B*/ { "CMSG_QUERY_SERVER_BUCK_DATA", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x41C*/ { "CMSG_CLEAR_SERVER_BUCK_DATA", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x41D*/ { "SMSG_SERVER_BUCK_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x41E*/ { "SMSG_SEND_UNLEARN_SPELLS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x41F*/ { "SMSG_PROPOSE_LEVEL_GRANT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x420*/ { "CMSG_ACCEPT_LEVEL_GRANT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x421*/ { "SMSG_REFER_A_FRIEND_FAILURE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x422*/ { "SMSG_SPLINE_MOVE_SET_FLYING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x423*/ { "SMSG_SPLINE_MOVE_UNSET_FLYING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x424*/ { "SMSG_SUMMON_CANCEL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x425*/ { "CMSG_CHANGE_PERSONAL_ARENA_RATING", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x426*/ { "CMSG_ALTER_APPEARANCE", STATUS_LOGGEDIN, &WorldSession::HandleAlterAppearance },
+ /*0x427*/ { "SMSG_ENABLE_BARBER_SHOP", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x428*/ { "SMSG_BARBER_SHOP_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x429*/ { "CMSG_CALENDAR_GET_CALENDAR", STATUS_LOGGEDIN, &WorldSession::HandleCalendarGetCalendar },
+ /*0x42A*/ { "CMSG_CALENDAR_GET_EVENT", STATUS_LOGGEDIN, &WorldSession::HandleCalendarGetEvent },
+ /*0x42B*/ { "CMSG_CALENDAR_GUILD_FILTER", STATUS_LOGGEDIN, &WorldSession::HandleCalendarGuildFilter },
+ /*0x42C*/ { "CMSG_CALENDAR_ARENA_TEAM", STATUS_LOGGEDIN, &WorldSession::HandleCalendarArenaTeam },
+ /*0x42D*/ { "CMSG_CALENDAR_ADD_EVENT", STATUS_LOGGEDIN, &WorldSession::HandleCalendarAddEvent },
+ /*0x42E*/ { "CMSG_CALENDAR_UPDATE_EVENT", STATUS_LOGGEDIN, &WorldSession::HandleCalendarUpdateEvent },
+ /*0x42F*/ { "CMSG_CALENDAR_REMOVE_EVENT", STATUS_LOGGEDIN, &WorldSession::HandleCalendarRemoveEvent },
+ /*0x430*/ { "CMSG_CALENDAR_COPY_EVENT", STATUS_LOGGEDIN, &WorldSession::HandleCalendarCopyEvent },
+ /*0x431*/ { "CMSG_CALENDAR_EVENT_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleCalendarEventInvite },
+ /*0x432*/ { "CMSG_CALENDAR_EVENT_RSVP", STATUS_LOGGEDIN, &WorldSession::HandleCalendarEventRsvp },
+ /*0x433*/ { "CMSG_CALENDAR_EVENT_REMOVE_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleCalendarEventRemoveInvite },
+ /*0x434*/ { "CMSG_CALENDAR_EVENT_STATUS", STATUS_LOGGEDIN, &WorldSession::HandleCalendarEventStatus },
+ /*0x435*/ { "CMSG_CALENDAR_EVENT_MODERATOR_STATUS", STATUS_LOGGEDIN, &WorldSession::HandleCalendarEventModeratorStatus},
+ /*0x436*/ { "SMSG_CALENDAR_SEND_CALENDAR", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x437*/ { "SMSG_CALENDAR_SEND_EVENT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x438*/ { "SMSG_CALENDAR_FILTER_GUILD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x439*/ { "SMSG_CALENDAR_ARENA_TEAM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x43A*/ { "SMSG_CALENDAR_EVENT_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x43B*/ { "SMSG_CALENDAR_EVENT_INVITE_REMOVED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x43C*/ { "SMSG_CALENDAR_EVENT_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x43D*/ { "SMSG_CALENDAR_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x43E*/ { "SMSG_CALENDAR_RAID_LOCKOUT_ADDED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x43F*/ { "SMSG_CALENDAR_RAID_LOCKOUT_REMOVED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x440*/ { "SMSG_CALENDAR_EVENT_INVITE_ALERT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x441*/ { "SMSG_CALENDAR_EVENT_INVITE_REMOVED_ALERT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x442*/ { "SMSG_CALENDAR_EVENT_INVITE_STATUS_ALERT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x443*/ { "SMSG_CALENDAR_EVENT_REMOVED_ALERT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x444*/ { "SMSG_CALENDAR_EVENT_UPDATED_ALERT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x445*/ { "SMSG_CALENDAR_EVENT_MODERATOR_STATUS_ALERT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x446*/ { "CMSG_CALENDAR_COMPLAIN", STATUS_LOGGEDIN, &WorldSession::HandleCalendarComplain },
+ /*0x447*/ { "CMSG_CALENDAR_GET_NUM_PENDING", STATUS_LOGGEDIN, &WorldSession::HandleCalendarGetNumPending },
+ /*0x448*/ { "SMSG_CALENDAR_SEND_NUM_PENDING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x449*/ { "CMSG_SAVE_DANCE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x44A*/ { "SMSG_NOTIFY_DANCE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x44B*/ { "CMSG_PLAY_DANCE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x44C*/ { "SMSG_PLAY_DANCE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x44D*/ { "CMSG_LOAD_DANCES", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x44E*/ { "CMSG_STOP_DANCE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x44F*/ { "SMSG_STOP_DANCE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x450*/ { "CMSG_SYNC_DANCE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x451*/ { "CMSG_DANCE_QUERY", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x452*/ { "SMSG_DANCE_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x453*/ { "SMSG_INVALIDATE_DANCE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x454*/ { "CMSG_DELETE_DANCE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x455*/ { "SMSG_LEARNED_DANCE_MOVES", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x456*/ { "CMSG_LEARN_DANCE_MOVE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x457*/ { "CMSG_UNLEARN_DANCE_MOVE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x458*/ { "CMSG_SET_RUNE_COUNT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x459*/ { "CMSG_SET_RUNE_COOLDOWN", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x45A*/ { "MSG_MOVE_SET_PITCH_RATE_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x45B*/ { "MSG_MOVE_SET_PITCH_RATE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x45C*/ { "SMSG_FORCE_PITCH_RATE_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x45D*/ { "CMSG_FORCE_PITCH_RATE_CHANGE_ACK", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x45E*/ { "SMSG_SPLINE_SET_PITCH_RATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x45F*/ { "SMSG_MOVE_ABANDON_TRANSPORT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x460*/ { "MSG_MOVE_ABANDON_TRANSPORT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x461*/ { "CMSG_MOVE_ABANDON_TRANSPORT_ACK", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x462*/ { "CMSG_UPDATE_MISSILE_TRAJECTORY", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x463*/ { "SMSG_UPDATE_ACCOUNT_DATA_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x464*/ { "SMSG_TRIGGER_MOVIE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x465*/ { "CMSG_COMPLETE_MOVIE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x466*/ { "CMSG_SET_GLYPH_SLOT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x467*/ { "CMSG_SET_GLYPH", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x468*/ { "SMSG_ACHIEVEMENT_EARNED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x469*/ { "SMSG_DYNAMIC_DROP_ROLL_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x46A*/ { "SMSG_CRITERIA_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x46B*/ { "CMSG_QUERY_INSPECT_ACHIEVEMENTS", STATUS_LOGGEDIN, &WorldSession::HandleInspectAchievements },
+ /*0x46C*/ { "SMSG_RESPOND_INSPECT_ACHIEVEMENTS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x46D*/ { "CMSG_DISMISS_CONTROLLED_VEHICLE", STATUS_LOGGEDIN, &WorldSession::HandleDismissControlledVehicle },
+ /*0x46E*/ { "CMSG_COMPLETE_ACHIEVEMENT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x46F*/ { "SMSG_QUESTUPDATE_ADD_PVP_KILL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x470*/ { "CMSG_SET_CRITERIA_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x471*/ { "SMSG_GROUP_SWAP_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x472*/ { "CMSG_UNITANIMTIER_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x473*/ { "CMSG_CHAR_CUSTOMIZE", STATUS_AUTHED, &WorldSession::HandleCharCustomize },
+ /*0x474*/ { "SMSG_CHAR_CUSTOMIZE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x475*/ { "SMSG_PET_RENAMEABLE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x476*/ { "CMSG_REQUEST_VEHICLE_EXIT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x477*/ { "CMSG_REQUEST_VEHICLE_PREV_SEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x478*/ { "CMSG_REQUEST_VEHICLE_NEXT_SEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x479*/ { "CMSG_REQUEST_VEHICLE_SWITCH_SEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x47A*/ { "CMSG_PET_LEARN_TALENT", STATUS_LOGGEDIN, &WorldSession::HandlePetLearnTalent },
+ /*0x47B*/ { "CMSG_PET_UNLEARN_TALENTS", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x47C*/ { "SMSG_SET_PHASE_SHIFT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x47D*/ { "SMSG_ALL_ACHIEVEMENT_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x47E*/ { "CMSG_FORCE_SAY_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x47F*/ { "SMSG_HEALTH_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x480*/ { "SMSG_POWER_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x481*/ { "CMSG_GAMEOBJ_REPORT_USE", STATUS_LOGGEDIN, &WorldSession::HandleGameobjectReportUse },
+ /*0x482*/ { "SMSG_HIGHEST_THREAT_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x483*/ { "SMSG_THREAT_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x484*/ { "SMSG_THREAT_REMOVE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x485*/ { "SMSG_THREAT_CLEAR", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x486*/ { "SMSG_CONVERT_RUNE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x487*/ { "SMSG_RESYNC_RUNES", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x488*/ { "SMSG_ADD_RUNE_POWER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x489*/ { "CMSG_START_QUEST", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x48A*/ { "CMSG_REMOVE_GLYPH", STATUS_LOGGEDIN, &WorldSession::HandleRemoveGlyph },
+ /*0x48B*/ { "CMSG_DUMP_OBJECTS", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x48C*/ { "SMSG_DUMP_OBJECTS_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x48D*/ { "CMSG_DISMISS_CRITTER", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x48E*/ { "SMSG_NOTIFY_DEST_LOC_SPELL_CAST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x48F*/ { "CMSG_AUCTION_LIST_PENDING_SALES", STATUS_LOGGEDIN, &WorldSession::HandleAuctionListPendingSales },
+ /*0x490*/ { "SMSG_AUCTION_LIST_PENDING_SALES", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x491*/ { "SMSG_MODIFY_COOLDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x492*/ { "SMSG_PET_UPDATE_COMBO_POINTS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x493*/ { "CMSG_ENABLETAXI", STATUS_LOGGEDIN, &WorldSession::HandleTaxiQueryAvailableNodes },
+ /*0x494*/ { "SMSG_PRE_RESURRECT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x495*/ { "SMSG_AURA_UPDATE_ALL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x496*/ { "SMSG_AURA_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x497*/ { "CMSG_FLOOD_GRACE_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x498*/ { "SMSG_SERVER_FIRST_ACHIEVEMENT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x499*/ { "SMSG_PET_LEARNED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x49A*/ { "SMSG_PET_REMOVED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x49B*/ { "CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x49C*/ { "CMSG_HEARTH_AND_RESURRECT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x49D*/ { "SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x49E*/ { "SMSG_CRITERIA_DELETED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x49F*/ { "SMSG_ACHIEVEMENT_DELETED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4A0*/ { "CMSG_SERVER_INFO_QUERY", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4A1*/ { "SMSG_SERVER_INFO_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4A2*/ { "CMSG_CHECK_LOGIN_CRITERIA", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4A3*/ { "SMSG_SERVER_BUCK_DATA_START", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4A4*/ { "CMSG_QUERY_VEHICLE_STATUS", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4A5*/ { "SMSG_PET_GUIDS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4A6*/ { "SMSG_CLIENTCACHE_VERSION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4A7*/ { "UMSG_UNKNOWN_1191", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4A8*/ { "UMSG_UNKNOWN_1192", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4A9*/ { "UMSG_UNKNOWN_1193", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4AA*/ { "UMSG_UNKNOWN_1194", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4AB*/ { "UMSG_UNKNOWN_1195", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4AC*/ { "UMSG_UNKNOWN_1196", STATUS_NEVER, &WorldSession::Handle_NULL },
};
diff --git a/src/game/Opcodes.h b/src/game/Opcodes.h
index 202166a57a0..2eb5d2d2920 100644
--- a/src/game/Opcodes.h
+++ b/src/game/Opcodes.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -49,8 +49,8 @@ enum Opcodes
CMSG_ZONE_MAP = 0x00A,
SMSG_ZONE_MAP = 0x00B,
CMSG_DEBUG_CHANGECELLZONE = 0x00C,
- CMSG_EMBLAZON_TABARD_OBSOLETE = 0x00D,
- CMSG_UNEMBLAZON_TABARD_OBSOLETE = 0x00E,
+ CMSG_MOVE_CHARACTER_CHEAT = 0x00D,
+ SMSG_MOVE_CHARACTER_CHEAT = 0x00E,
CMSG_RECHARGE = 0x00F,
CMSG_LEARN_SPELL = 0x010,
CMSG_CREATEMONSTER = 0x011,
@@ -66,7 +66,7 @@ enum Opcodes
SMSG_FORCEACTIONSHOW = 0x01B,
CMSG_PETGODMODE = 0x01C,
SMSG_PETGODMODE = 0x01D,
- SMSG_DEBUGINFOSPELLMISS_OBSOLETE = 0x01E,
+ SMSG_REFER_A_FRIEND_EXPIRED = 0x01E,
CMSG_WEATHER_SPEED_CHEAT = 0x01F,
CMSG_UNDRESSPLAYER = 0x020,
CMSG_BEASTMASTER = 0x021,
@@ -86,7 +86,7 @@ enum Opcodes
SMSG_DEBUG_AISTATE = 0x02F,
CMSG_DISABLE_PVP_CHEAT = 0x030,
CMSG_ADVANCE_SPAWN_TIME = 0x031,
- CMSG_PVP_PORT_OBSOLETE = 0x032,
+ SMSG_DESTRUCTIBLE_BUILDING_DAMAGE = 0x032,
CMSG_AUTH_SRP6_BEGIN = 0x033,
CMSG_AUTH_SRP6_PROOF = 0x034,
CMSG_AUTH_SRP6_RECODE = 0x035,
@@ -214,7 +214,7 @@ enum Opcodes
SMSG_READ_ITEM_FAILED = 0x0AF,
SMSG_ITEM_COOLDOWN = 0x0B0,
CMSG_GAMEOBJ_USE = 0x0B1,
- CMSG_GAMEOBJ_CHAIR_USE_OBSOLETE = 0x0B2,
+ CMSG_DESTROY_ITEMS = 0x0B2,
SMSG_GAMEOBJECT_CUSTOM_ANIM = 0x0B3,
CMSG_AREATRIGGER = 0x0B4,
MSG_MOVE_START_FORWARD = 0x0B5,
@@ -347,7 +347,7 @@ enum Opcodes
SMSG_SPELL_COOLDOWN = 0x134,
SMSG_COOLDOWN_EVENT = 0x135,
CMSG_CANCEL_AURA = 0x136,
- SMSG_UPDATE_AURA_DURATION = 0x137,
+ SMSG_UPDATE_AURA_DURATION_OBSOLETE = 0x137,
SMSG_PET_CAST_FAILED = 0x138,
MSG_CHANNEL_START = 0x139,
MSG_CHANNEL_UPDATE = 0x13A,
@@ -371,10 +371,10 @@ enum Opcodes
SMSG_DAMAGE_DONE_OBSOLETE = 0x14C,
SMSG_DAMAGE_TAKEN_OBSOLETE = 0x14D,
SMSG_CANCEL_COMBAT = 0x14E,
- SMSG_PLAYER_COMBAT_XP_GAIN_OBSOLETE = 0x14F,
+ SMSG_SPELLBREAKLOG = 0x14F,
SMSG_SPELLHEALLOG = 0x150,
SMSG_SPELLENERGIZELOG = 0x151,
- CMSG_SHEATHE_OBSOLETE = 0x152,
+ SMSG_BREAK_TARGET = 0x152,
CMSG_SAVE_PLAYER = 0x153,
CMSG_SETDEATHBINDPOINT = 0x154,
SMSG_BINDPOINTUPDATE = 0x155,
@@ -578,7 +578,7 @@ enum Opcodes
SMSG_GMTICKET_SYSTEMSTATUS = 0x21B,
CMSG_SPIRIT_HEALER_ACTIVATE = 0x21C,
CMSG_SET_STAT_CHEAT = 0x21D,
- SMSG_SET_REST_START = 0x21E,
+ SMSG_SET_REST_START_OBSOLETE = 0x21E,
CMSG_SKILL_BUY_STEP = 0x21F,
CMSG_SKILL_BUY_RANK = 0x220,
CMSG_XP_CHEAT = 0x221,
@@ -733,8 +733,8 @@ enum Opcodes
SMSG_SCRIPT_MESSAGE = 0x2B6,
SMSG_DUEL_COUNTDOWN = 0x2B7,
SMSG_AREA_TRIGGER_MESSAGE = 0x2B8,
- CMSG_TOGGLE_HELM = 0x2B9,
- CMSG_TOGGLE_CLOAK = 0x2BA,
+ CMSG_SHOWING_HELM = 0x2B9,
+ CMSG_SHOWING_CLOAK = 0x2BA,
SMSG_MEETINGSTONE_JOINFAILED = 0x2BB,
SMSG_PLAYER_SKINNED = 0x2BC,
SMSG_DURABILITY_DAMAGE_DEATH = 0x2BD,
@@ -967,10 +967,10 @@ enum Opcodes
SMSG_VOICE_SESSION_ADJUST_PRIORITY = 0x3A0,
CMSG_VOICE_SET_TALKER_MUTED_REQUEST = 0x3A1,
SMSG_VOICE_SET_TALKER_MUTED = 0x3A2,
- SMSG_INIT_EXTRA_AURA_INFO = 0x3A3,
- SMSG_SET_EXTRA_AURA_INFO = 0x3A4,
- SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE = 0x3A5,
- SMSG_CLEAR_EXTRA_AURA_INFO = 0x3A6,
+ 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,
@@ -980,127 +980,262 @@ enum Opcodes
MSG_MOVE_UPDATE_CAN_FLY = 0x3AD,
MSG_RAID_READY_CHECK_CONFIRM = 0x3AE,
CMSG_VOICE_SESSION_ENABLE = 0x3AF,
- SMSG_VOICE_PARENTAL_CONTROLS = 0x3B0,
- CMSG_GM_WHISPER = 0x3B1,
- SMSG_GM_MESSAGECHAT = 0x3B2,
- MSG_GM_GEARRATING = 0x3B3,
- CMSG_COMMENTATOR_ENABLE = 0x3B4,
- SMSG_COMMENTATOR_STATE_CHANGED = 0x3B5,
- CMSG_COMMENTATOR_GET_MAP_INFO = 0x3B6,
- SMSG_COMMENTATOR_MAP_INFO = 0x3B7,
- CMSG_COMMENTATOR_GET_PLAYER_INFO = 0x3B8,
- SMSG_COMMENTATOR_GET_PLAYER_INFO = 0x3B9,
- SMSG_COMMENTATOR_PLAYER_INFO = 0x3BA,
- CMSG_COMMENTATOR_ENTER_INSTANCE = 0x3BB,
- CMSG_COMMENTATOR_EXIT_INSTANCE = 0x3BC,
- CMSG_COMMENTATOR_INSTANCE_COMMAND = 0x3BD,
- SMSG_CLEAR_TARGET = 0x3BE,
- CMSG_BOT_DETECTED = 0x3BF,
- SMSG_CROSSED_INEBRIATION_THRESHOLD = 0x3C0,
- CMSG_CHEAT_PLAYER_LOGIN = 0x3C1,
- CMSG_CHEAT_PLAYER_LOOKUP = 0x3C2,
- SMSG_CHEAT_PLAYER_LOOKUP = 0x3C3,
- SMSG_KICK_REASON = 0x3C4,
- MSG_RAID_READY_CHECK_FINISHED = 0x3C5,
- CMSG_COMPLAIN = 0x3C6,
- SMSG_COMPLAIN_RESULT = 0x3C7,
- SMSG_FEATURE_SYSTEM_STATUS = 0x3C8,
- CMSG_GM_SHOW_COMPLAINTS = 0x3C9,
- CMSG_GM_UNSQUELCH = 0x3CA,
- CMSG_CHANNEL_SILENCE_VOICE = 0x3CB,
- CMSG_CHANNEL_SILENCE_ALL = 0x3CC,
- CMSG_CHANNEL_UNSILENCE_VOICE = 0x3CD,
- CMSG_CHANNEL_UNSILENCE_ALL = 0x3CE,
- CMSG_TARGET_CAST = 0x3CF,
- CMSG_TARGET_SCRIPT_CAST = 0x3D0,
- CMSG_CHANNEL_DISPLAY_LIST = 0x3D1,
- CMSG_SET_ACTIVE_VOICE_CHANNEL = 0x3D2,
- CMSG_GET_CHANNEL_MEMBER_COUNT = 0x3D3,
- SMSG_CHANNEL_MEMBER_COUNT = 0x3D4,
- CMSG_CHANNEL_VOICE_ON = 0x3D5,
- CMSG_CHANNEL_VOICE_OFF = 0x3D6,
- CMSG_DEBUG_LIST_TARGETS = 0x3D7,
- SMSG_DEBUG_LIST_TARGETS = 0x3D8,
- SMSG_AVAILABLE_VOICE_CHANNEL = 0x3D9,
- CMSG_ADD_VOICE_IGNORE = 0x3DA,
- CMSG_DEL_VOICE_IGNORE = 0x3DB,
- CMSG_PARTY_SILENCE = 0x3DC,
- CMSG_PARTY_UNSILENCE = 0x3DD,
- MSG_NOTIFY_PARTY_SQUELCH = 0x3DE,
- SMSG_COMSAT_RECONNECT_TRY = 0x3DF,
- SMSG_COMSAT_DISCONNECT = 0x3E0,
- SMSG_COMSAT_CONNECT_FAIL = 0x3E1,
- SMSG_VOICE_CHAT_STATUS = 0x3E2,
- CMSG_REPORT_PVP_AFK = 0x3E3,
- CMSG_REPORT_PVP_AFK_RESULT = 0x3E4,
- CMSG_GUILD_BANKER_ACTIVATE = 0x3E5,
- CMSG_GUILD_BANK_QUERY_TAB = 0x3E6,
- SMSG_GUILD_BANK_LIST = 0x3E7,
- CMSG_GUILD_BANK_SWAP_ITEMS = 0x3E8,
- CMSG_GUILD_BANK_BUY_TAB = 0x3E9,
- CMSG_GUILD_BANK_UPDATE_TAB = 0x3EA,
- CMSG_GUILD_BANK_DEPOSIT_MONEY = 0x3EB,
- CMSG_GUILD_BANK_WITHDRAW_MONEY = 0x3EC,
- MSG_GUILD_BANK_LOG_QUERY = 0x3ED,
- CMSG_SET_CHANNEL_WATCH = 0x3EE,
- SMSG_USERLIST_ADD = 0x3EF,
- SMSG_USERLIST_REMOVE = 0x3F0,
- SMSG_USERLIST_UPDATE = 0x3F1,
- CMSG_CLEAR_CHANNEL_WATCH = 0x3F2,
- SMSG_INSPECT_TALENT = 0x3F3,
- SMSG_GOGOGO_OBSOLETE = 0x3F4,
- SMSG_ECHO_PARTY_SQUELCH = 0x3F5,
- CMSG_SET_TITLE_SUFFIX = 0x3F6,
- CMSG_SPELLCLICK = 0x3F7,
- SMSG_LOOT_LIST = 0x3F8,
- CMSG_GM_CHARACTER_RESTORE = 0x3F9,
- CMSG_GM_CHARACTER_SAVE = 0x3FA,
- SMSG_VOICESESSION_FULL = 0x3FB,
- MSG_GUILD_PERMISSIONS = 0x3FC,
- MSG_GUILD_BANK_MONEY_WITHDRAWN = 0x3FD,
- MSG_GUILD_EVENT_LOG_QUERY = 0x3FE,
- CMSG_MAELSTROM_RENAME_GUILD = 0x3FF,
- CMSG_GET_MIRRORIMAGE_DATA = 0x400,
- SMSG_MIRRORIMAGE_DATA = 0x401,
- SMSG_FORCE_DISPLAY_UPDATE = 0x402,
- SMSG_SPELL_CHANCE_RESIST_PUSHBACK = 0x403,
- CMSG_IGNORE_DIMINISHING_RETURNS_CHEAT = 0x404,
- SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT = 0x405,
- CMSG_KEEP_ALIVE = 0x406,
- SMSG_RAID_READY_CHECK_ERROR = 0x407,
- CMSG_OPT_OUT_OF_LOOT = 0x408,
- MSG_QUERY_GUILD_BANK_TEXT = 0x409,
- CMSG_SET_GUILD_BANK_TEXT = 0x40A,
- CMSG_SET_GRANTABLE_LEVELS = 0x40B,
- CMSG_GRANT_LEVEL = 0x40C,
- CMSG_REFER_A_FRIEND = 0x40D,
- MSG_GM_CHANGE_ARENA_RATING = 0x40E,
- CMSG_DECLINE_CHANNEL_INVITE = 0x40F,
- CMSG_GROUPACTION_THROTTLED = 0x410,
- SMSG_OVERRIDE_LIGHT = 0x411,
- SMSG_TOTEM_CREATED = 0x412,
- CMSG_TOTEM_DESTROYED = 0x413,
- CMSG_EXPIRE_RAID_INSTANCE = 0x414,
- CMSG_NO_SPELL_VARIANCE = 0x415,
- CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY = 0x416,
- SMSG_QUESTGIVER_STATUS_MULTIPLE = 0x417,
- CMSG_SET_PLAYER_DECLINED_NAMES = 0x418,
- SMSG_SET_PLAYER_DECLINED_NAMES_RESULT = 0x419,
- CMSG_QUERY_SERVER_BUCK_DATA = 0x41A,
- CMSG_CLEAR_SERVER_BUCK_DATA = 0x41B,
- SMSG_SERVER_BUCK_DATA = 0x41C,
- SMSG_SEND_UNLEARN_SPELLS = 0x41D,
- SMSG_PROPOSE_LEVEL_GRANT = 0x41E,
- CMSG_ACCEPT_LEVEL_GRANT = 0x41F,
- SMSG_REFER_A_FRIEND_FAILURE = 0x420,
- SMSG_SPLINE_MOVE_SET_FLYING = 0x421,
- SMSG_SPLINE_MOVE_UNSET_FLYING = 0x422,
- SMSG_SUMMON_CANCEL = 0x423
+ 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,
+ CMSG_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,
+ CMSG_GROUPACTION_THROTTLED = 0x411,
+ SMSG_OVERRIDE_LIGHT = 0x412,
+ 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,
+ SMSG_MOVE_ABANDON_TRANSPORT = 0x45F,
+ MSG_MOVE_ABANDON_TRANSPORT = 0x460,
+ CMSG_MOVE_ABANDON_TRANSPORT_ACK = 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_GROUP_SWAP_FAILED = 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_QUERY_VEHICLE_STATUS = 0x4A4,
+ SMSG_PET_GUIDS = 0x4A5,
+ SMSG_CLIENTCACHE_VERSION = 0x4A6,
+ UMSG_UNKNOWN_1191 = 0x4A7,
+ UMSG_UNKNOWN_1192 = 0x4A8,
+ UMSG_UNKNOWN_1193 = 0x4A9,
+ UMSG_UNKNOWN_1194 = 0x4AA,
+ UMSG_UNKNOWN_1195 = 0x4AB,
+ UMSG_UNKNOWN_1196 = 0x4AC,
+ NUM_MSG_TYPES = 0x4AD
};
-// Don't forget to change this value and add opcode name to Opcodes.cpp when you add new opcode!
-#define NUM_MSG_TYPES 0x424
-
/// Player state
enum SessionStatus
{
diff --git a/src/game/OutdoorPvP.cpp b/src/game/OutdoorPvP.cpp
index a6f050c5a62..adbe220fbe5 100644
--- a/src/game/OutdoorPvP.cpp
+++ b/src/game/OutdoorPvP.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -95,7 +95,7 @@ bool OutdoorPvPObjective::AddObject(uint32 type, uint32 entry, uint32 map, float
if(!pMap)
return true;
GameObject * go = new GameObject;
- if(!go->Create(guid,entry, pMap,x,y,z,o,rotation0,rotation1,rotation2,rotation3,100,1))
+ if(!go->Create(guid,entry, pMap,PHASEMASK_NORMAL,x,y,z,o,rotation0,rotation1,rotation2,rotation3,100,1))
{
sLog.outError("Gameobject template %u not found in database.", entry);
delete go;
@@ -156,7 +156,7 @@ bool OutdoorPvPObjective::AddCreature(uint32 type, uint32 entry, uint32 teamval,
if(!pMap)
return true;
Creature* pCreature = new Creature;
- if (!pCreature->Create(guid, pMap, entry, teamval))
+ if (!pCreature->Create(guid, pMap, PHASEMASK_NORMAL, entry, teamval))
{
sLog.outError("Can't create creature entry: %u",entry);
delete pCreature;
@@ -256,7 +256,7 @@ bool OutdoorPvPObjective::AddCapturePoint(uint32 entry, uint32 map, float x, flo
return true;
// add GO...
GameObject * go = new GameObject;
- if(!go->Create(guid,entry, pMap,x,y,z,o,rotation0,rotation1,rotation2,rotation3,100,1))
+ if(!go->Create(guid,entry, pMap,PHASEMASK_NORMAL,x,y,z,o,rotation0,rotation1,rotation2,rotation3,100,1))
{
sLog.outError("Gameobject template %u not found in database.", entry);
delete go;
@@ -269,7 +269,7 @@ bool OutdoorPvPObjective::AddCapturePoint(uint32 entry, uint32 map, float x, flo
}
// add creature...
Creature* pCreature = new Creature;
- if (!pCreature->Create(creature_guid, pMap, OPVP_TRIGGER_CREATURE_ENTRY, 0))
+ if (!pCreature->Create(creature_guid, pMap, PHASEMASK_NORMAL, OPVP_TRIGGER_CREATURE_ENTRY, 0))
{
sLog.outError("Can't create creature entry: %u",entry);
delete pCreature;
diff --git a/src/game/OutdoorPvP.h b/src/game/OutdoorPvP.h
index 5643c5f3148..542863a5341 100644
--- a/src/game/OutdoorPvP.h
+++ b/src/game/OutdoorPvP.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/OutdoorPvPEP.cpp b/src/game/OutdoorPvPEP.cpp
index 93064c85d88..c403a5dc094 100644
--- a/src/game/OutdoorPvPEP.cpp
+++ b/src/game/OutdoorPvPEP.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/OutdoorPvPEP.h b/src/game/OutdoorPvPEP.h
index d454848e249..2a6a47827d6 100644
--- a/src/game/OutdoorPvPEP.h
+++ b/src/game/OutdoorPvPEP.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/OutdoorPvPHP.cpp b/src/game/OutdoorPvPHP.cpp
index ced9bcf09e6..7294db0fb77 100644
--- a/src/game/OutdoorPvPHP.cpp
+++ b/src/game/OutdoorPvPHP.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/OutdoorPvPHP.h b/src/game/OutdoorPvPHP.h
index dd274097dfa..986e8daee7e 100644
--- a/src/game/OutdoorPvPHP.h
+++ b/src/game/OutdoorPvPHP.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/OutdoorPvPMgr.cpp b/src/game/OutdoorPvPMgr.cpp
index 7f1ffa3faa6..757cbe82188 100644
--- a/src/game/OutdoorPvPMgr.cpp
+++ b/src/game/OutdoorPvPMgr.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/OutdoorPvPMgr.h b/src/game/OutdoorPvPMgr.h
index 033f67d97d3..2478acf76f4 100644
--- a/src/game/OutdoorPvPMgr.h
+++ b/src/game/OutdoorPvPMgr.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/OutdoorPvPNA.cpp b/src/game/OutdoorPvPNA.cpp
index 827f988a959..c8134944cc1 100644
--- a/src/game/OutdoorPvPNA.cpp
+++ b/src/game/OutdoorPvPNA.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/OutdoorPvPNA.h b/src/game/OutdoorPvPNA.h
index a833a6d95b2..e7f157879bc 100644
--- a/src/game/OutdoorPvPNA.h
+++ b/src/game/OutdoorPvPNA.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/OutdoorPvPObjectiveAI.cpp b/src/game/OutdoorPvPObjectiveAI.cpp
index b907fa7cdba..6e6cf8d64e5 100644
--- a/src/game/OutdoorPvPObjectiveAI.cpp
+++ b/src/game/OutdoorPvPObjectiveAI.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/OutdoorPvPObjectiveAI.h b/src/game/OutdoorPvPObjectiveAI.h
index 4b65c72e6f9..3395b7e1be5 100644
--- a/src/game/OutdoorPvPObjectiveAI.h
+++ b/src/game/OutdoorPvPObjectiveAI.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/OutdoorPvPSI.cpp b/src/game/OutdoorPvPSI.cpp
index b2bbc8a109b..9e95c315c7f 100644
--- a/src/game/OutdoorPvPSI.cpp
+++ b/src/game/OutdoorPvPSI.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -202,7 +202,7 @@ bool OutdoorPvPSI::HandleDropFlag(Player *plr, uint32 spellId)
Map * map = MapManager::Instance().GetMap(plr->GetMapId(), plr);
if(!map)
return true;
- if(!go->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT),SI_SILITHYST_MOUND, map,plr->GetPositionX(),plr->GetPositionY(),plr->GetPositionZ(),plr->GetOrientation(),0,0,0,0,100,1))
+ if(!go->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT),SI_SILITHYST_MOUND, map, plr->GetPhaseMask(), plr->GetPositionX(),plr->GetPositionY(),plr->GetPositionZ(),plr->GetOrientation(),0,0,0,0,100,1))
{
delete go;
}
@@ -228,7 +228,7 @@ bool OutdoorPvPSI::HandleDropFlag(Player *plr, uint32 spellId)
Map * map = MapManager::Instance().GetMap(plr->GetMapId(), plr);
if(!map)
return true;
- if(!go->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT),SI_SILITHYST_MOUND, map ,plr->GetPositionX(),plr->GetPositionY(),plr->GetPositionZ(),plr->GetOrientation(),0,0,0,0,100,1))
+ if(!go->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT),SI_SILITHYST_MOUND, map, plr->GetPhaseMask() ,plr->GetPositionX(),plr->GetPositionY(),plr->GetPositionZ(),plr->GetOrientation(),0,0,0,0,100,1))
{
delete go;
}
diff --git a/src/game/OutdoorPvPSI.h b/src/game/OutdoorPvPSI.h
index 0eb07af508f..208e35d09a1 100644
--- a/src/game/OutdoorPvPSI.h
+++ b/src/game/OutdoorPvPSI.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/OutdoorPvPTF.cpp b/src/game/OutdoorPvPTF.cpp
index bd8355de667..39acc70ba53 100644
--- a/src/game/OutdoorPvPTF.cpp
+++ b/src/game/OutdoorPvPTF.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/OutdoorPvPZM.cpp b/src/game/OutdoorPvPZM.cpp
index be2a8c7f093..d8ac0de5f7d 100644
--- a/src/game/OutdoorPvPZM.cpp
+++ b/src/game/OutdoorPvPZM.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/OutdoorPvPZM.h b/src/game/OutdoorPvPZM.h
index 8ccbe77f363..c99ad69fa22 100644
--- a/src/game/OutdoorPvPZM.h
+++ b/src/game/OutdoorPvPZM.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/Path.h b/src/game/Path.h
index 2bf7cfa4d6b..fe1c3587caf 100644
--- a/src/game/Path.h
+++ b/src/game/Path.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp
index 72951420573..bf150ec3a42 100644
--- a/src/game/Pet.cpp
+++ b/src/game/Pet.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -41,46 +41,14 @@ char const* petTypeSuffix[MAX_PET_TYPE] =
"'s Companion" // MINI_PET
};
-//numbers represent minutes * 100 while happy (you get 100 loyalty points per min while happy)
-uint32 const LevelUpLoyalty[6] =
-{
- 5500,
- 11500,
- 17000,
- 23500,
- 31000,
- 39500,
-};
-
-uint32 const LevelStartLoyalty[6] =
-{
- 2000,
- 4500,
- 7000,
- 10000,
- 13500,
- 17500,
-};
-
-Pet::Pet(PetType type) : Creature()
+Pet::Pet(PetType type) :
+Creature(), m_petType(type), m_removed(false), m_happinessTimer(7500), m_duration(0), m_bonusdamage(0),
+m_resetTalentsCost(0), m_resetTalentsTime(0), m_usedTalentCount(0), m_auraRaidUpdateMask(0), m_loading(false),
+m_declinedname(NULL)
{
m_isPet = true;
m_name = "Pet";
- m_petType = type;
-
- m_removed = false;
m_regenTimer = 4000;
- m_happinessTimer = 7500;
- m_loyaltyTimer = 12000;
- m_duration = 0;
- m_bonusdamage = 0;
-
- m_loyaltyPoints = 0;
- m_TrainingPoints = 0;
- m_resetTalentsCost = 0;
- m_resetTalentsTime = 0;
-
- m_auraUpdateMask = 0;
// pets always have a charminfo, even if they are not actually charmed
CharmInfo* charmInfo = InitCharmInfo(this);
@@ -90,12 +58,6 @@ Pet::Pet(PetType type) : Creature()
else if(type == GUARDIAN_PET) // always aggressive
charmInfo->SetReactState(REACT_AGGRESSIVE);
- m_spells.clear();
- m_Auras.clear();
- m_CreatureSpellCooldowns.clear();
- m_CreatureCategoryCooldowns.clear();
- m_autospells.clear();
- m_declinedname = NULL;
m_isActive = true;
}
@@ -126,26 +88,28 @@ void Pet::RemoveFromWorld()
Unit::RemoveFromWorld();
}
-bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool current )
+bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool current )
{
+ m_loading = true;
+
uint32 ownerid = owner->GetGUIDLow();
QueryResult *result;
if(petnumber)
- // known petnumber entry 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
- result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND id = '%u'",ownerid, petnumber);
+ // known petnumber entry 0 1 2(?) 3 4 5 6 7 8(?) 9 10 11 12 13 14 15 16 17 18 19 20
+ result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND id = '%u'",ownerid, petnumber);
else if(current)
- // current pet (slot 0) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
- result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND slot = '0'",ownerid );
+ // current pet (slot 0) 0 1 2(?) 3 4 5 6 7 8(?) 9 10 11 12 13 14 15 16 17 18 19 20
+ result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND slot = '0'",ownerid );
else if(petentry)
// known petentry entry (unique for summoned pet, but non unique for hunter pet (only from current or not stabled pets)
- // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
- result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND entry = '%u' AND (slot = '0' OR slot = '3') ",ownerid, petentry );
+ // 0 1 2(?) 3 4 5 6 7 8(?) 9 10 11 12 13 14 15 16 17 18 19 20
+ result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND entry = '%u' AND (slot = '0' OR slot = '3') ",ownerid, petentry );
else
// any current or other non-stabled pet (for hunter "call pet")
- // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
- result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND (slot = '0' OR slot = '3') ",ownerid);
+ // 0 1 2(?) 3 4 5 6 7 8(?) 9 10 11 12 13 14 15 16 17 18 19 20
+ result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND (slot = '0' OR slot = '3') ",ownerid);
if(!result)
return false;
@@ -160,7 +124,7 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu
return false;
}
- uint32 summon_spell_id = fields[21].GetUInt32();
+ uint32 summon_spell_id = fields[19].GetUInt32();
SpellEntry const* spellInfo = sSpellStore.LookupEntry(summon_spell_id);
bool is_temporary_summoned = spellInfo && GetSpellDuration(spellInfo) > 0;
@@ -175,7 +139,7 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu
Map *map = owner->GetMap();
uint32 guid = objmgr.GenerateLowGuid(HIGHGUID_PET);
uint32 pet_number = fields[0].GetUInt32();
- if(!Create(guid, map, petentry, pet_number))
+ if(!Create(guid, map, owner->GetPhaseMask(), petentry, pet_number))
{
delete result;
return false;
@@ -194,8 +158,8 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu
return false;
}
- setPetType(PetType(fields[22].GetUInt8()));
- SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,owner->getFaction());
+ setPetType(PetType(fields[20].GetUInt8()));
+ SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, owner->getFaction());
SetUInt32Value(UNIT_CREATED_BY_SPELL, summon_spell_id);
CreatureInfo const *cinfo = GetCreatureInfo();
@@ -206,72 +170,67 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu
delete result;
return true;
}
- if(getPetType()==HUNTER_PET || (getPetType()==SUMMON_PET && cinfo->type == CREATURE_TYPE_DEMON && owner->getClass() == CLASS_WARLOCK))
+
+ if(getPetType() == HUNTER_PET || (getPetType() == SUMMON_PET && cinfo->type == CREATURE_TYPE_DEMON && owner->getClass() == CLASS_WARLOCK))
m_charmInfo->SetPetNumber(pet_number, true);
else
m_charmInfo->SetPetNumber(pet_number, false);
- SetUInt64Value(UNIT_FIELD_SUMMONEDBY, owner->GetGUID());
+
+ SetOwnerGUID(owner->GetGUID());
SetDisplayId(fields[3].GetUInt32());
SetNativeDisplayId(fields[3].GetUInt32());
- uint32 petlevel=fields[4].GetUInt32();
- SetUInt32Value(UNIT_NPC_FLAGS , 0);
- SetName(fields[11].GetString());
+ uint32 petlevel = fields[4].GetUInt32();
+ SetUInt32Value(UNIT_NPC_FLAGS, 0);
+ SetName(fields[9].GetString());
switch(getPetType())
{
-
case SUMMON_PET:
petlevel=owner->getLevel();
- SetUInt32Value(UNIT_FIELD_BYTES_0,2048);
+ SetUInt32Value(UNIT_FIELD_BYTES_0, 2048);
SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
// this enables popup window (pet dismiss, cancel)
break;
case HUNTER_PET:
SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100);
- SetByteValue(UNIT_FIELD_BYTES_1, 1, fields[8].GetUInt32());
- SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE );
- SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY | UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5 );
-
- if(fields[12].GetBool())
- SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_NOT_ALLOWED);
- else
- SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_ALLOWED);
+ SetByteValue(UNIT_FIELD_BYTES_1, 1, fields[7].GetUInt32());
+ SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE);
+ SetByteValue(UNIT_FIELD_BYTES_2, 2, fields[10].GetBool() ? UNIT_RENAME_NOT_ALLOWED : UNIT_RENAME_ALLOWED);
SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
// this enables popup window (pet abandon, cancel)
- SetTP(fields[9].GetInt32());
- SetMaxPower(POWER_HAPPINESS,GetCreatePowers(POWER_HAPPINESS));
- SetPower( POWER_HAPPINESS,fields[15].GetUInt32());
+ SetMaxPower(POWER_HAPPINESS, GetCreatePowers(POWER_HAPPINESS));
+ SetPower(POWER_HAPPINESS, fields[13].GetUInt32());
setPowerType(POWER_FOCUS);
break;
default:
- sLog.outError("Pet have incorrect type (%u) for pet loading.",getPetType());
+ sLog.outError("Pet have incorrect type (%u) for pet loading.", getPetType());
}
- InitStatsForLevel( petlevel);
+
+ InitStatsForLevel(petlevel);
SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL));
SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, fields[5].GetUInt32());
- SetUInt64Value(UNIT_FIELD_CREATEDBY, owner->GetGUID());
+ SetCreatorGUID(owner->GetGUID());
- m_charmInfo->SetReactState( ReactStates( fields[6].GetUInt8() ));
- m_loyaltyPoints = fields[7].GetInt32();
+ m_charmInfo->SetReactState(ReactStates(fields[6].GetUInt8()));
- uint32 savedhealth = fields[13].GetUInt32();
- uint32 savedmana = fields[14].GetUInt32();
+ uint32 savedhealth = fields[11].GetUInt32();
+ uint32 savedmana = fields[12].GetUInt32();
// set current pet as current
- if(fields[10].GetUInt32() != 0)
+ if(fields[8].GetUInt32() != 0)
{
CharacterDatabase.BeginTransaction();
- CharacterDatabase.PExecute("UPDATE character_pet SET slot = '3' WHERE owner = '%u' AND slot = '0' AND id <> '%u'",ownerid, m_charmInfo->GetPetNumber());
- CharacterDatabase.PExecute("UPDATE character_pet SET slot = '0' WHERE owner = '%u' AND id = '%u'",ownerid, m_charmInfo->GetPetNumber());
+ CharacterDatabase.PExecute("UPDATE character_pet SET slot = '3' WHERE owner = '%u' AND slot = '0' AND id <> '%u'", ownerid, m_charmInfo->GetPetNumber());
+ CharacterDatabase.PExecute("UPDATE character_pet SET slot = '0' WHERE owner = '%u' AND id = '%u'", ownerid, m_charmInfo->GetPetNumber());
CharacterDatabase.CommitTransaction();
}
if(!is_temporary_summoned)
{
// permanent controlled pets store state in DB
- Tokens tokens = StrSplit(fields[16].GetString(), " ");
+ Tokens tokens = StrSplit(fields[14].GetString(), " ");
if(tokens.size() != 20)
{
@@ -290,11 +249,11 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu
// patch for old data where some spells have ACT_DECIDE but should have ACT_CAST
// so overwrite old state
SpellEntry const *spellInfo = sSpellStore.LookupEntry(m_charmInfo->GetActionBarEntry(index)->SpellOrAction);
- if (spellInfo && spellInfo->AttributesEx & SPELL_ATTR_EX_UNAUTOCASTABLE_BY_PET) m_charmInfo->GetActionBarEntry(index)->Type = ACT_CAST;
+ if (spellInfo && spellInfo->AttributesEx & SPELL_ATTR_EX_UNAUTOCASTABLE_BY_PET) m_charmInfo->GetActionBarEntry(index)->Type = ACT_ENABLED;
}
//init teach spells
- tokens = StrSplit(fields[17].GetString(), " ");
+ tokens = StrSplit(fields[15].GetString(), " ");
for (iter = tokens.begin(), index = 0; index < 4; ++iter, ++index)
{
uint32 tmp = atol((*iter).c_str());
@@ -309,7 +268,10 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu
}
// since last save (in seconds)
- uint32 timediff = (time(NULL) - fields[18].GetUInt32());
+ uint32 timediff = (time(NULL) - fields[16].GetUInt32());
+
+ m_resetTalentsCost = fields[17].GetUInt32();
+ m_resetTalentsTime = fields[18].GetUInt64();
delete result;
@@ -375,6 +337,7 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu
}
}
+ m_loading = false;
return true;
}
@@ -417,10 +380,6 @@ void Pet::SavePetToDB(PetSaveMode mode)
case PET_SAVE_IN_STABLE_SLOT_2:
case PET_SAVE_NOT_IN_SLOT:
{
- uint32 loyalty =1;
- if(getPetType()!=HUNTER_PET)
- loyalty = GetLoyaltyLevel();
-
uint32 owner = GUID_LOPART(GetOwnerGUID());
std::string name = m_name;
CharacterDatabase.escape_string(name);
@@ -437,7 +396,7 @@ void Pet::SavePetToDB(PetSaveMode mode)
CharacterDatabase.PExecute("DELETE FROM character_pet WHERE owner = '%u' AND (slot = '0' OR slot = '3')", owner );
// save pet
std::ostringstream ss;
- ss << "INSERT INTO character_pet ( id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata,TeachSpelldata,savetime,resettalents_cost,resettalents_time,CreatedBySpell,PetType) "
+ ss << "INSERT INTO character_pet ( id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType) "
<< "VALUES ("
<< m_charmInfo->GetPetNumber() << ", "
<< GetEntry() << ", "
@@ -446,9 +405,7 @@ void Pet::SavePetToDB(PetSaveMode mode)
<< getLevel() << ", "
<< GetUInt32Value(UNIT_FIELD_PETEXPERIENCE) << ", "
<< uint32(m_charmInfo->GetReactState()) << ", "
- << m_loyaltyPoints << ", "
- << GetLoyaltyLevel() << ", "
- << m_TrainingPoints << ", "
+ << uint32(GetFreeTalentPoints()) << ", "
<< uint32(mode) << ", '"
<< name.c_str() << "', "
<< uint32((GetByteValue(UNIT_FIELD_BYTES_2, 2) == UNIT_RENAME_ALLOWED)?0:1) << ", "
@@ -521,12 +478,12 @@ void Pet::setDeathState(DeathState s) // overwrite virtual
if(!mapEntry || (mapEntry->map_type != MAP_ARENA && mapEntry->map_type != MAP_BATTLEGROUND))
ModifyPower(POWER_HAPPINESS, -HAPPINESS_LEVEL_SIZE);
- SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
+ SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
}
}
else if(getDeathState()==ALIVE)
{
- RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
+ RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
CastPetAuras(true);
}
}
@@ -553,6 +510,7 @@ void Pet::Update(uint32 diff)
// unsummon pet that lost owner
Unit* owner = GetOwner();
if(!owner || (!IsWithinDistInMap(owner, OWNER_MAX_DISTANCE) && !isPossessed()) || isControlled() && !owner->GetPetGUID())
+ //if(!owner || (!IsWithinDistInMap(owner, OWNER_MAX_DISTANCE) && (owner->GetCharmGUID() && (owner->GetCharmGUID() != GetGUID()))) || (isControlled() && !owner->GetPetGUID()))
{
Remove(PET_SAVE_NOT_IN_SLOT, true);
return;
@@ -598,14 +556,6 @@ void Pet::Update(uint32 diff)
else
m_happinessTimer -= diff;
- if(m_loyaltyTimer <= diff)
- {
- TickLoyaltyChange();
- m_loyaltyTimer = 12000;
- }
- else
- m_loyaltyTimer -= diff;
-
break;
}
default:
@@ -627,7 +577,7 @@ void Pet::RegenerateFocus()
AuraList const& ModPowerRegenPCTAuras = GetAurasByType(SPELL_AURA_MOD_POWER_REGEN_PERCENT);
for(AuraList::const_iterator i = ModPowerRegenPCTAuras.begin(); i != ModPowerRegenPCTAuras.end(); ++i)
if ((*i)->GetModifier()->m_miscvalue == POWER_FOCUS)
- addvalue *= ((*i)->GetModifierValue() + 100) / 100.0f;
+ addvalue *= ((*i)->GetModifier()->m_amount + 100) / 100.0f;
ModifyPower(POWER_FOCUS, (int32)addvalue);
}
@@ -637,83 +587,12 @@ void Pet::LooseHappiness()
uint32 curValue = GetPower(POWER_HAPPINESS);
if (curValue <= 0)
return;
- int32 addvalue = (140 >> GetLoyaltyLevel()) * 125; //value is 70/35/17/8/4 (per min) * 1000 / 8 (timer 7.5 secs)
+ 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.5);
ModifyPower(POWER_HAPPINESS, -addvalue);
}
-void Pet::ModifyLoyalty(int32 addvalue)
-{
- uint32 loyaltylevel = GetLoyaltyLevel();
-
- if(addvalue > 0) //only gain influenced, not loss
- addvalue = int32((float)addvalue * sWorld.getRate(RATE_LOYALTY));
-
- if(loyaltylevel >= BEST_FRIEND && (addvalue + m_loyaltyPoints) > int32(GetMaxLoyaltyPoints(loyaltylevel)))
- return;
-
- m_loyaltyPoints += addvalue;
-
- if(m_loyaltyPoints < 0)
- {
- if(loyaltylevel > REBELLIOUS)
- {
- //level down
- --loyaltylevel;
- SetLoyaltyLevel(LoyaltyLevel(loyaltylevel));
- m_loyaltyPoints = GetStartLoyaltyPoints(loyaltylevel);
- SetTP(m_TrainingPoints - int32(getLevel()));
- }
- else
- {
- m_loyaltyPoints = 0;
- Unit* owner = GetOwner();
- if(owner && owner->GetTypeId() == TYPEID_PLAYER)
- {
- WorldPacket data(SMSG_PET_BROKEN, 0);
- ((Player*)owner)->GetSession()->SendPacket(&data);
-
- //run away
- ((Player*)owner)->RemovePet(this,PET_SAVE_AS_DELETED);
- }
- }
- }
- //level up
- else if(m_loyaltyPoints > int32(GetMaxLoyaltyPoints(loyaltylevel)))
- {
- ++loyaltylevel;
- SetLoyaltyLevel(LoyaltyLevel(loyaltylevel));
- m_loyaltyPoints = GetStartLoyaltyPoints(loyaltylevel);
- SetTP(m_TrainingPoints + getLevel());
- }
-}
-
-void Pet::TickLoyaltyChange()
-{
- int32 addvalue;
-
- switch(GetHappinessState())
- {
- case HAPPY: addvalue = 20; break;
- case CONTENT: addvalue = 10; break;
- case UNHAPPY: addvalue = -20; break;
- default:
- return;
- }
- ModifyLoyalty(addvalue);
-}
-
-void Pet::KillLoyaltyBonus(uint32 level)
-{
- if(level > 100)
- return;
-
- //at lower levels gain is faster | the lower loyalty the more loyalty is gained
- uint32 bonus = uint32(((100 - level) / 10) + (6 - GetLoyaltyLevel()));
- ModifyLoyalty(bonus);
-}
-
HappinessState Pet::GetHappinessState()
{
if(GetPower(POWER_HAPPINESS) < HAPPINESS_LEVEL_SIZE)
@@ -724,11 +603,6 @@ HappinessState Pet::GetHappinessState()
return CONTENT;
}
-void Pet::SetLoyaltyLevel(LoyaltyLevel level)
-{
- SetByteValue(UNIT_FIELD_BYTES_1, 1, level);
-}
-
bool Pet::CanTakeMoreActiveSpells(uint32 spellid)
{
uint8 activecount = 1;
@@ -765,82 +639,6 @@ bool Pet::CanTakeMoreActiveSpells(uint32 spellid)
return true;
}
-bool Pet::HasTPForSpell(uint32 spellid)
-{
- int32 neededtrainp = GetTPForSpell(spellid);
- if((m_TrainingPoints - neededtrainp < 0 || neededtrainp < 0) && neededtrainp != 0)
- return false;
- return true;
-}
-
-int32 Pet::GetTPForSpell(uint32 spellid)
-{
- uint32 basetrainp = 0;
-
- SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(spellid);
- SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(spellid);
- for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
- {
- if(!_spell_idx->second->reqtrainpoints)
- return 0;
-
- basetrainp = _spell_idx->second->reqtrainpoints;
- break;
- }
-
- uint32 spenttrainp = 0;
- uint32 chainstart = spellmgr.GetFirstSpellInChain(spellid);
-
- for (PetSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
- {
- if(itr->second->state == PETSPELL_REMOVED)
- continue;
-
- if(spellmgr.GetFirstSpellInChain(itr->first) == chainstart)
- {
- SkillLineAbilityMap::const_iterator _lower = spellmgr.GetBeginSkillLineAbilityMap(itr->first);
- SkillLineAbilityMap::const_iterator _upper = spellmgr.GetEndSkillLineAbilityMap(itr->first);
-
- for(SkillLineAbilityMap::const_iterator _spell_idx2 = _lower; _spell_idx2 != _upper; ++_spell_idx2)
- {
- if(_spell_idx2->second->reqtrainpoints > spenttrainp)
- {
- spenttrainp = _spell_idx2->second->reqtrainpoints;
- break;
- }
- }
- }
- }
-
- return int32(basetrainp) - int32(spenttrainp);
-}
-
-uint32 Pet::GetMaxLoyaltyPoints(uint32 level)
-{
- return LevelUpLoyalty[level - 1];
-}
-
-uint32 Pet::GetStartLoyaltyPoints(uint32 level)
-{
- return LevelStartLoyalty[level - 1];
-}
-
-void Pet::SetTP(int32 TP)
-{
- m_TrainingPoints = TP;
- SetUInt32Value(UNIT_TRAINING_POINTS, (uint32)GetDispTP());
-}
-
-int32 Pet::GetDispTP()
-{
- if(getPetType()!= HUNTER_PET)
- return(0);
- if(m_TrainingPoints < 0)
- return -m_TrainingPoints;
- else
- return -(m_TrainingPoints + 1);
-}
-
void Pet::Remove(PetSaveMode mode, bool returnreagent)
{
Unit* owner = GetOwner();
@@ -895,7 +693,7 @@ void Pet::GivePetXP(uint32 xp)
newXP -= nextLvlXP;
SetLevel( level + 1 );
- SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, uint32((Trinity::XP::xp_to_level(level+1))/4));
+ SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, objmgr.GetXPForLevel(level+1)/4);
level = getLevel();
nextLvlXP = GetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP);
@@ -903,9 +701,6 @@ void Pet::GivePetXP(uint32 xp)
}
SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, newXP);
-
- if(getPetType() == HUNTER_PET)
- KillLoyaltyBonus(level);
}
void Pet::GivePetLevel(uint32 level)
@@ -913,9 +708,8 @@ void Pet::GivePetLevel(uint32 level)
if(!level)
return;
- InitStatsForLevel( level);
-
- SetTP(m_TrainingPoints + (GetLoyaltyLevel() - 1));
+ InitStatsForLevel(level);
+ InitTalentForLevel();
}
bool Pet::CreateBaseAtCreature(Creature* creature)
@@ -932,7 +726,7 @@ bool Pet::CreateBaseAtCreature(Creature* creature)
sLog.outDebug("Create pet");
uint32 pet_number = objmgr.GeneratePetNumber();
- if(!Create(guid, creature->GetMap(), creature->GetEntry(), pet_number))
+ if(!Create(guid, creature->GetMap(), creature->GetPhaseMask(), creature->GetEntry(), pet_number))
return false;
Relocate(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetOrientation());
@@ -963,26 +757,20 @@ bool Pet::CreateBaseAtCreature(Creature* creature)
setPowerType(POWER_FOCUS);
SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, 0);
SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0);
- SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, uint32((Trinity::XP::xp_to_level(creature->getLevel()))/4));
- SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
+ SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, objmgr.GetXPForLevel(creature->getLevel())/4);
SetUInt32Value(UNIT_NPC_FLAGS, 0);
- CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(creature->GetCreatureInfo()->family);
- if( char* familyname = cFamily->Name[sWorld.GetDefaultDbcLocale()] )
- SetName(familyname);
+ if(CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cinfo->family))
+ SetName(cFamily->Name[sWorld.GetDefaultDbcLocale()]);
else
- SetName(creature->GetName());
+ SetName(creature->GetNameForLocaleIdx(objmgr.GetDBCLocaleIndex()));
- m_loyaltyPoints = 1000;
if(cinfo->type == CREATURE_TYPE_BEAST)
{
SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100);
SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE );
- SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY | UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5 );
SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_ALLOWED);
-
- SetUInt32Value(UNIT_MOD_CAST_SPEED, creature->GetUInt32Value(UNIT_MOD_CAST_SPEED) );
- SetLoyaltyLevel(REBELLIOUS);
+ SetUInt32Value(UNIT_MOD_CAST_SPEED, creature->GetUInt32Value(UNIT_MOD_CAST_SPEED));
}
return true;
}
@@ -1111,8 +899,8 @@ bool Pet::InitStatsForLevel(uint32 petlevel)
}
case HUNTER_PET:
{
- SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, uint32((Trinity::XP::xp_to_level(petlevel))/4));
-
+ SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, objmgr.GetXPForLevel(petlevel)/4);
+ learnLevelupSpells();
//these formula may not be correct; however, it is designed to be close to what it should be
//this makes dps 0.5 of pets level
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4)) );
@@ -1304,7 +1092,7 @@ void Pet::_SaveSpellCooldowns()
void Pet::_LoadSpells()
{
- QueryResult *result = CharacterDatabase.PQuery("SELECT spell,slot,active FROM pet_spell WHERE guid = '%u'",m_charmInfo->GetPetNumber());
+ QueryResult *result = CharacterDatabase.PQuery("SELECT spell,active FROM pet_spell WHERE guid = '%u'",m_charmInfo->GetPetNumber());
if(result)
{
@@ -1312,7 +1100,7 @@ void Pet::_LoadSpells()
{
Field *fields = result->Fetch();
- addSpell(fields[0].GetUInt16(), fields[2].GetUInt16(), PETSPELL_UNCHANGED, fields[1].GetUInt16());
+ addSpell(fields[0].GetUInt32(), fields[1].GetUInt16(), PETSPELL_UNCHANGED);
}
while( result->NextRow() );
@@ -1329,7 +1117,7 @@ void Pet::_SaveSpells()
if (itr->second->state == PETSPELL_REMOVED || itr->second->state == PETSPELL_CHANGED)
CharacterDatabase.PExecute("DELETE FROM pet_spell WHERE guid = '%u' and spell = '%u'", m_charmInfo->GetPetNumber(), itr->first);
if (itr->second->state == PETSPELL_NEW || itr->second->state == PETSPELL_CHANGED)
- CharacterDatabase.PExecute("INSERT INTO pet_spell (guid,spell,slot,active) VALUES ('%u', '%u', '%u','%u')", m_charmInfo->GetPetNumber(), itr->first, itr->second->slotId,itr->second->active);
+ CharacterDatabase.PExecute("INSERT INTO pet_spell (guid,spell,active) VALUES ('%u', '%u', '%u')", m_charmInfo->GetPetNumber(), itr->first, itr->second->active);
if (itr->second->state == PETSPELL_REMOVED)
_removeSpell(itr->first);
@@ -1344,10 +1132,6 @@ void Pet::_LoadAuras(uint32 timediff)
for (int i = 0; i < TOTAL_AURAS; i++)
m_modAuras[i].clear();
- // all aura related fields
- for(int i = UNIT_FIELD_AURA; i <= UNIT_FIELD_AURASTATE; ++i)
- SetUInt32Value(i, 0);
-
QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM pet_aura WHERE guid = '%u'",m_charmInfo->GetPetNumber());
if(result)
@@ -1451,7 +1235,7 @@ void Pet::_SaveAuras()
{
CharacterDatabase.PExecute("INSERT INTO pet_aura (guid,caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges) "
"VALUES ('%u', '" I64FMTD "', '%u', '%u', '%u', '%d', '%d', '%d', '%d')",
- m_charmInfo->GetPetNumber(), itr2->second->GetCasterGUID(),(uint32)itr2->second->GetId(), (uint32)itr2->second->GetEffIndex(), (uint32)itr2->second->GetStackAmount(), itr2->second->GetModifier()->m_amount,int(itr2->second->GetAuraMaxDuration()),int(itr2->second->GetAuraDuration()),int(itr2->second->m_procCharges));
+ m_charmInfo->GetPetNumber(), itr2->second->GetCasterGUID(),(uint32)itr2->second->GetId(), (uint32)itr2->second->GetEffIndex(), (uint32)itr2->second->GetStackAmount(), itr2->second->GetModifier()->m_amount ,int(itr2->second->GetAuraMaxDuration()),int(itr2->second->GetAuraDuration()),int(itr2->second->GetAuraCharges()));
}
}
}
@@ -1469,7 +1253,7 @@ void Pet::_SaveAuras()
}
}
-bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, uint16 slot_id, PetSpellType type)
+bool Pet::addSpell(uint32 spell_id, uint16 active, PetSpellState state, PetSpellType type)
{
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id);
if (!spellInfo)
@@ -1488,7 +1272,7 @@ bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, uint16 s
// same spells don't have autocast option
if (spellInfo->AttributesEx & SPELL_ATTR_EX_UNAUTOCASTABLE_BY_PET)
- active = ACT_CAST;
+ active = ACT_ENABLED;
PetSpellMap::iterator itr = m_spells.find(spell_id);
if (itr != m_spells.end())
@@ -1525,40 +1309,45 @@ bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, uint16 s
else
newspell->active = active;
- uint32 chainstart = spellmgr.GetFirstSpellInChain(spell_id);
-
- for (PetSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
+ // talent: unlearn all other talent ranks (high and low)
+ if(TalentSpellPos const* talentPos = GetTalentSpellPos(spell_id))
{
- if(itr->second->state == PETSPELL_REMOVED) continue;
-
- if(spellmgr.GetFirstSpellInChain(itr->first) == chainstart)
+ if(TalentEntry const *talentInfo = sTalentStore.LookupEntry( talentPos->talent_id ))
{
- slot_id = itr->second->slotId;
- newspell->active = itr->second->active;
-
- if(newspell->active == ACT_ENABLED)
- ToggleAutocast(itr->first, false);
+ for(int i=0; i <5; ++i)
+ {
+ // skip learning spell and no rank spell case
+ uint32 rankSpellId = talentInfo->RankID[i];
+ if(!rankSpellId || rankSpellId==spell_id)
+ continue;
- oldspell_id = itr->first;
- removeSpell(itr->first);
+ // skip unknown ranks
+ if(!HasSpell(rankSpellId))
+ continue;
+ removeSpell(rankSpellId);
+ }
}
}
-
- uint16 tmpslot=slot_id;
-
- if (tmpslot == 0xffff)
+ else if(uint32 chainstart = spellmgr.GetFirstSpellInChain(spell_id))
{
- uint16 maxid = 0;
- PetSpellMap::iterator itr;
- for (itr = m_spells.begin(); itr != m_spells.end(); ++itr)
+ for (PetSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
{
if(itr->second->state == PETSPELL_REMOVED) continue;
- if (itr->second->slotId > maxid) maxid = itr->second->slotId;
+
+ if(spellmgr.GetFirstSpellInChain(itr->first) == chainstart)
+ {
+ newspell->active = itr->second->active;
+
+ if(newspell->active == ACT_ENABLED)
+ ToggleAutocast(itr->first, false);
+
+ oldspell_id = itr->first;
+ unlearnSpell(itr->first);
+ break;
+ }
}
- tmpslot = maxid + 1;
}
- newspell->slotId = tmpslot;
m_spells[spell_id] = newspell;
if (IsPassiveSpell(spell_id))
@@ -1569,29 +1358,81 @@ bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, uint16 s
if(newspell->active == ACT_ENABLED)
ToggleAutocast(spell_id, true);
+ uint32 talentCost = GetTalentSpellCost(spell_id);
+ if (talentCost)
+ {
+ int32 free_points = GetMaxTalentPointsForLevel(getLevel());
+ m_usedTalentCount+=talentCost;
+ // update free talent points
+ free_points-=m_usedTalentCount;
+ SetFreeTalentPoints(free_points > 0 ? free_points : 0);
+ }
return true;
}
-bool Pet::learnSpell(uint16 spell_id)
+bool Pet::learnSpell(uint32 spell_id)
{
// prevent duplicated entires in spell book
if (!addSpell(spell_id))
return false;
Unit* owner = GetOwner();
- if(owner->GetTypeId()==TYPEID_PLAYER)
+ if(owner && owner->GetTypeId() == TYPEID_PLAYER)
+ {
+ if(!m_loading)
+ {
+ WorldPacket data(SMSG_PET_LEARNED_SPELL, 2);
+ data << uint16(spell_id);
+ ((Player*)owner)->GetSession()->SendPacket(&data);
+ }
((Player*)owner)->PetSpellInitialize();
+ }
return true;
}
-void Pet::removeSpell(uint16 spell_id)
+void Pet::learnLevelupSpells()
+{
+ PetLevelupSpellSet const *levelupSpells = spellmgr.GetPetLevelupSpellList(GetCreatureInfo()->family);
+ if(!levelupSpells)
+ return;
+
+ uint32 level = getLevel();
+
+ for(PetLevelupSpellSet::const_iterator itr = levelupSpells->begin(); itr != levelupSpells->end(); ++itr)
+ {
+ if(itr->first <= level)
+ learnSpell(itr->second);
+ else
+ unlearnSpell(itr->second);
+ }
+}
+
+bool Pet::unlearnSpell(uint32 spell_id)
+{
+ if(removeSpell(spell_id))
+ {
+ if(GetOwner()->GetTypeId() == TYPEID_PLAYER)
+ {
+ if(!m_loading)
+ {
+ WorldPacket data(SMSG_PET_REMOVED_SPELL, 2);
+ data << uint16(spell_id);
+ ((Player*)GetOwner())->GetSession()->SendPacket(&data);
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+bool Pet::removeSpell(uint32 spell_id)
{
PetSpellMap::iterator itr = m_spells.find(spell_id);
if (itr == m_spells.end())
- return;
+ return false;
if(itr->second->state == PETSPELL_REMOVED)
- return;
+ return false;
if(itr->second->state == PETSPELL_NEW)
{
@@ -1602,9 +1443,23 @@ void Pet::removeSpell(uint16 spell_id)
itr->second->state = PETSPELL_REMOVED;
RemoveAurasDueToSpell(spell_id);
+
+ uint32 talentCost = GetTalentSpellCost(spell_id);
+ if (talentCost > 0)
+ {
+ if (m_usedTalentCount > talentCost)
+ m_usedTalentCount-=talentCost;
+ else
+ m_usedTalentCount = 0;
+ // update free talent points
+ int32 free_points = GetMaxTalentPointsForLevel(getLevel()) - m_usedTalentCount;
+ SetFreeTalentPoints(free_points > 0 ? free_points : 0);
+ }
+
+ return true;
}
-bool Pet::_removeSpell(uint16 spell_id)
+bool Pet::_removeSpell(uint32 spell_id)
{
PetSpellMap::iterator itr = m_spells.find(spell_id);
if (itr != m_spells.end())
@@ -1620,8 +1475,11 @@ void Pet::InitPetCreateSpells()
{
m_charmInfo->InitPetActionBar();
+ for (PetSpellMap::iterator i = m_spells.begin(); i != m_spells.end(); ++i)
+ delete i->second;
m_spells.clear();
- int32 usedtrainpoints = 0, petspellid;
+
+ uint32 petspellid;
PetCreateSpellEntry const* CreateSpells = objmgr.GetPetCreateSpellEntry(GetEntry());
if(CreateSpells)
{
@@ -1641,7 +1499,7 @@ void Pet::InitPetCreateSpells()
if(owner->GetTypeId() == TYPEID_PLAYER && !((Player*)owner)->HasSpell(learn_spellproto->Id))
{
if(IsPassiveSpell(petspellid)) //learn passive skills when tamed, not sure if thats right
- ((Player*)owner)->learnSpell(learn_spellproto->Id);
+ ((Player*)owner)->learnSpell(learn_spellproto->Id,false);
else
AddTeachSpell(learn_spellproto->EffectTriggerSpell[0], learn_spellproto->Id);
}
@@ -1650,23 +1508,12 @@ void Pet::InitPetCreateSpells()
petspellid = learn_spellproto->Id;
addSpell(petspellid);
-
- SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(learn_spellproto->EffectTriggerSpell[0]);
- SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(learn_spellproto->EffectTriggerSpell[0]);
-
- for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
- {
- usedtrainpoints += _spell_idx->second->reqtrainpoints;
- break;
- }
}
}
LearnPetPassives();
CastPetAuras(false);
-
- SetTP(-usedtrainpoints);
}
void Pet::CheckLearning(uint32 spellid)
@@ -1686,11 +1533,115 @@ void Pet::CheckLearning(uint32 spellid)
if(urand(0, 100) < 10)
{
- ((Player*)owner)->learnSpell(itr->second);
+ ((Player*)owner)->learnSpell(itr->second,false);
m_teachspells.erase(itr);
}
}
+bool Pet::resetTalents(bool no_cost)
+{
+ Unit *owner = GetOwner();
+ if (!owner || owner->GetTypeId()!=TYPEID_PLAYER)
+ return false;
+
+ CreatureInfo const * ci = GetCreatureInfo();
+ if(!ci)
+ return false;
+ // Check pet talent type
+ CreatureFamilyEntry const *pet_family = sCreatureFamilyStore.LookupEntry(ci->family);
+ if(!pet_family || pet_family->petTalentType < 0)
+ return false;
+
+ Player *player = (Player *)owner;
+
+ uint32 level = getLevel();
+ uint32 talentPointsForLevel = GetMaxTalentPointsForLevel(level);
+
+ if (m_usedTalentCount == 0)
+ {
+ SetFreeTalentPoints(talentPointsForLevel);
+ return false;
+ }
+
+ uint32 cost = 0;
+
+ if(!no_cost)
+ {
+ cost = resetTalentsCost();
+
+ if (player->GetMoney() < cost)
+ {
+ player->SendBuyError( BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0);
+ return false;
+ }
+ }
+
+ for (unsigned int i = 0; i < sTalentStore.GetNumRows(); i++)
+ {
+ TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
+
+ if (!talentInfo) continue;
+
+ TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
+
+ if(!talentTabInfo)
+ continue;
+
+ // unlearn only talents for pets family talent type
+ if(!((1 << pet_family->petTalentType) & talentTabInfo->petTalentMask))
+ continue;
+
+ for (int j = 0; j < 5; j++)
+ {
+ for(PetSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end();)
+ {
+ if(itr->second->state == PETSPELL_REMOVED)
+ {
+ ++itr;
+ continue;
+ }
+ // remove learned spells (all ranks)
+ uint32 itrFirstId = spellmgr.GetFirstSpellInChain(itr->first);
+
+ // unlearn if first rank is talent or learned by talent
+ if (itrFirstId == talentInfo->RankID[j] || spellmgr.IsSpellLearnToSpell(talentInfo->RankID[j],itrFirstId))
+ {
+ removeSpell(itr->first);
+ itr = m_spells.begin();
+ continue;
+ }
+ else
+ ++itr;
+ }
+ }
+ }
+
+ SetFreeTalentPoints(talentPointsForLevel);
+
+ if(!no_cost)
+ {
+ player->ModifyMoney(-(int32)cost);
+
+ m_resetTalentsCost = cost;
+ m_resetTalentsTime = time(NULL);
+ }
+ player->PetSpellInitialize();
+ return true;
+}
+
+void Pet::InitTalentForLevel()
+{
+ uint32 level = getLevel();
+ uint32 talentPointsForLevel = GetMaxTalentPointsForLevel(level);
+ // Reset talents in case low level (on level down) or wrong points for level (hunter can unlearn TP increase talent)
+ if(talentPointsForLevel == 0 || m_usedTalentCount > talentPointsForLevel)
+ {
+ // Remove all talent points
+ resetTalents(true);
+ }
+ SetFreeTalentPoints(talentPointsForLevel - m_usedTalentCount);
+}
+
uint32 Pet::resetTalentsCost() const
{
uint32 days = (sWorld.GetGameTime() - m_resetTalentsTime)/DAY;
@@ -1709,6 +1660,15 @@ uint32 Pet::resetTalentsCost() const
return (m_resetTalentsCost + 1*GOLD > 10*GOLD ? 10*GOLD : m_resetTalentsCost + 1*GOLD);
}
+uint8 Pet::GetMaxTalentPointsForLevel(uint32 level)
+{
+ uint8 points = (level >= 20) ? ((level - 16) / 4) : 0;
+ // Mod points from owner SPELL_AURA_MOD_PET_TALENT_POINTS
+ if (Unit *owner = GetOwner())
+ points+=owner->GetTotalAuraModifier(SPELL_AURA_MOD_PET_TALENT_POINTS);
+ return points;
+}
+
void Pet::ToggleAutocast(uint32 spellid, bool apply)
{
if(IsPassiveSpell(spellid))
@@ -1719,13 +1679,15 @@ void Pet::ToggleAutocast(uint32 spellid, bool apply)
// && tempSpell->EffectImplicitTargetA[0] != TARGET_CHAIN_DAMAGE)
// return;
- PetSpellMap::const_iterator itr = m_spells.find((uint16)spellid);
+ PetSpellMap::const_iterator itr = m_spells.find(spellid);
int i;
if(apply)
{
- for (i = 0; i < m_autospells.size() && m_autospells[i] != spellid; i++);
+ for (i = 0; i < m_autospells.size() && m_autospells[i] != spellid; i++)
+ ; // just search
+
if (i == m_autospells.size())
{
m_autospells.push_back(spellid);
@@ -1736,7 +1698,9 @@ void Pet::ToggleAutocast(uint32 spellid, bool apply)
else
{
AutoSpellList::iterator itr2 = m_autospells.begin();
- for (i = 0; i < m_autospells.size() && m_autospells[i] != spellid; i++, itr2++);
+ for (i = 0; i < m_autospells.size() && m_autospells[i] != spellid; i++, itr2++)
+ ; // just search
+
if (i < m_autospells.size())
{
m_autospells.erase(itr2);
@@ -1746,10 +1710,11 @@ void Pet::ToggleAutocast(uint32 spellid, bool apply)
}
}
-bool Pet::Create(uint32 guidlow, Map *map, uint32 Entry, uint32 pet_number)
+bool Pet::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 pet_number)
{
SetMapId(map->GetId());
SetInstanceId(map->GetInstanceId());
+ SetPhaseMask(phaseMask,false);
Object::_Create(guidlow, pet_number, HIGHGUID_PET);
@@ -1759,8 +1724,7 @@ bool Pet::Create(uint32 guidlow, Map *map, uint32 Entry, uint32 pet_number)
if(!InitEntry(Entry))
return false;
- SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE );
- SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY | UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5 );
+ SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE);
if(getPetType() == MINI_PET) // always non-attackable
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
@@ -1770,7 +1734,8 @@ bool Pet::Create(uint32 guidlow, Map *map, uint32 Entry, uint32 pet_number)
bool Pet::HasSpell(uint32 spell) const
{
- return (m_spells.find(spell) != m_spells.end());
+ PetSpellMap::const_iterator itr = m_spells.find(spell);
+ return (itr != m_spells.end() && itr->second->state != PETSPELL_REMOVED );
}
// Get all passive spells in our skill line
@@ -1791,7 +1756,7 @@ void Pet::LearnPetPassives()
// Passive 01~10, Passive 00 (20782, not used), Ferocious Inspiration (34457)
// Scale 01~03 (34902~34904, bonus from owner, not used)
for(PetFamilySpellsSet::const_iterator petSet = petStore->second.begin(); petSet != petStore->second.end(); ++petSet)
- addSpell(*petSet, ACT_DECIDE, PETSPELL_NEW, 0xffff, PETSPELL_FAMILY);
+ addSpell(*petSet, ACT_DECIDE, PETSPELL_NEW, PETSPELL_FAMILY);
}
}
diff --git a/src/game/Pet.h b/src/game/Pet.h
index 9d187b24b45..f863051b74d 100644
--- a/src/game/Pet.h
+++ b/src/game/Pet.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -52,16 +52,6 @@ enum HappinessState
HAPPY = 3
};
-enum LoyaltyLevel
-{
- REBELLIOUS = 1,
- UNRULY = 2,
- SUBMISSIVE = 3,
- DEPENDABLE = 4,
- FAITHFUL = 5,
- BEST_FRIEND = 6
-};
-
enum PetSpellState
{
PETSPELL_UNCHANGED = 0,
@@ -78,7 +68,6 @@ enum PetSpellType
struct PetSpell
{
- uint16 slotId;
uint16 active;
PetSpellState state : 16;
@@ -116,15 +105,12 @@ enum PetNameInvalidReason
PET_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 16
};
-typedef UNORDERED_MAP<uint16, PetSpell*> PetSpellMap;
+typedef UNORDERED_MAP<uint32, PetSpell*> PetSpellMap;
typedef std::map<uint32,uint32> TeachSpellMap;
typedef std::vector<uint32> AutoSpellList;
#define HAPPINESS_LEVEL_SIZE 333000
-extern const uint32 LevelUpLoyalty[6];
-extern const uint32 LevelStartLoyalty[6];
-
#define ACTIVE_SPELLS_MAX 4
#define OWNER_MAX_DISTANCE 100
@@ -146,9 +132,9 @@ class Pet : public Creature
bool isControlled() const { return getPetType()==SUMMON_PET || getPetType()==HUNTER_PET; }
bool isTemporarySummoned() const { return m_duration > 0; }
- bool Create (uint32 guidlow, Map *map, uint32 Entry, uint32 pet_number);
+ bool Create (uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 pet_number);
bool CreateBaseAtCreature(Creature* creature);
- bool LoadPetFromDB( Unit* owner,uint32 petentry = 0,uint32 petnumber = 0, bool current = false );
+ bool LoadPetFromDB( Player* owner,uint32 petentry = 0,uint32 petnumber = 0, bool current = false );
void SavePetToDB(PetSaveMode mode);
void Remove(PetSaveMode mode, bool returnreagent = false);
static void DeleteFromDB(uint32 guidlow);
@@ -167,14 +153,7 @@ class Pet : public Creature
void RegenerateFocus();
void LooseHappiness();
- void TickLoyaltyChange();
- void ModifyLoyalty(int32 addvalue);
HappinessState GetHappinessState();
- uint32 GetMaxLoyaltyPoints(uint32 level);
- uint32 GetStartLoyaltyPoints(uint32 level);
- void KillLoyaltyBonus(uint32 level);
- uint32 GetLoyaltyLevel() { return GetByteValue(UNIT_FIELD_BYTES_1, 1); }
- void SetLoyaltyLevel(LoyaltyLevel level);
void GivePetXP(uint32 xp);
void GivePetLevel(uint32 level);
bool InitStatsForLevel(uint32 level);
@@ -194,10 +173,8 @@ class Pet : public Creature
void UpdateAttackPowerAndDamage(bool ranged = false);
void UpdateDamagePhysical(WeaponAttackType attType);
- bool CanTakeMoreActiveSpells(uint32 SpellIconID);
- void ToggleAutocast(uint32 spellid, bool apply);
- bool HasTPForSpell(uint32 spellid);
- int32 GetTPForSpell(uint32 spellid);
+ bool CanTakeMoreActiveSpells(uint32 SpellIconID);
+ void ToggleAutocast(uint32 spellid, bool apply);
bool HasSpell(uint32 spell) const;
void AddTeachSpell(uint32 learned_id, uint32 source_id) { m_teachspells[learned_id] = source_id; }
@@ -213,10 +190,12 @@ class Pet : public Creature
void _LoadSpells();
void _SaveSpells();
- bool addSpell(uint16 spell_id,uint16 active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, uint16 slot_id=0xffff, PetSpellType type = PETSPELL_NORMAL);
- bool learnSpell(uint16 spell_id);
- void removeSpell(uint16 spell_id);
- bool _removeSpell(uint16 spell_id);
+ bool addSpell(uint32 spell_id,uint16 active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, PetSpellType type = PETSPELL_NORMAL);
+ bool learnSpell(uint32 spell_id);
+ void learnLevelupSpells();
+ bool unlearnSpell(uint32 spell_id);
+ bool removeSpell(uint32 spell_id);
+ bool _removeSpell(uint32 spell_id);
PetSpellMap m_spells;
TeachSpellMap m_teachspells;
@@ -224,32 +203,33 @@ class Pet : public Creature
void InitPetCreateSpells();
void CheckLearning(uint32 spellid);
+
+ bool resetTalents(bool no_cost = false);
uint32 resetTalentsCost() const;
+ void InitTalentForLevel();
- void SetTP(int32 TP);
- int32 GetDispTP();
+ uint8 GetMaxTalentPointsForLevel(uint32 level);
+ uint8 GetFreeTalentPoints() { return GetByteValue(UNIT_FIELD_BYTES_1, 1); }
+ void SetFreeTalentPoints(uint8 points) { SetByteValue(UNIT_FIELD_BYTES_1, 1, points); }
- int32 m_TrainingPoints;
uint32 m_resetTalentsCost;
time_t m_resetTalentsTime;
+ uint32 m_usedTalentCount;
- uint64 GetAuraUpdateMask() { return m_auraUpdateMask; }
- void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); }
- void UnsetAuraUpdateMask(uint8 slot) { m_auraUpdateMask &= ~(uint64(1) << slot); }
- void ResetAuraUpdateMask() { m_auraUpdateMask = 0; }
+ const uint64& GetAuraUpdateMaskForRaid() const { return m_auraRaidUpdateMask; }
+ void SetAuraUpdateMaskForRaid(uint8 slot) { m_auraRaidUpdateMask |= (uint64(1) << slot); }
+ void ResetAuraUpdateMaskForRaid() { m_auraRaidUpdateMask = 0; }
DeclinedName const* GetDeclinedNames() const { return m_declinedname; }
bool m_removed; // prevent overwrite pet state in DB at next Pet::Update if pet already removed(saved)
protected:
- uint32 m_regenTimer;
uint32 m_happinessTimer;
- uint32 m_loyaltyTimer;
PetType m_petType;
int32 m_duration; // time until unsummon (used mostly for summoned guardians and not used for controlled pets)
- int32 m_loyaltyPoints;
int32 m_bonusdamage;
- uint64 m_auraUpdateMask;
+ uint64 m_auraRaidUpdateMask;
+ bool m_loading;
DeclinedName *m_declinedname;
diff --git a/src/game/PetAI.cpp b/src/game/PetAI.cpp
index 67607defba0..4545b9a395f 100644
--- a/src/game/PetAI.cpp
+++ b/src/game/PetAI.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -139,11 +139,11 @@ void PetAI::UpdateAI(const uint32 diff)
else
m_updateAlliesTimer -= diff;
- if (inCombat && i_pet.getVictim() == NULL)
+ if (inCombat && !i_pet.getVictim())
_stopAttack();
// i_pet.getVictim() can't be used for check in case stop fighting, i_pet.getVictim() clear at Unit death etc.
- if( i_pet.getVictim() != NULL )
+ if( i_pet.getVictim() )
{
if( _needToStop() )
{
diff --git a/src/game/PetAI.h b/src/game/PetAI.h
index b81bdd8e14f..ceaa00e7ed3 100644
--- a/src/game/PetAI.h
+++ b/src/game/PetAI.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp
index e4269ddafd6..da8ce311462 100644
--- a/src/game/PetHandler.cpp
+++ b/src/game/PetHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -106,7 +106,7 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
}
// only place where pet can be player
pet->clearUnitState(UNIT_STAT_FOLLOW);
- uint64 selguid = _player->GetSelection();
+ const uint64& selguid = _player->GetSelection();
Unit *TargetUnit = ObjectAccessor::GetUnit(*_player, selguid);
if(!TargetUnit)
return;
@@ -118,27 +118,35 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
//if(!pet->IsWithinLOSInMap(TargetUnit))
// return;
- if(pet->GetTypeId() != TYPEID_PLAYER)
+ // This is true if pet has no target or has target but targets differs.
+ if(pet->getVictim() != TargetUnit)
{
- if (((Creature*)pet)->AI())
- ((Creature*)pet)->AI()->AttackStart(TargetUnit);
+ if (pet->getVictim())
+ pet->AttackStop();
- //10% chance to play special pet attack talk, else growl
- if(((Creature*)pet)->isPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != TargetUnit && urand(0, 100) < 10)
- pet->SendPetTalk((uint32)PET_TALK_ATTACK);
- else
+ if(pet->GetTypeId() != TYPEID_PLAYER)
{
- // 90% chance for pet and 100% chance for charmed creature
- pet->SendPetAIReaction(guid1);
+ pet->GetMotionMaster()->Clear();
+ if (((Creature*)pet)->AI())
+ ((Creature*)pet)->AI()->AttackStart(TargetUnit);
+
+ //10% chance to play special pet attack talk, else growl
+ if(((Creature*)pet)->isPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != TargetUnit && urand(0, 100) < 10)
+ pet->SendPetTalk((uint32)PET_TALK_ATTACK);
+ else
+ {
+ // 90% chance for pet and 100% chance for charmed creature
+ pet->SendPetAIReaction(guid1);
+ }
}
- }
- else // charmed player
- {
- if(pet->getVictim() && pet->getVictim() != TargetUnit)
- pet->AttackStop();
+ else // charmed player
+ {
+ if(pet->getVictim() && pet->getVictim() != TargetUnit)
+ pet->AttackStop();
- pet->Attack(TargetUnit,true);
- pet->SendPetAIReaction(guid1);
+ pet->Attack(TargetUnit,true);
+ pet->SendPetAIReaction(guid1);
+ }
}
break;
}
@@ -174,19 +182,17 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
break;
}
break;
- case ACT_DISABLED: //0x8100 spell (disabled), ignore
- case ACT_CAST: //0x0100
- case ACT_ENABLED: //0xc100 spell
+ case ACT_DISABLED: // 0x8100 spell (disabled), ignore
+ case ACT_PASSIVE: // 0x0100
+ case ACT_ENABLED: // 0xC100 spell
{
- Unit* unit_target;
- if(guid2)
- unit_target = ObjectAccessor::GetUnit(*_player,guid2);
- else
- unit_target = NULL;
-
+ Unit* unit_target = NULL;
if (((Creature*)pet)->GetGlobalCooldown() > 0)
return;
+ if(guid2)
+ unit_target = ObjectAccessor::GetUnit(*_player,guid2);
+
// do not cast unknown spells
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellid );
if(!spellInfo)
@@ -211,7 +217,7 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
int16 result = spell->PetCanCast(unit_target);
- //auto turn to target unless possessed
+ //auto turn to target unless possessed
if(result == SPELL_FAILED_UNIT_NOT_INFRONT && !pet->isPossessed())
{
pet->SetInFront(unit_target);
@@ -242,12 +248,15 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
if( unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet->isPossessed())
{
- pet->clearUnitState(UNIT_STAT_FOLLOW);
- if(pet->getVictim())
- pet->AttackStop();
- pet->GetMotionMaster()->Clear();
- if (((Creature*)pet)->AI())
- ((Creature*)pet)->AI()->AttackStart(unit_target);
+ // This is true if pet has no target or has target but targets differs.
+ if (pet->getVictim() != unit_target)
+ {
+ if (pet->getVictim())
+ pet->AttackStop();
+ pet->GetMotionMaster()->Clear();
+ if (((Creature*)pet)->AI())
+ ((Creature*)pet)->AI()->AttackStart(unit_target);
+ }
}
spell->prepare(&(spell->m_targets));
@@ -257,15 +266,12 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
if(pet->isPossessed())
{
WorldPacket data(SMSG_CAST_FAILED, (4+1+1));
- data << uint32(spellid) << uint8(2) << uint8(result);
+ data << uint8(0) << uint32(spellid) << uint8(result);
switch (result)
{
case SPELL_FAILED_REQUIRES_SPELL_FOCUS:
data << uint32(spellInfo->RequiresSpellFocus);
break;
- case SPELL_FAILED_REQUIRES_AREA:
- data << uint32(spellInfo->AreaId);
- break;
}
SendPacket(&data);
}
@@ -302,7 +308,7 @@ void WorldSession::HandlePetNameQuery( WorldPacket & recv_data )
void WorldSession::SendPetNameQuery( uint64 petguid, uint32 petnumber)
{
- Creature* pet = ObjectAccessor::GetCreatureOrPet(*_player, petguid);
+ Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, petguid);
if(!pet || !pet->GetCharmInfo() || pet->GetCharmInfo()->GetPetNumber() != petnumber)
return;
@@ -344,7 +350,7 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data )
if(ObjectAccessor::FindPlayer(petguid))
return;
- Creature* pet = ObjectAccessor::GetCreatureOrPet(*_player, petguid);
+ Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, petguid);
if(!pet || (pet != _player->GetPet() && pet != _player->GetCharm()))
{
@@ -369,7 +375,7 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data )
sLog.outDetail( "Player %s has changed pet spell action. Position: %u, Spell: %u, State: 0x%X\n", _player->GetName(), position, spell_id, act_state);
//if it's act for spell (en/disable/cast) and there is a spell given (0 = remove spell) which pet doesn't know, don't add
- if(!((act_state == ACT_ENABLED || act_state == ACT_DISABLED || act_state == ACT_CAST) && spell_id && !pet->HasSpell(spell_id)))
+ if(!((act_state == ACT_ENABLED || act_state == ACT_DISABLED || act_state == ACT_PASSIVE) && spell_id && !pet->HasSpell(spell_id)))
{
//sign for autocast
if(act_state == ACT_ENABLED && spell_id)
@@ -481,7 +487,7 @@ void WorldSession::HandlePetAbandon( WorldPacket & recv_data )
sLog.outDetail( "HandlePetAbandon. CMSG_PET_ABANDON pet guid is %u", GUID_LOPART(guid) );
// pet/charmed
- Creature* pet = ObjectAccessor::GetCreatureOrPet(*_player, guid);
+ Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, guid);
if(pet)
{
if(pet->isPet())
@@ -510,11 +516,11 @@ void WorldSession::HandlePetUnlearnOpcode(WorldPacket& recvPacket)
sLog.outDetail("CMSG_PET_UNLEARN");
uint64 guid;
- recvPacket >> guid;
+ recvPacket >> guid; // Pet guid
Pet* pet = _player->GetPet();
- if(!pet || pet->getPetType() != HUNTER_PET || pet->m_spells.size() <= 1)
+ if(!pet || pet->getPetType() != HUNTER_PET || pet->m_usedTalentCount == 0)
return;
if(guid != pet->GetGUID())
@@ -529,38 +535,7 @@ void WorldSession::HandlePetUnlearnOpcode(WorldPacket& recvPacket)
sLog.outError("WorldSession::HandlePetUnlearnOpcode: object "I64FMTD" is considered pet-like but doesn't have a charminfo!", pet->GetGUID());
return;
}
-
- uint32 cost = pet->resetTalentsCost();
-
- if (GetPlayer()->GetMoney() < cost)
- {
- GetPlayer()->SendBuyError( BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0);
- return;
- }
-
- for(PetSpellMap::iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end();)
- {
- uint32 spell_id = itr->first; // Pet::removeSpell can invalidate iterator at erase NEW spell
- ++itr;
- pet->removeSpell(spell_id);
- }
-
- pet->SetTP(pet->getLevel() * (pet->GetLoyaltyLevel() - 1));
-
- for(uint8 i = 0; i < 10; i++)
- {
- if(charmInfo->GetActionBarEntry(i)->SpellOrAction && charmInfo->GetActionBarEntry(i)->Type == ACT_ENABLED || charmInfo->GetActionBarEntry(i)->Type == ACT_DISABLED)
- charmInfo->GetActionBarEntry(i)->SpellOrAction = 0;
- }
-
- // relearn pet passives
- pet->LearnPetPassives();
-
- pet->m_resetTalentsTime = time(NULL);
- pet->m_resetTalentsCost = cost;
- GetPlayer()->ModifyMoney(-(int32)cost);
-
- GetPlayer()->PetSpellInitialize();
+ pet->resetTalents();
}
void WorldSession::HandlePetSpellAutocastOpcode( WorldPacket& recvPacket )
@@ -580,7 +555,7 @@ void WorldSession::HandlePetSpellAutocastOpcode( WorldPacket& recvPacket )
if(ObjectAccessor::FindPlayer(guid))
return;
- Creature* pet=ObjectAccessor::GetCreatureOrPet(*_player,guid);
+ Creature* pet=ObjectAccessor::GetCreatureOrPetOrVehicle(*_player,guid);
if(!pet || (pet != _player->GetPet() && pet != _player->GetCharm()))
{
@@ -616,11 +591,15 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
{
sLog.outDetail("WORLD: CMSG_PET_CAST_SPELL");
- CHECK_PACKET_SIZE(recvPacket,8+4);
+ CHECK_PACKET_SIZE(recvPacket,8+1+4+1);
uint64 guid;
uint32 spellid;
+ uint8 cast_count;
+ uint8 unk_flags; // flags (if 0x02 - some additional data are received)
+
+ recvPacket >> guid >> cast_count >> spellid >> unk_flags;
- recvPacket >> guid >> spellid;
+ sLog.outDebug("WORLD: CMSG_PET_CAST_SPELL, cast_count: %u, spellid %u, unk_flags %u", cast_count, spellid, unk_flags);
// This opcode is also sent from charmed and possessed units (players and creatures)
if(!_player->GetPet() && !_player->GetCharm())
@@ -655,6 +634,7 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
caster->clearUnitState(UNIT_STAT_FOLLOW);
Spell *spell = new Spell(caster, spellInfo, false);
+ spell->m_cast_count = cast_count; // probably pending spell cast
spell->m_targets = targets;
int16 result = spell->PetCanCast(NULL);
@@ -713,3 +693,129 @@ void WorldSession::SendPetNameInvalid(uint32 error, const std::string& name, Dec
data << uint8(0);
SendPacket(&data);
}
+
+void WorldSession::HandlePetLearnTalent( WorldPacket & recv_data )
+{
+ sLog.outDebug("WORLD: CMSG_PET_LEARN_TALENT");
+ recv_data.hexlike();
+
+ CHECK_PACKET_SIZE(recv_data, 8+4+4);
+
+ uint64 guid;
+ uint32 talent_id, requested_rank;
+ recv_data >> guid >> talent_id >> requested_rank;
+
+ Pet *pet = _player->GetPet();
+
+ if(!pet)
+ return;
+
+ if(guid != pet->GetGUID())
+ return;
+
+ uint32 CurTalentPoints = pet->GetFreeTalentPoints();
+
+ if(CurTalentPoints == 0)
+ return;
+
+ if (requested_rank > 4)
+ return;
+
+ TalentEntry const *talentInfo = sTalentStore.LookupEntry(talent_id);
+
+ if(!talentInfo)
+ return;
+
+ TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab);
+
+ if(!talentTabInfo)
+ return;
+
+ CreatureInfo const *ci = pet->GetCreatureInfo();
+
+ if(!ci)
+ return;
+
+ CreatureFamilyEntry const *pet_family = sCreatureFamilyStore.LookupEntry(ci->family);
+
+ if(!pet_family)
+ return;
+
+ if(pet_family->petTalentType < 0) // not hunter pet
+ return;
+
+ // prevent learn talent for different family (cheating)
+ if(!((1 << pet_family->petTalentType) & talentTabInfo->petTalentMask))
+ return;
+
+ // prevent skip talent ranks (cheating)
+ if(requested_rank > 0 && !pet->HasSpell(talentInfo->RankID[requested_rank-1]))
+ return;
+
+ // Check if it requires another talent
+ if (talentInfo->DependsOn > 0)
+ {
+ if(TalentEntry const *depTalentInfo = sTalentStore.LookupEntry(talentInfo->DependsOn))
+ {
+ bool hasEnoughRank = false;
+ for (int i = talentInfo->DependsOnRank; i <= 4; i++)
+ {
+ if (depTalentInfo->RankID[i] != 0)
+ if (pet->HasSpell(depTalentInfo->RankID[i]))
+ hasEnoughRank = true;
+ }
+ if (!hasEnoughRank)
+ return;
+ }
+ }
+
+ // Find out how many points we have in this field
+ uint32 spentPoints = 0;
+
+ uint32 tTab = talentInfo->TalentTab;
+ if (talentInfo->Row > 0)
+ {
+ unsigned int numRows = sTalentStore.GetNumRows();
+ for (unsigned int i = 0; i < numRows; i++) // Loop through all talents.
+ {
+ // Someday, someone needs to revamp
+ const TalentEntry *tmpTalent = sTalentStore.LookupEntry(i);
+ if (tmpTalent) // the way talents are tracked
+ {
+ if (tmpTalent->TalentTab == tTab)
+ {
+ for (int j = 0; j <= 4; j++)
+ {
+ if (tmpTalent->RankID[j] != 0)
+ {
+ if (pet->HasSpell(tmpTalent->RankID[j]))
+ {
+ spentPoints += j + 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // not have required min points spent in talent tree
+ if(spentPoints < (talentInfo->Row * 3))
+ return;
+
+ // spell not set in talent.dbc
+ uint32 spellid = talentInfo->RankID[requested_rank];
+ if( spellid == 0 )
+ {
+ sLog.outError("Talent.dbc have for talent: %u Rank: %u spell id = 0", talent_id, requested_rank);
+ return;
+ }
+
+ // already known
+ if(pet->HasSpell(spellid))
+ return;
+
+ // learn! (other talent ranks will unlearned at learning)
+ pet->learnSpell(spellid);
+ sLog.outDetail("TalentID: %u Rank: %u Spell: %u\n", talent_id, requested_rank, spellid);
+}
diff --git a/src/game/PetitionsHandler.cpp b/src/game/PetitionsHandler.cpp
index 8fc18b1c259..5911af4e560 100644
--- a/src/game/PetitionsHandler.cpp
+++ b/src/game/PetitionsHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -199,9 +199,9 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recv_data)
if(!charter)
return;
- charter->SetUInt32Value(ITEM_FIELD_ENCHANTMENT, charter->GetGUIDLow());
- // ITEM_FIELD_ENCHANTMENT is guild/arenateam id
- // ITEM_FIELD_ENCHANTMENT+1 is current signatures count (showed on item)
+ charter->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1, charter->GetGUIDLow());
+ // ITEM_FIELD_ENCHANTMENT_1_1 is guild/arenateam id
+ // ITEM_FIELD_ENCHANTMENT_1_1+1 is current signatures count (showed on item)
charter->SetState(ITEM_CHANGED, _player);
_player->SendNewItem(charter, 1, true, false);
@@ -565,7 +565,7 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data)
// update signs count on charter, required testing...
//Item *item = _player->GetItemByGuid(petitionguid));
//if(item)
- // item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT+1, signs);
+ // item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1+1, signs);
// update for owner if online
if(Player *owner = objmgr.GetPlayer(ownerguid))
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 02e6e94f94c..2dba5867129 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -64,6 +64,7 @@
#include "Spell.h"
#include "SocialMgr.h"
#include "GameEvent.h"
+#include "AchievementMgr.h"
#include <cmath>
@@ -132,7 +133,7 @@ PlayerTaxi::PlayerTaxi()
memset(m_taximask, 0, sizeof(m_taximask));
}
-void PlayerTaxi::InitTaxiNodesForLevel(uint32 race, uint32 level)
+void PlayerTaxi::InitTaxiNodesForLevel(uint32 race, uint32 chrClass, uint32 level)
{
// capital and taxi hub masks
switch(race)
@@ -149,6 +150,13 @@ void PlayerTaxi::InitTaxiNodesForLevel(uint32 race, uint32 level)
case RACE_BLOODELF: SetTaximaskNode(82); break; // Blood Elf
case RACE_DRAENEI: SetTaximaskNode(94); break; // Draenei
}
+
+ switch(chrClass)
+ {
+ case CLASS_DEATH_KNIGHT: // TODO: figure out initial known nodes
+ break;
+ }
+
// new continent starting masks (It will be accessible only at new map)
switch(Player::TeamForRace(race))
{
@@ -188,7 +196,7 @@ void PlayerTaxi::AppendTaximaskTo( ByteBuffer& data, bool all )
}
}
-bool PlayerTaxi::LoadTaxiDestinationsFromString( const std::string& values )
+bool PlayerTaxi::LoadTaxiDestinationsFromString( const std::string& values, uint32 team )
{
ClearTaxiDestinations();
@@ -216,6 +224,10 @@ bool PlayerTaxi::LoadTaxiDestinationsFromString( const std::string& values )
return false;
}
+ // can't load taxi path without mount set (quest taxi path?)
+ if(!objmgr.GetTaxiMount(GetTaxiSource(),team))
+ return false;
+
return true;
}
@@ -245,13 +257,22 @@ uint32 PlayerTaxi::GetCurrentTaxiPath() const
return path;
}
+std::ostringstream& operator<< (std::ostringstream& ss, PlayerTaxi const& taxi)
+{
+ ss << "'";
+ for(int i = 0; i < TaxiMaskSize; ++i)
+ ss << taxi.m_taximask[i] << " ";
+ ss << "'";
+ return ss;
+}
+
//== Player ====================================================
const int32 Player::ReputationRank_Length[MAX_REPUTATION_RANK] = {36000, 3000, 3000, 3000, 6000, 12000, 21000, 1000};
UpdateMask Player::updateVisualBits;
-Player::Player (WorldSession *session): Unit()
+Player::Player (WorldSession *session): Unit(), m_achievementMgr(this)
{
m_transport = 0;
@@ -280,6 +301,7 @@ Player::Player (WorldSession *session): Unit()
m_comboPoints = 0;
m_usedTalentCount = 0;
+ m_questRewardTalentCount = 0;
m_regenTimer = 0;
m_weaponChangeTimer = 0;
@@ -306,7 +328,7 @@ Player::Player (WorldSession *session): Unit()
// group is initialized in the reference constructor
SetGroupInvite(NULL);
m_groupUpdateMask = 0;
- m_auraUpdateMask = 0;
+ m_auraRaidUpdateMask = 0;
duel = NULL;
@@ -335,7 +357,7 @@ Player::Player (WorldSession *session): Unit()
m_regenTimer = 0;
m_weaponChangeTimer = 0;
m_breathTimer = 0;
- m_isunderwater = 0;
+ m_isunderwater = UNDERWATER_NONE;
m_isInWater = false;
m_drunkTimer = 0;
m_drunk = 0;
@@ -362,6 +384,7 @@ Player::Player (WorldSession *session): Unit()
m_canParry = false;
m_canBlock = false;
m_canDualWield = false;
+ m_canTitanGrip = false;
m_ammoDPS = 0.0f;
m_temporaryUnsummonedPetNumber = 0;
@@ -406,6 +429,14 @@ Player::Player (WorldSession *session): Unit()
m_auraBaseMod[i][PCT_MOD] = 1.0f;
}
+ for (int i = 0; i < MAX_COMBAT_RATING; i++)
+ m_baseRatingValue[i] = 0;
+
+ m_baseSpellDamage = 0;
+ m_baseSpellHealing = 0;
+ m_baseFeralAP = 0;
+ m_baseManaRegen = 0;
+
// Honor System
m_lastHonorUpdateTime = time(NULL);
@@ -419,6 +450,8 @@ Player::Player (WorldSession *session): Unit()
//Default movement to run mode
m_unit_movement_flags = 0;
+ m_mover = NULL;
+
m_miniPet = 0;
m_bgAfkReportedTimer = 0;
m_contestedPvPTimer = 0;
@@ -428,6 +461,8 @@ Player::Player (WorldSession *session): Unit()
m_isActive = true;
m_farsightVision = false;
+
+ m_runes = NULL;
}
Player::~Player ()
@@ -475,6 +510,7 @@ Player::~Player ()
RemovePossess(false);
delete m_declinedname;
+ delete m_runes;
}
void Player::CleanupsBeforeDelete()
@@ -520,24 +556,8 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
uint8 powertype = cEntry->powerType;
- uint32 unitfield;
-
- switch(powertype)
- {
- case POWER_ENERGY:
- case POWER_MANA:
- unitfield = 0x00000000;
- break;
- case POWER_RAGE:
- unitfield = 0x00110000;
- break;
- default:
- sLog.outError("Invalid default powertype %u for player (class %u)",powertype,class_);
- return false;
- }
-
- SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE );
- SetFloatValue(UNIT_FIELD_COMBATREACH, DEFAULT_COMBAT_REACH );
+ SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE);
+ SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f);
switch(gender)
{
@@ -560,12 +580,13 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
uint32 RaceClassGender = ( race ) | ( class_ << 8 ) | ( gender << 16 );
SetUInt32Value(UNIT_FIELD_BYTES_0, ( RaceClassGender | ( powertype << 24 ) ) );
- SetUInt32Value(UNIT_FIELD_BYTES_1, unitfield);
- SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY | UNIT_BYTE2_FLAG_UNK5 );
- SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE );
+ 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
- //-1 is default value
+ // -1 is default value
SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1));
SetUInt32Value(PLAYER_BYTES, (skin | (face << 8) | (hairStyle << 16) | (hairColor << 24)));
@@ -577,6 +598,7 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
SetUInt32Value( PLAYER_GUILD_TIMESTAMP, 0 );
SetUInt64Value( PLAYER__FIELD_KNOWN_TITLES, 0 ); // 0=disabled
+ SetUInt64Value( PLAYER__FIELD_KNOWN_TITLES1, 0 ); // 0=disabled
SetUInt32Value( PLAYER_CHOSEN_TITLE, 0 );
SetUInt32Value( PLAYER_FIELD_KILLS, 0 );
SetUInt32Value( PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0 );
@@ -584,10 +606,20 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
SetUInt32Value( PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0 );
// set starting level
+ uint32 start_level = getClass() != CLASS_DEATH_KNIGHT
+ ? sWorld.getConfig(CONFIG_START_PLAYER_LEVEL)
+ : sWorld.getConfig(CONFIG_START_HEROIC_PLAYER_LEVEL);
+
if (GetSession()->GetSecurity() >= SEC_MODERATOR)
- SetUInt32Value (UNIT_FIELD_LEVEL, sWorld.getConfig(CONFIG_START_GM_LEVEL));
- else
- SetUInt32Value (UNIT_FIELD_LEVEL, sWorld.getConfig(CONFIG_START_PLAYER_LEVEL));
+ {
+ uint32 gm_level = sWorld.getConfig(CONFIG_START_GM_LEVEL);
+ if(gm_level > start_level)
+ start_level = gm_level;
+ }
+
+ SetUInt32Value(UNIT_FIELD_LEVEL, start_level);
+
+ InitRunes();
SetUInt32Value (PLAYER_FIELD_COINAGE, sWorld.getConfig(CONFIG_START_PLAYER_MONEY));
SetUInt32Value (PLAYER_FIELD_HONOR_CURRENCY, sWorld.getConfig(CONFIG_START_HONOR_POINTS));
@@ -651,6 +683,7 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
// base stats and related field values
InitStatsForLevel();
InitTaxiNodesForLevel();
+ InitGlyphsForLevel();
InitTalentForLevel();
InitPrimaryProffesions(); // to max set before any spell added
@@ -663,8 +696,16 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
SetPower(POWER_MANA,GetMaxPower(POWER_MANA));
}
+ if(getPowerType() == POWER_RUNIC_POWER)
+ {
+ SetPower(POWER_RUNE, 8);
+ SetMaxPower(POWER_RUNE, 8);
+ SetPower(POWER_RUNIC_POWER, 0);
+ SetMaxPower(POWER_RUNIC_POWER, 1000);
+ }
+
// original spells
- learnDefaultSpells(true);
+ learnDefaultSpells();
// original action bar
std::list<uint16>::const_iterator action_itr[4];
@@ -706,6 +747,11 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
uint32 item_id = oEntry->ItemId[j];
+
+ // Hack for not existed item id in dbc 3.0.3
+ if(item_id==40582)
+ continue;
+
ItemPrototype const* iProto = objmgr.GetItemPrototype(item_id);
if(!iProto)
{
@@ -713,7 +759,9 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
continue;
}
- uint32 count = iProto->Stackable; // max stack by default (mostly 1)
+ // max stack by default (mostly 1), 1 for infinity stackable
+ uint32 count = iProto->Stackable > 0 ? uint32(iProto->Stackable) : 1;
+
if(iProto->Class==ITEM_CLASS_CONSUMABLE && iProto->SubClass==ITEM_SUBCLASS_FOOD)
{
switch(iProto->Spells[0].SpellCategory)
@@ -872,39 +920,40 @@ void Player::EnvironmentalDamage(uint64 guid, EnviromentalDamage type, uint32 da
void Player::HandleDrowning()
{
- if(!m_isunderwater)
+ if(!(m_isunderwater&~UNDERWATER_INLAVA))
return;
//if player is GM, have waterbreath, is dead or if breathing is disabled then return
- if(waterbreath || isGameMaster() || !isAlive() || GetSession()->GetSecurity() >= sWorld.getConfig(CONFIG_DISABLE_BREATHING))
+ if(isGameMaster() || !isAlive() || HasAuraType(SPELL_AURA_WATER_BREATHING) || GetSession()->GetSecurity() >= sWorld.getConfig(CONFIG_DISABLE_BREATHING))
{
StopMirrorTimer(BREATH_TIMER);
- m_isunderwater = 0;
+ // drop every flag _except_ LAVA - otherwise waterbreathing will prevent lava damage
+ m_isunderwater &= UNDERWATER_INLAVA;
return;
}
- uint32 UnderWaterTime = 1*MINUTE*1000; // default length 1 min
+ uint32 UnderWaterTime = 3*MINUTE*1000; // default duration
AuraList const& mModWaterBreathing = GetAurasByType(SPELL_AURA_MOD_WATER_BREATHING);
for(AuraList::const_iterator i = mModWaterBreathing.begin(); i != mModWaterBreathing.end(); ++i)
- UnderWaterTime = uint32(UnderWaterTime * (100.0f + (*i)->GetModifierValue()) / 100.0f);
+ UnderWaterTime = uint32(UnderWaterTime * (100.0f + (*i)->GetModifier()->m_amount) / 100.0f);
- if ((m_isunderwater & 0x01) && !(m_isunderwater & 0x80) && isAlive())
+ if ((m_isunderwater & UNDERWATER_INWATER) && !(m_isunderwater & UNDERWATER_INLAVA) && isAlive())
{
//single trigger timer
- if (!(m_isunderwater & 0x02))
+ if (!(m_isunderwater & UNDERWATER_WATER_TRIGGER))
{
- m_isunderwater|= 0x02;
+ m_isunderwater|= UNDERWATER_WATER_TRIGGER;
m_breathTimer = UnderWaterTime + 1000;
}
- //single trigger "Breathbar"
- if ( m_breathTimer <= UnderWaterTime && !(m_isunderwater & 0x04))
+ //single trigger "show Breathbar"
+ if ( m_breathTimer <= UnderWaterTime && !(m_isunderwater & UNDERWATER_WATER_BREATHB))
{
- m_isunderwater|= 0x04;
+ m_isunderwater|= UNDERWATER_WATER_BREATHB;
StartMirrorTimer(BREATH_TIMER, UnderWaterTime);
}
//continuous trigger drowning "Damage"
- if ((m_breathTimer == 0) && (m_isunderwater & 0x01))
+ if ((m_breathTimer == 0) && (m_isunderwater & UNDERWATER_INWATER))
{
//TODO: Check this formula
uint64 guid = GetGUID();
@@ -915,74 +964,51 @@ void Player::HandleDrowning()
}
}
//single trigger retract bar
- else if (!(m_isunderwater & 0x01) && !(m_isunderwater & 0x08) && (m_isunderwater & 0x02) && (m_breathTimer > 0) && isAlive())
+ else if (!(m_isunderwater & UNDERWATER_INWATER) && (m_isunderwater & UNDERWATER_WATER_TRIGGER) && (m_breathTimer > 0) && isAlive())
{
- m_isunderwater = 0x08;
-
uint32 BreathRegen = 10;
+ // m_breathTimer will be reduced in ModifyMirrorTimer
ModifyMirrorTimer(BREATH_TIMER, UnderWaterTime, m_breathTimer,BreathRegen);
- m_isunderwater = 0x10;
+ m_isunderwater = UNDERWATER_WATER_BREATHB_RETRACTING;
}
//remove bar
- else if ((m_breathTimer < 50) && !(m_isunderwater & 0x01) && (m_isunderwater == 0x10))
+ else if ((m_breathTimer < 50) && !(m_isunderwater & UNDERWATER_INWATER) && (m_isunderwater == UNDERWATER_WATER_BREATHB_RETRACTING))
{
StopMirrorTimer(BREATH_TIMER);
- m_isunderwater = 0;
+ m_isunderwater = UNDERWATER_NONE;
}
}
void Player::HandleLava()
{
- bool ValidArea = false;
-
- if ((m_isunderwater & 0x80) && isAlive())
+ if ((m_isunderwater & UNDERWATER_INLAVA) && isAlive())
{
- //Single trigger Set BreathTimer
- if (!(m_isunderwater & 0x80))
+ /*
+ * arrai: how is this supposed to work? UNDERWATER_INLAVA is always set in this scope!
+ // Single trigger Set BreathTimer
+ if (!(m_isunderwater & UNDERWATER_INLAVA))
{
- m_isunderwater|= 0x04;
+ m_isunderwater|= UNDERWATER_WATER_BREATHB;
m_breathTimer = 1000;
}
- //Reset BreathTimer and still in the lava
+ */
+ // Reset BreathTimer and still in the lava
if (!m_breathTimer)
{
uint64 guid = GetGUID();
uint32 damage = urand(600, 700); // TODO: Get more detailed information about lava damage
- uint32 dmgZone = GetZoneId(); // TODO: Find correct "lava dealing zone" flag in Area Table
-
- // Deal lava damage only in lava zones.
- switch(dmgZone)
- {
- case 0x8D:
- ValidArea = false;
- break;
- case 0x94:
- ValidArea = false;
- break;
- case 0x2CE:
- ValidArea = false;
- break;
- case 0x2CF:
- ValidArea = false;
- break;
- default:
- if (dmgZone / 5 & 0x408)
- ValidArea = true;
- }
- // if is valid area and is not gamemaster then deal damage
- if ( ValidArea && !isGameMaster() )
+ // if not gamemaster then deal damage
+ if ( !isGameMaster() )
EnvironmentalDamage(guid, DAMAGE_LAVA, damage);
m_breathTimer = 1000;
}
-
}
- //Death timer disabled and WaterFlags reset
- else if (m_deathState == DEAD)
+ else if (!isAlive()) // Disable breath timer and reset underwater flags
{
m_breathTimer = 0;
- m_isunderwater = 0;
+ m_isunderwater = UNDERWATER_NONE;
}
}
@@ -1314,6 +1340,7 @@ void Player::Update( uint32 p_time )
Pet* pet = GetPet();
if(pet && !IsWithinDistInMap(pet, OWNER_MAX_DISTANCE) && !pet->isPossessed())
+ //if(pet && !IsWithinDistInMap(pet, OWNER_MAX_DISTANCE) && (GetCharmGUID() && (pet->GetGUID() != GetCharmGUID())))
{
RemovePet(pet, PET_SAVE_NOT_IN_SLOT, true);
return;
@@ -1363,6 +1390,7 @@ void Player::setDeathState(DeathState s)
// passive spell
if(!ressSpellId)
ressSpellId = GetResurrectionSpellId();
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP, 1);
}
Unit::setDeathState(s);
@@ -1383,13 +1411,15 @@ void Player::setDeathState(DeathState s)
void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )
{
- *p_data << GetGUID();
+ Field *fields = result->Fetch();
+
+ *p_data << uint64(GetGUID());
*p_data << m_name;
- *p_data << getRace();
+ *p_data << uint8(getRace());
uint8 pClass = getClass();
- *p_data << pClass;
- *p_data << getGender();
+ *p_data << uint8(pClass);
+ *p_data << uint8(getGender());
uint32 bytes = GetUInt32Value(PLAYER_BYTES);
*p_data << uint8(bytes);
@@ -1402,16 +1432,17 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )
*p_data << uint8(getLevel()); // player level
// do not use GetMap! it will spawn a new instance since the bound instances are not loaded
- uint32 zoneId = MapManager::Instance().GetZoneId(GetMapId(), GetPositionX(),GetPositionY());
+ uint32 zoneId = MapManager::Instance().GetZoneId(GetMapId(), GetPositionX(),GetPositionY(),GetPositionZ());
sLog.outDebug("Player::BuildEnumData: m:%u, x:%f, y:%f, z:%f zone:%u", GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), zoneId);
- *p_data << zoneId;
- *p_data << GetMapId();
+ *p_data << uint32(zoneId);
+ *p_data << uint32(GetMapId());
*p_data << GetPositionX();
*p_data << GetPositionY();
*p_data << GetPositionZ();
- *p_data << (result ? result->Fetch()[13].GetUInt32() : 0);
+ // guild id
+ *p_data << (result ? fields[13].GetUInt32() : 0);
uint32 char_flags = 0;
if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_HELM))
@@ -1422,14 +1453,13 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )
char_flags |= CHARACTER_FLAG_GHOST;
if(HasAtLoginFlag(AT_LOGIN_RENAME))
char_flags |= CHARACTER_FLAG_RENAME;
- // always send the flag if declined names aren't used
- // to let the client select a default method of declining the name
- if(!sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) || (result && result->Fetch()[14].GetCppString() != ""))
+ if(sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) && (fields[14].GetCppString() != ""))
char_flags |= CHARACTER_FLAG_DECLINED;
- *p_data << (uint32)char_flags; // character flags
-
- *p_data << (uint8)1; // unknown
+ *p_data << uint32(char_flags); // character flags
+ // character customize (flags?)
+ *p_data << uint32(HasAtLoginFlag(AT_LOGIN_CUSTOMIZE) ? 1 : 0);
+ *p_data << uint8(1); // unknown
// Pets info
{
@@ -1440,8 +1470,6 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )
// show pet at selection character in character list only for non-ghost character
if(result && isAlive() && (pClass == CLASS_WARLOCK || pClass == CLASS_HUNTER))
{
- Field* fields = result->Fetch();
-
uint32 entry = fields[10].GetUInt32();
CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(entry);
if(cInfo)
@@ -1452,36 +1480,11 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )
}
}
- *p_data << (uint32)petDisplayId;
- *p_data << (uint32)petLevel;
- *p_data << (uint32)petFamily;
+ *p_data << uint32(petDisplayId);
+ *p_data << uint32(petLevel);
+ *p_data << uint32(petFamily);
}
- /*ItemPrototype const *items[EQUIPMENT_SLOT_END];
- for (int i = 0; i < EQUIPMENT_SLOT_END; i++)
- items[i] = NULL;
-
- QueryResult *result = CharacterDatabase.PQuery("SELECT slot,item_template FROM character_inventory WHERE guid = '%u' AND bag = 0",GetGUIDLow());
- if (result)
- {
- do
- {
- Field *fields = result->Fetch();
- uint8 slot = fields[0].GetUInt8() & 255;
- uint32 item_id = fields[1].GetUInt32();
- if( slot >= EQUIPMENT_SLOT_END )
- continue;
-
- items[slot] = objmgr.GetItemPrototype(item_id);
- if(!items[slot])
- {
- sLog.outError( "Player::BuildEnumData: Player %s have unknown item (id: #%u) in inventory, skipped.", GetName(),item_id );
- continue;
- }
- } while (result->NextRow());
- delete result;
- }*/
-
for (uint8 slot = 0; slot < EQUIPMENT_SLOT_END; slot++)
{
uint32 visualbase = PLAYER_VISIBLE_ITEM_1_0 + (slot * MAX_VISIBLE_ITEM_OFFSET);
@@ -1498,20 +1501,20 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )
if (proto != NULL)
{
- *p_data << (uint32)proto->DisplayInfoID;
- *p_data << (uint8)proto->InventoryType;
- *p_data << (uint32)(enchant?enchant->aura_id:0);
+ *p_data << uint32(proto->DisplayInfoID);
+ *p_data << uint8(proto->InventoryType);
+ *p_data << uint32(enchant ? enchant->aura_id : 0);
}
else
{
- *p_data << (uint32)0;
- *p_data << (uint8)0;
- *p_data << (uint32)0; // enchant?
+ *p_data << uint32(0);
+ *p_data << uint8(0);
+ *p_data << uint32(0); // enchant?
}
}
- *p_data << (uint32)0; // first bag display id
- *p_data << (uint8)0; // first bag inventory type
- *p_data << (uint32)0; // enchant?
+ *p_data << uint32(0); // first bag display id
+ *p_data << uint8(0); // first bag inventory type
+ *p_data << uint32(0); // enchant?
}
bool Player::ToggleAFK()
@@ -1596,7 +1599,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
if(GetTransport())
RepopAtGraveyard(); // teleport to near graveyard if on transport, looks blizz like :)
- SendTransferAborted(mapid, TRANSFER_ABORT_INSUF_EXPAN_LVL1);
+ SendTransferAborted(mapid, TRANSFER_ABORT_INSUF_EXPAN_LVL, mEntry->Expansion());
return false; // normal client can't teleport to this map...
}
@@ -1916,13 +1919,20 @@ void Player::RegenerateAll()
{
RegenerateHealth();
if (!isInCombat() && !HasAuraType(SPELL_AURA_INTERRUPT_REGEN))
+ {
Regenerate(POWER_RAGE);
+ if(getClass() == CLASS_DEATH_KNIGHT)
+ Regenerate(POWER_RUNIC_POWER);
+ }
}
Regenerate( POWER_ENERGY );
Regenerate( POWER_MANA );
+ if(getClass() == CLASS_DEATH_KNIGHT)
+ Regenerate( POWER_RUNE );
+
m_regenTimer = regenDelay;
}
@@ -1942,11 +1952,11 @@ void Player::Regenerate(Powers power)
if (recentCast)
{
// Trinity Updates Mana in intervals of 2s, which is correct
- addvalue = GetFloatValue(PLAYER_FIELD_MOD_MANA_REGEN_INTERRUPT) * ManaIncreaseRate * 2.00f;
+ addvalue = GetFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER) * ManaIncreaseRate * 2.00f;
}
else
{
- addvalue = GetFloatValue(PLAYER_FIELD_MOD_MANA_REGEN) * ManaIncreaseRate * 2.00f;
+ addvalue = GetFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER) * ManaIncreaseRate * 2.00f;
}
} break;
case POWER_RAGE: // Regenerate rage
@@ -1957,6 +1967,17 @@ void Player::Regenerate(Powers power)
case POWER_ENERGY: // Regenerate energy (rogue)
addvalue = 20;
break;
+ case POWER_RUNIC_POWER:
+ {
+ float RunicPowerDecreaseRate = sWorld.getRate(RATE_POWER_RUNICPOWER_LOSS);
+ addvalue = 30 * RunicPowerDecreaseRate; // 3 RunicPower by tick
+ } break;
+ case POWER_RUNE:
+ {
+ for(uint32 i = 0; i < MAX_RUNES; ++i)
+ if(uint8 cd = GetRuneCooldown(i)) // if we have cooldown, reduce it...
+ SetRuneCooldown(i, cd - 1); // ... by 2 sec (because update is every 2 sec)
+ } break;
case POWER_FOCUS:
case POWER_HAPPINESS:
break;
@@ -1969,10 +1990,10 @@ void Player::Regenerate(Powers power)
AuraList const& ModPowerRegenPCTAuras = GetAurasByType(SPELL_AURA_MOD_POWER_REGEN_PERCENT);
for(AuraList::const_iterator i = ModPowerRegenPCTAuras.begin(); i != ModPowerRegenPCTAuras.end(); ++i)
if ((*i)->GetModifier()->m_miscvalue == power)
- addvalue *= ((*i)->GetModifierValue() + 100) / 100.0f;
+ addvalue *= ((*i)->GetModifier()->m_amount + 100) / 100.0f;
}
- if (power != POWER_RAGE)
+ if (power != POWER_RAGE && power != POWER_RUNIC_POWER)
{
curValue += uint32(addvalue);
if (curValue > maxValue)
@@ -2010,7 +2031,7 @@ void Player::RegenerateHealth()
{
AuraList const& mModHealthRegenPct = GetAurasByType(SPELL_AURA_MOD_HEALTH_REGEN_PERCENT);
for(AuraList::const_iterator i = mModHealthRegenPct.begin(); i != mModHealthRegenPct.end(); ++i)
- addvalue *= (100.0f + (*i)->GetModifierValue()) / 100.0f;
+ addvalue *= (100.0f + (*i)->GetModifier()->m_amount) / 100.0f;
}
else if(HasAuraType(SPELL_AURA_MOD_REGEN_DURING_COMBAT))
addvalue *= GetTotalAuraModifier(SPELL_AURA_MOD_REGEN_DURING_COMBAT) / 100.0f;
@@ -2070,21 +2091,27 @@ void Player::SetGameMaster(bool on)
setFaction(35);
SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_GM);
- RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP);
+ RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
ResetContestedPvP();
getHostilRefManager().setOnlineOfflineState(false);
CombatStop();
+
+ SetPhaseMask(PHASEMASK_ANYWHERE,false); // see and visible in all phases
}
else
{
+ // restore phase
+ AuraList const& phases = GetAurasByType(SPELL_AURA_PHASE);
+ SetPhaseMask(!phases.empty() ? phases.front()->GetMiscValue() : PHASEMASK_NORMAL,false);
+
m_ExtraFlags &= ~ PLAYER_EXTRA_GM_ON;
setFactionForRace(getRace());
RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GM);
// restore FFA PvP Server state
if(sWorld.IsFFAPvPRealm())
- SetFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP);
+ SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
// restore FFA PvP area state, remove not allowed for GM mounts
UpdateArea(m_areaUpdateId);
@@ -2208,7 +2235,7 @@ void Player::GiveXP(uint32 xp, Unit* victim)
// handle SPELL_AURA_MOD_XP_PCT auras
Unit::AuraList const& ModXPPctAuras = GetAurasByType(SPELL_AURA_MOD_XP_PCT);
for(Unit::AuraList::const_iterator i = ModXPPctAuras.begin();i != ModXPPctAuras.end(); ++i)
- xp = uint32(xp*(1.0f + (*i)->GetModifierValue() / 100.0f));
+ xp = uint32(xp*(1.0f + (*i)->GetModifier()->m_amount / 100.0f));
// XP resting bonus for kill
uint32 rested_bonus_xp = victim ? GetXPRestBonus(xp) : 0;
@@ -2256,13 +2283,15 @@ void Player::GiveLevel(uint32 level)
data << uint32(0);
data << uint32(0);
data << uint32(0);
+ data << uint32(0);
+ data << uint32(0);
// end for
for(int i = STAT_STRENGTH; i < MAX_STATS; ++i) // Stats loop (0-4)
data << uint32(int32(info.stats[i]) - GetCreateStat(Stats(i)));
GetSession()->SendPacket(&data);
- SetUInt32Value(PLAYER_NEXT_LEVEL_XP, Trinity::XP::xp_to_level(level));
+ SetUInt32Value(PLAYER_NEXT_LEVEL_XP, objmgr.GetXPForLevel(level));
//update level, max level of skills
if(getLevel()!= level)
@@ -2279,6 +2308,7 @@ void Player::GiveLevel(uint32 level)
InitTalentForLevel();
InitTaxiNodesForLevel();
+ InitGlyphsForLevel();
UpdateAllStats();
@@ -2298,6 +2328,7 @@ void Player::GiveLevel(uint32 level)
Pet* pet = GetPet();
if(pet && pet->getPetType()==SUMMON_PET)
pet->GivePetLevel(level);
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL);
}
void Player::InitTalentForLevel()
@@ -2315,7 +2346,8 @@ void Player::InitTalentForLevel()
}
else
{
- uint32 talentPointsForLevel = uint32((level-9)*sWorld.getRate(RATE_TALENT));
+ uint32 talentPointsForLevel = CalculateTalentsPoints();
+
// if used more that have then reset
if(m_usedTalentCount > talentPointsForLevel)
{
@@ -2342,7 +2374,7 @@ void Player::InitStatsForLevel(bool reapplyMods)
objmgr.GetPlayerLevelInfo(getRace(),getClass(),getLevel(),&info);
SetUInt32Value(PLAYER_FIELD_MAX_LEVEL, sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) );
- SetUInt32Value(PLAYER_NEXT_LEVEL_XP, Trinity::XP::xp_to_level(getLevel()));
+ SetUInt32Value(PLAYER_NEXT_LEVEL_XP, objmgr.GetXPForLevel(getLevel()));
UpdateSkillsForLevel ();
@@ -2392,11 +2424,11 @@ void Player::InitStatsForLevel(bool reapplyMods)
SetFloatValue(UNIT_FIELD_MINRANGEDDAMAGE, 0.0f );
SetFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE, 0.0f );
- SetUInt32Value(UNIT_FIELD_ATTACK_POWER, 0 );
- SetUInt32Value(UNIT_FIELD_ATTACK_POWER_MODS, 0 );
+ SetInt32Value(UNIT_FIELD_ATTACK_POWER, 0 );
+ SetInt32Value(UNIT_FIELD_ATTACK_POWER_MODS, 0 );
SetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER,0.0f);
- SetUInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER, 0 );
- SetUInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER_MODS,0 );
+ 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
@@ -2434,6 +2466,9 @@ void Player::InitStatsForLevel(bool reapplyMods)
SetFloatValue(UNIT_FIELD_POWER_COST_MODIFIER+i,0.0f);
SetFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER+i,0.0f);
}
+ // Reset no reagent cost field
+ for(int i = 0; i < 3; i++)
+ SetUInt32Value(PLAYER_NO_REAGENT_COST_1 + i, 0);
// Init data for form but skip reapply item mods for form
InitDataForForm(reapplyMods);
@@ -2450,15 +2485,16 @@ void Player::InitStatsForLevel(bool reapplyMods)
RemoveFlag( UNIT_FIELD_FLAGS,
UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_ATTACKABLE_1 |
UNIT_FLAG_PET_IN_COMBAT | UNIT_FLAG_SILENCED | UNIT_FLAG_PACIFIED |
- UNIT_FLAG_DISABLE_ROTATE | UNIT_FLAG_IN_COMBAT | UNIT_FLAG_DISARMED |
+ UNIT_FLAG_STUNNED | UNIT_FLAG_IN_COMBAT | UNIT_FLAG_DISARMED |
UNIT_FLAG_CONFUSED | UNIT_FLAG_FLEEING | UNIT_FLAG_NOT_SELECTABLE |
UNIT_FLAG_SKINNABLE | UNIT_FLAG_MOUNT | UNIT_FLAG_TAXI_FLIGHT );
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE ); // must be set
// cleanup player flags (will be re-applied if need at aura load), to avoid have ghost flag without ghost aura, for example.
- RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_AFK | PLAYER_FLAGS_DND | PLAYER_FLAGS_GM | PLAYER_FLAGS_GHOST | PLAYER_FLAGS_FFA_PVP);
+ RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_AFK | PLAYER_FLAGS_DND | PLAYER_FLAGS_GM | PLAYER_FLAGS_GHOST | PLAYER_ALLOW_ONLY_ABILITY);
- SetByteValue(UNIT_FIELD_BYTES_1, 2, 0x00); // one form stealth modified bytes
+ RemoveStandFlags(UNIT_STAND_FLAGS_ALL); // one form stealth modified bytes
+ RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP | UNIT_BYTE2_FLAG_SANCTUARY);
// restore if need some important flags
SetUInt32Value(PLAYER_FIELD_BYTES2, 0 ); // flags empty by default
@@ -2474,6 +2510,7 @@ void Player::InitStatsForLevel(bool reapplyMods)
SetPower(POWER_RAGE, GetMaxPower(POWER_RAGE));
SetPower(POWER_FOCUS, 0);
SetPower(POWER_HAPPINESS, 0);
+ SetPower(POWER_RUNIC_POWER, 0);
}
void Player::SendInitialSpells()
@@ -2606,13 +2643,13 @@ void Player::AddNewMailDeliverTime(time_t deliver_time)
}
}
-bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading, uint16 slot_id, bool disabled)
+bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependent, bool disabled)
{
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id);
if (!spellInfo)
{
// do character spell book cleanup (all characters)
- if(loading && !learning) // spell load case
+ if(!IsInWorld() && !learning) // spell load case
{
sLog.outError("Player::addSpell: Non-existed in SpellStore spell #%u request, deleting for all characters in `character_spell`.",spell_id);
CharacterDatabase.PExecute("DELETE FROM character_spell WHERE spell = '%u'",spell_id);
@@ -2626,7 +2663,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading,
if(!SpellMgr::IsSpellValid(spellInfo,this,false))
{
// do character spell book cleanup (all characters)
- if(loading && !learning) // spell load case
+ if(!IsInWorld() && !learning) // spell load case
{
sLog.outError("Player::addSpell: Broken spell #%u learning not allowed, deleting for all characters in `character_spell`.",spell_id);
CharacterDatabase.PExecute("DELETE FROM character_spell WHERE spell = '%u'",spell_id);
@@ -2639,29 +2676,80 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading,
PlayerSpellState state = learning ? PLAYERSPELL_NEW : PLAYERSPELL_UNCHANGED;
+ bool dependent_set = false;
bool disabled_case = false;
bool superceded_old = false;
PlayerSpellMap::iterator itr = m_spells.find(spell_id);
if (itr != m_spells.end())
{
+ uint32 next_active_spell_id = 0;
+ // fix activate state for non-stackable low rank (and find next spell for !active case)
+ if(!SpellMgr::canStackSpellRanks(spellInfo) && spellmgr.GetSpellRank(spellInfo->Id) != 0)
+ {
+ if(uint32 next = spellmgr.GetNextSpellInChain(spell_id))
+ {
+ if(HasSpell(next))
+ {
+ // high rank already known so this must !active
+ active = false;
+ next_active_spell_id = next;
+ }
+ }
+ }
+
+ // not do anything if already known in expected state
+ if(itr->second->state != PLAYERSPELL_REMOVED && itr->second->active == active &&
+ itr->second->dependent == dependent && itr->second->disabled == disabled)
+ {
+ if(!IsInWorld() && !learning) // explicitly load from DB and then exist in it already and set correctly
+ itr->second->state = PLAYERSPELL_UNCHANGED;
+
+ return false;
+ }
+
+ // dependent spell known as not dependent, overwrite state
+ if (itr->second->state != PLAYERSPELL_REMOVED && !itr->second->dependent && dependent)
+ {
+ itr->second->dependent = dependent;
+ if (itr->second->state != PLAYERSPELL_NEW)
+ itr->second->state = PLAYERSPELL_CHANGED;
+ dependent_set = true;
+ }
+
// update active state for known spell
if(itr->second->active != active && itr->second->state != PLAYERSPELL_REMOVED && !itr->second->disabled)
{
itr->second->active = active;
- // loading && !learning == explicitly load from DB and then exist in it already and set correctly
- if(loading && !learning)
+ if(!IsInWorld() && !learning && !dependent_set) // explicitly load from DB and then exist in it already and set correctly
itr->second->state = PLAYERSPELL_UNCHANGED;
else if(itr->second->state != PLAYERSPELL_NEW)
itr->second->state = PLAYERSPELL_CHANGED;
- if(!active)
+ if(active)
{
- WorldPacket data(SMSG_REMOVED_SPELL, 4);
- data << uint16(spell_id);
- GetSession()->SendPacket(&data);
+ if (IsPassiveSpell(spell_id) && IsNeedCastPassiveSpellAtLearn(spellInfo))
+ CastSpell (this,spell_id,true);
}
+ else if(IsInWorld())
+ {
+ if(next_active_spell_id)
+ {
+ // update spell ranks in spellbook and action bar
+ WorldPacket data(SMSG_SUPERCEDED_SPELL, (4));
+ data << uint16(spell_id);
+ data << uint16(next_active_spell_id);
+ GetSession()->SendPacket( &data );
+ }
+ else
+ {
+ WorldPacket data(SMSG_REMOVED_SPELL, 4);
+ data << uint16(spell_id);
+ GetSession()->SendPacket(&data);
+ }
+ }
+
return active; // learn (show in spell book if active now)
}
@@ -2690,7 +2778,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading,
default: // known not saved yet spell (new or modified)
{
// can be in case spell loading but learned at some previous spell loading
- if(loading && !learning)
+ if(!IsInWorld() && !learning && !dependent_set)
itr->second->state = PLAYERSPELL_UNCHANGED;
return false;
@@ -2712,10 +2800,6 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading,
if(!rankSpellId || rankSpellId==spell_id)
continue;
- // skip unknown ranks
- if(!HasSpell(rankSpellId))
- continue;
-
removeSpell(rankSpellId);
}
}
@@ -2723,16 +2807,17 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading,
// non talent spell: learn low ranks (recursive call)
else if(uint32 prev_spell = spellmgr.GetPrevSpellInChain(spell_id))
{
- if(loading) // at spells loading, no output, but allow save
- addSpell(prev_spell,active,true,loading,SPELL_WITHOUT_SLOT_ID,disabled);
+ if(!IsInWorld() || disabled) // at spells loading, no output, but allow save
+ addSpell(prev_spell,active,true,true,disabled);
else // at normal learning
- learnSpell(prev_spell);
+ learnSpell(prev_spell,true);
}
PlayerSpell *newspell = new PlayerSpell;
- newspell->active = active;
- newspell->state = state;
- newspell->disabled = disabled;
+ newspell->state = state;
+ newspell->active = active;
+ newspell->dependent = dependent;
+ newspell->disabled = disabled;
// replace spells in action bars and spellbook to bigger rank if only one spell rank must be accessible
if(newspell->active && !newspell->disabled && !SpellMgr::canStackSpellRanks(spellInfo) && spellmgr.GetSpellRank(spellInfo->Id) != 0)
@@ -2749,7 +2834,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading,
{
if(spellmgr.IsHighRankOfSpell(spell_id,itr->first))
{
- if(!loading) // not send spell (re-/over-)learn packets at loading
+ if(IsInWorld()) // not send spell (re-/over-)learn packets at loading
{
WorldPacket data(SMSG_SUPERCEDED_SPELL, (4));
data << uint16(itr->first);
@@ -2759,12 +2844,13 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading,
// mark old spell as disable (SMSG_SUPERCEDED_SPELL replace it in client by new)
itr->second->active = false;
- itr->second->state = PLAYERSPELL_CHANGED;
+ if(itr->second->state != PLAYERSPELL_NEW)
+ itr->second->state = PLAYERSPELL_CHANGED;
superceded_old = true; // new spell replace old in action bars and spell book.
}
else if(spellmgr.IsHighRankOfSpell(itr->first,spell_id))
{
- if(!loading) // not send spell (re-/over-)learn packets at loading
+ if(IsInWorld()) // not send spell (re-/over-)learn packets at loading
{
WorldPacket data(SMSG_SUPERCEDED_SPELL, (4));
data << uint16(spell_id);
@@ -2782,23 +2868,6 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading,
}
}
- uint16 tmpslot=slot_id;
-
- if (tmpslot == SPELL_WITHOUT_SLOT_ID)
- {
- uint16 maxid = 0;
- PlayerSpellMap::iterator itr;
- for (itr = m_spells.begin(); itr != m_spells.end(); ++itr)
- {
- if(itr->second->state == PLAYERSPELL_REMOVED)
- continue;
- if (itr->second->slotId > maxid)
- maxid = itr->second->slotId;
- }
- tmpslot = maxid + 1;
- }
-
- newspell->slotId = tmpslot;
m_spells[spell_id] = newspell;
// return false if spell disabled
@@ -2818,23 +2887,8 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading,
// also cast passive spells (including all talents without SPELL_EFFECT_LEARN_SPELL) with additional checks
else if (IsPassiveSpell(spell_id))
{
- // if spell doesn't require a stance or the player is in the required stance
- if( ( !spellInfo->Stances &&
- spell_id != 5420 && spell_id != 5419 && spell_id != 7376 &&
- spell_id != 7381 && spell_id != 21156 && spell_id != 21009 &&
- spell_id != 21178 && spell_id != 33948 && spell_id != 40121 ) ||
- m_form != 0 && (spellInfo->Stances & (1<<(m_form-1))) ||
- (spell_id == 5420 && m_form == FORM_TREE) ||
- (spell_id == 5419 && m_form == FORM_TRAVEL) ||
- (spell_id == 7376 && m_form == FORM_DEFENSIVESTANCE) ||
- (spell_id == 7381 && m_form == FORM_BERSERKERSTANCE) ||
- (spell_id == 21156 && m_form == FORM_BATTLESTANCE)||
- (spell_id == 21178 && (m_form == FORM_BEAR || m_form == FORM_DIREBEAR) ) ||
- (spell_id == 33948 && m_form == FORM_FLIGHT) ||
- (spell_id == 40121 && m_form == FORM_FLIGHT_EPIC) )
- //Check CasterAuraStates
- if (!spellInfo->CasterAuraState || HasAuraState(AuraState(spellInfo->CasterAuraState)))
- CastSpell(this, spell_id, true);
+ if(IsNeedCastPassiveSpellAtLearn(spellInfo))
+ CastSpell(this, spell_id, true);
}
else if( IsSpellHaveEffect(spellInfo,SPELL_EFFECT_SKILL_STEP) )
{
@@ -2888,8 +2942,6 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading,
continue;
if(_spell_idx->second->learnOnGetSkill == ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL ||
- // poison special case, not have ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL
- pSkill->id==SKILL_POISONS && _spell_idx->second->max_value==0 ||
// lockpicking special case, not have ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL
pSkill->id==SKILL_LOCKPICKING && _spell_idx->second->max_value==0 )
{
@@ -2919,37 +2971,71 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading,
{
if(!itr->second.autoLearned)
{
- if(loading) // at spells loading, no output, but allow save
- addSpell(itr->second.spell,true,true,loading);
+ if(!IsInWorld() || !itr->second.active) // at spells loading, no output, but allow save
+ addSpell(itr->second.spell,itr->second.active,true,true,false);
else // at normal learning
- learnSpell(itr->second.spell);
+ learnSpell(itr->second.spell,true);
}
}
+ if(IsInWorld())
+ {
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL);
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS);
+ }
+
// return true (for send learn packet) only if spell active (in case ranked spells) and not replace old spell
return active && !disabled && !superceded_old;
}
-void Player::learnSpell(uint32 spell_id)
+bool Player::IsNeedCastPassiveSpellAtLearn(SpellEntry const* spellInfo) const
+{
+ bool need_cast = false;
+
+ switch(spellInfo->Id)
+ {
+ // some spells not have stance data expacted cast at form change or present
+ case 5420: need_cast = (m_form == FORM_TREE); break;
+ case 5419: need_cast = (m_form == FORM_TRAVEL); break;
+ case 7376: need_cast = (m_form == FORM_DEFENSIVESTANCE); break;
+ case 7381: need_cast = (m_form == FORM_BERSERKERSTANCE); break;
+ case 21156: need_cast = (m_form == FORM_BATTLESTANCE); break;
+ case 21178: need_cast = (m_form == FORM_BEAR || m_form == FORM_DIREBEAR); break;
+ case 33948: need_cast = (m_form == FORM_FLIGHT); break;
+ case 34764: need_cast = (m_form == FORM_FLIGHT); break;
+ case 40121: need_cast = (m_form == FORM_FLIGHT_EPIC); break;
+ case 40122: need_cast = (m_form == FORM_FLIGHT_EPIC); break;
+ // another spells have proper stance data
+ default: need_cast = !spellInfo->Stances || m_form != 0 && (spellInfo->Stances & (1<<(m_form-1))); break;
+ }
+
+ //Check CasterAuraStates
+ return need_cast && (!spellInfo->CasterAuraState || HasAuraState(AuraState(spellInfo->CasterAuraState)));
+}
+
+void Player::learnSpell(uint32 spell_id, bool dependent)
{
PlayerSpellMap::iterator itr = m_spells.find(spell_id);
bool disabled = (itr != m_spells.end()) ? itr->second->disabled : false;
bool active = disabled ? itr->second->active : true;
- bool learning = addSpell(spell_id,active);
+ bool learning = addSpell(spell_id,active,true,dependent,false);
// learn all disabled higher ranks (recursive)
- SpellChainNode const* node = spellmgr.GetSpellChainNode(spell_id);
- if (node)
+ if(disabled)
{
- PlayerSpellMap::iterator iter = m_spells.find(node->next);
- if (disabled && iter != m_spells.end() && iter->second->disabled )
- learnSpell(node->next);
+ SpellChainNode const* node = spellmgr.GetSpellChainNode(spell_id);
+ if(node)
+ {
+ PlayerSpellMap::iterator iter = m_spells.find(node->next);
+ if (iter != m_spells.end() && iter->second->disabled )
+ learnSpell(node->next,false);
+ }
}
- // prevent duplicated entires in spell book
- if(!learning)
+ // prevent duplicated entires in spell book, also not send if not in world (loading)
+ if(!learning || !IsInWorld ())
return;
WorldPacket data(SMSG_LEARNED_SPELL, 4);
@@ -2957,7 +3043,7 @@ void Player::learnSpell(uint32 spell_id)
GetSession()->SendPacket(&data);
}
-void Player::removeSpell(uint32 spell_id, bool disabled)
+void Player::removeSpell(uint32 spell_id, bool disabled, bool update_action_bar_for_low_rank)
{
PlayerSpellMap::iterator itr = m_spells.find(spell_id);
if (itr == m_spells.end())
@@ -2979,10 +3065,8 @@ void Player::removeSpell(uint32 spell_id, bool disabled)
for (uint32 i=reqMap.count(spell_id);i>0;i--,itr2++)
removeSpell(itr2->second,disabled);
- // removing
- WorldPacket data(SMSG_REMOVED_SPELL, 4);
- data << uint16(spell_id);
- GetSession()->SendPacket(&data);
+ bool cur_active = itr->second->active;
+ bool cur_dependent = itr->second->dependent;
if (disabled)
{
@@ -3075,8 +3159,6 @@ void Player::removeSpell(uint32 spell_id, bool disabled)
continue;
if(_spell_idx->second->learnOnGetSkill == ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL ||
- // poison special case, not have ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL
- pSkill->id==SKILL_POISONS && _spell_idx->second->max_value==0 ||
// lockpicking special case, not have ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL
pSkill->id==SKILL_LOCKPICKING && _spell_idx->second->max_value==0 )
{
@@ -3096,6 +3178,58 @@ void Player::removeSpell(uint32 spell_id, bool disabled)
for(SpellLearnSpellMap::const_iterator itr2 = spell_begin; itr2 != spell_end; ++itr2)
removeSpell(itr2->second.spell, disabled);
+
+ // activate lesser rank in spellbook/action bar, and cast it if need
+ bool prev_activate = false;
+
+ if(uint32 prev_id = spellmgr.GetPrevSpellInChain (spell_id))
+ {
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id);
+
+ // if talent then lesser rank also talent and need learn
+ if(talentCosts)
+ learnSpell (prev_id,false);
+ // if ranked non-stackable spell: need activate lesser rank and update dendence state
+ else if(cur_active && !SpellMgr::canStackSpellRanks(spellInfo) && spellmgr.GetSpellRank(spellInfo->Id) != 0)
+ {
+ // need manually update dependence state (learn spell ignore like attempts)
+ PlayerSpellMap::iterator prev_itr = m_spells.find(prev_id);
+ if (prev_itr != m_spells.end())
+ {
+ if(prev_itr->second->dependent != cur_dependent)
+ {
+ prev_itr->second->dependent = cur_dependent;
+ if(prev_itr->second->state != PLAYERSPELL_NEW)
+ prev_itr->second->state = PLAYERSPELL_CHANGED;
+ }
+
+ // now re-learn if need re-activate
+ if(cur_active && !prev_itr->second->active)
+ {
+ if(addSpell(prev_id,true,false,prev_itr->second->dependent,prev_itr->second->disabled))
+ {
+ if(update_action_bar_for_low_rank)
+ {
+ // downgrade spell ranks in spellbook and action bar
+ WorldPacket data(SMSG_SUPERCEDED_SPELL, (4));
+ data << uint16(spell_id);
+ data << uint16(prev_id);
+ GetSession()->SendPacket( &data );
+ prev_activate = true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // remove from spell book if not replaced by lesser rank
+ if(!prev_activate)
+ {
+ WorldPacket data(SMSG_REMOVED_SPELL, 4);
+ data << uint16(spell_id);
+ GetSession()->SendPacket(&data);
+ }
}
void Player::RemoveArenaSpellCooldowns()
@@ -3238,8 +3372,7 @@ bool Player::resetTalents(bool no_cost)
CharacterDatabase.PExecute("UPDATE characters set at_login = at_login & ~ %u WHERE guid ='%u'", uint32(AT_LOGIN_RESET_TALENTS), GetGUIDLow());
}
- uint32 level = getLevel();
- uint32 talentPointsForLevel = level < 10 ? 0 : uint32((level-9)*sWorld.getRate(RATE_TALENT));
+ uint32 talentPointsForLevel = CalculateTalentsPoints();
if (m_usedTalentCount == 0)
{
@@ -3319,18 +3452,6 @@ bool Player::resetTalents(bool no_cost)
return true;
}
-bool Player::_removeSpell(uint16 spell_id)
-{
- PlayerSpellMap::iterator itr = m_spells.find(spell_id);
- if (itr != m_spells.end())
- {
- delete itr->second;
- m_spells.erase(itr);
- return true;
- }
- return false;
-}
-
Mail* Player::GetMail(uint32 id)
{
for(PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end(); ++itr)
@@ -3376,50 +3497,46 @@ void Player::InitVisibleBits()
{
updateVisualBits.SetCount(PLAYER_END);
- // TODO: really implement OWNER_ONLY and GROUP_ONLY. Flags can be found in UpdateFields.h
-
updateVisualBits.SetBit(OBJECT_FIELD_GUID);
updateVisualBits.SetBit(OBJECT_FIELD_TYPE);
+ updateVisualBits.SetBit(OBJECT_FIELD_ENTRY);
updateVisualBits.SetBit(OBJECT_FIELD_SCALE_X);
-
- updateVisualBits.SetBit(UNIT_FIELD_CHARM);
- updateVisualBits.SetBit(UNIT_FIELD_CHARM+1);
-
- updateVisualBits.SetBit(UNIT_FIELD_SUMMON);
- updateVisualBits.SetBit(UNIT_FIELD_SUMMON+1);
-
- updateVisualBits.SetBit(UNIT_FIELD_CHARMEDBY);
- updateVisualBits.SetBit(UNIT_FIELD_CHARMEDBY+1);
-
- updateVisualBits.SetBit(UNIT_FIELD_TARGET);
- updateVisualBits.SetBit(UNIT_FIELD_TARGET+1);
-
- updateVisualBits.SetBit(UNIT_FIELD_CHANNEL_OBJECT);
- updateVisualBits.SetBit(UNIT_FIELD_CHANNEL_OBJECT+1);
-
+ updateVisualBits.SetBit(UNIT_FIELD_CHARM + 0);
+ updateVisualBits.SetBit(UNIT_FIELD_CHARM + 1);
+ updateVisualBits.SetBit(UNIT_FIELD_SUMMON + 0);
+ updateVisualBits.SetBit(UNIT_FIELD_SUMMON + 1);
+ updateVisualBits.SetBit(UNIT_FIELD_CHARMEDBY + 0);
+ updateVisualBits.SetBit(UNIT_FIELD_CHARMEDBY + 1);
+ updateVisualBits.SetBit(UNIT_FIELD_TARGET + 0);
+ updateVisualBits.SetBit(UNIT_FIELD_TARGET + 1);
+ updateVisualBits.SetBit(UNIT_FIELD_CHANNEL_OBJECT + 0);
+ updateVisualBits.SetBit(UNIT_FIELD_CHANNEL_OBJECT + 1);
+ updateVisualBits.SetBit(UNIT_FIELD_BYTES_0);
updateVisualBits.SetBit(UNIT_FIELD_HEALTH);
updateVisualBits.SetBit(UNIT_FIELD_POWER1);
updateVisualBits.SetBit(UNIT_FIELD_POWER2);
updateVisualBits.SetBit(UNIT_FIELD_POWER3);
updateVisualBits.SetBit(UNIT_FIELD_POWER4);
updateVisualBits.SetBit(UNIT_FIELD_POWER5);
-
+ updateVisualBits.SetBit(UNIT_FIELD_POWER6);
+ updateVisualBits.SetBit(UNIT_FIELD_POWER7);
updateVisualBits.SetBit(UNIT_FIELD_MAXHEALTH);
updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER1);
updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER2);
updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER3);
updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER4);
updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER5);
-
+ updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER6);
+ updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER7);
updateVisualBits.SetBit(UNIT_FIELD_LEVEL);
updateVisualBits.SetBit(UNIT_FIELD_FACTIONTEMPLATE);
- updateVisualBits.SetBit(UNIT_FIELD_BYTES_0);
+ updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_SLOT_ID + 0);
+ updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_SLOT_ID + 1);
+ updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_SLOT_ID + 2);
updateVisualBits.SetBit(UNIT_FIELD_FLAGS);
updateVisualBits.SetBit(UNIT_FIELD_FLAGS_2);
- for(uint16 i = UNIT_FIELD_AURA; i < UNIT_FIELD_AURASTATE; ++i)
- updateVisualBits.SetBit(i);
updateVisualBits.SetBit(UNIT_FIELD_AURASTATE);
- updateVisualBits.SetBit(UNIT_FIELD_BASEATTACKTIME);
+ updateVisualBits.SetBit(UNIT_FIELD_BASEATTACKTIME + 0);
updateVisualBits.SetBit(UNIT_FIELD_BASEATTACKTIME + 1);
updateVisualBits.SetBit(UNIT_FIELD_BOUNDINGRADIUS);
updateVisualBits.SetBit(UNIT_FIELD_COMBATREACH);
@@ -3432,10 +3549,12 @@ void Player::InitVisibleBits()
updateVisualBits.SetBit(UNIT_DYNAMIC_FLAGS);
updateVisualBits.SetBit(UNIT_CHANNEL_SPELL);
updateVisualBits.SetBit(UNIT_MOD_CAST_SPEED);
+ updateVisualBits.SetBit(UNIT_FIELD_BASE_MANA);
updateVisualBits.SetBit(UNIT_FIELD_BYTES_2);
+ updateVisualBits.SetBit(UNIT_FIELD_HOVERHEIGHT);
- updateVisualBits.SetBit(PLAYER_DUEL_ARBITER);
- updateVisualBits.SetBit(PLAYER_DUEL_ARBITER+1);
+ updateVisualBits.SetBit(PLAYER_DUEL_ARBITER + 0);
+ updateVisualBits.SetBit(PLAYER_DUEL_ARBITER + 1);
updateVisualBits.SetBit(PLAYER_FLAGS);
updateVisualBits.SetBit(PLAYER_GUILDID);
updateVisualBits.SetBit(PLAYER_GUILDRANK);
@@ -3446,29 +3565,29 @@ void Player::InitVisibleBits()
updateVisualBits.SetBit(PLAYER_GUILD_TIMESTAMP);
// PLAYER_QUEST_LOG_x also visible bit on official (but only on party/raid)...
- for(uint16 i = PLAYER_QUEST_LOG_1_1; i < PLAYER_QUEST_LOG_25_2; i+=4)
+ for(uint16 i = PLAYER_QUEST_LOG_1_1; i < PLAYER_QUEST_LOG_25_2; i += 4)
updateVisualBits.SetBit(i);
- //Players visible items are not inventory stuff
- //431) = 884 (0x374) = main weapon
- for(uint16 i = 0; i < EQUIPMENT_SLOT_END; i++)
+ // Players visible items are not inventory stuff
+ for(uint16 i = 0; i < EQUIPMENT_SLOT_END; ++i)
{
- // item creator
- updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_CREATOR + (i*MAX_VISIBLE_ITEM_OFFSET) + 0);
- updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_CREATOR + (i*MAX_VISIBLE_ITEM_OFFSET) + 1);
+ uint32 offset = i * MAX_VISIBLE_ITEM_OFFSET;
- uint16 visual_base = PLAYER_VISIBLE_ITEM_1_0 + (i*MAX_VISIBLE_ITEM_OFFSET);
+ // item creator
+ updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_CREATOR + 0 + offset);
+ updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_CREATOR + 1 + offset);
// item entry
- updateVisualBits.SetBit(visual_base + 0);
+ updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_0 + 0 + offset);
- // item enchantment IDs
- for(uint8 j = 0; j < MAX_INSPECTED_ENCHANTMENT_SLOT; ++j)
- updateVisualBits.SetBit(visual_base + 1 + j);
+ // item enchantments
+ for(uint8 j = 0; j < MAX_ENCHANTMENT_SLOT; ++j)
+ updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_0 + 1 + j + offset);
// random properties
- updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_PROPERTIES + 0 + (i*MAX_VISIBLE_ITEM_OFFSET));
- updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_PROPERTIES + 1 + (i*MAX_VISIBLE_ITEM_OFFSET));
+ updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_PROPERTIES + offset);
+ updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_SEED + offset);
+ updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_PAD + offset);
}
updateVisualBits.SetBit(PLAYER_CHOSEN_TITLE);
@@ -3486,7 +3605,6 @@ void Player::BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target )
if(target == this)
{
-
for(int i = INVENTORY_SLOT_BAG_START; i < BANK_SLOT_BAG_END; i++)
{
if(m_items[i] == NULL)
@@ -3494,7 +3612,7 @@ void Player::BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target )
m_items[i]->BuildCreateUpdateBlockForPlayer( data, target );
}
- for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++)
+ for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++)
{
if(m_items[i] == NULL)
continue;
@@ -3527,7 +3645,7 @@ void Player::DestroyForPlayer( Player *target ) const
m_items[i]->DestroyForPlayer( target );
}
- for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++)
+ for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++)
{
if(m_items[i] == NULL)
continue;
@@ -3539,8 +3657,16 @@ void Player::DestroyForPlayer( Player *target ) const
bool Player::HasSpell(uint32 spell) const
{
- PlayerSpellMap::const_iterator itr = m_spells.find((uint16)spell);
- return (itr != m_spells.end() && itr->second->state != PLAYERSPELL_REMOVED && !itr->second->disabled);
+ PlayerSpellMap::const_iterator itr = m_spells.find(spell);
+ return (itr != m_spells.end() && itr->second->state != PLAYERSPELL_REMOVED &&
+ !itr->second->disabled);
+}
+
+bool Player::HasActiveSpell(uint32 spell) const
+{
+ PlayerSpellMap::const_iterator itr = m_spells.find(spell);
+ return (itr != m_spells.end() && itr->second->state != PLAYERSPELL_REMOVED &&
+ itr->second->active && !itr->second->disabled);
}
TrainerSpellState Player::GetTrainerSpellState(TrainerSpell const* trainer_spell) const
@@ -3548,22 +3674,22 @@ TrainerSpellState Player::GetTrainerSpellState(TrainerSpell const* trainer_spell
if (!trainer_spell)
return TRAINER_SPELL_RED;
- if (!trainer_spell->spell)
+ if (!trainer_spell->learnedSpell)
return TRAINER_SPELL_RED;
// known spell
- if(HasSpell(trainer_spell->spell))
+ if(HasSpell(trainer_spell->learnedSpell))
return TRAINER_SPELL_GRAY;
// check race/class requirement
- if(!IsSpellFitByClassAndRace(trainer_spell->spell))
+ if(!IsSpellFitByClassAndRace(trainer_spell->learnedSpell))
return TRAINER_SPELL_RED;
// check level requirement
- if(getLevel() < trainer_spell->reqlevel)
+ if(getLevel() < trainer_spell->reqLevel)
return TRAINER_SPELL_RED;
- if(SpellChainNode const* spell_chain = spellmgr.GetSpellChainNode(trainer_spell->spell))
+ if(SpellChainNode const* spell_chain = spellmgr.GetSpellChainNode(trainer_spell->learnedSpell))
{
// check prev.rank requirement
if(spell_chain->prev && !HasSpell(spell_chain->prev))
@@ -3578,11 +3704,11 @@ TrainerSpellState Player::GetTrainerSpellState(TrainerSpell const* trainer_spell
}
// check skill requirement
- if(trainer_spell->reqskill && GetBaseSkillValue(trainer_spell->reqskill) < trainer_spell->reqskillvalue)
+ if(trainer_spell->reqSkill && GetBaseSkillValue(trainer_spell->reqSkill) < trainer_spell->reqSkillValue)
return TRAINER_SPELL_RED;
// exist, already checked at loading
- SpellEntry const* spell = sSpellStore.LookupEntry(trainer_spell->spell);
+ SpellEntry const* spell = sSpellStore.LookupEntry(trainer_spell->learnedSpell);
// secondary prof. or not prof. spell
uint32 skill = spell->EffectMiscValue[1];
@@ -3615,27 +3741,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
}
// remove from arena teams
- uint32 at_id = GetArenaTeamIdFromDB(playerguid,ARENA_TEAM_2v2);
- if(at_id != 0)
- {
- ArenaTeam * at = objmgr.GetArenaTeamById(at_id);
- if(at)
- at->DelMember(playerguid);
- }
- at_id = GetArenaTeamIdFromDB(playerguid,ARENA_TEAM_3v3);
- if(at_id != 0)
- {
- ArenaTeam * at = objmgr.GetArenaTeamById(at_id);
- if(at)
- at->DelMember(playerguid);
- }
- at_id = GetArenaTeamIdFromDB(playerguid,ARENA_TEAM_5v5);
- if(at_id != 0)
- {
- ArenaTeam * at = objmgr.GetArenaTeamById(at_id);
- if(at)
- at->DelMember(playerguid);
- }
+ LeaveAllArenaTeams(playerguid);
// the player was uninvited already on logout so just remove from group
QueryResult *resultGroup = CharacterDatabase.PQuery("SELECT leaderGuid FROM group_member WHERE memberGuid='%u'", guid);
@@ -3676,15 +3782,16 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
MailItemsInfo mi;
if(has_items)
{
- QueryResult *resultItems = CharacterDatabase.PQuery("SELECT item_guid,item_template FROM mail_items WHERE mail_id='%u'", mail_id);
+ // data needs to be at first place for Item::LoadFromDB
+ QueryResult *resultItems = CharacterDatabase.PQuery("SELECT data,item_guid,item_template FROM mail_items JOIN item_instance ON item_guid = guid WHERE mail_id='%u'", mail_id);
if(resultItems)
{
do
{
Field *fields2 = resultItems->Fetch();
- uint32 item_guidlow = fields2[0].GetUInt32();
- uint32 item_template = fields2[1].GetUInt32();
+ uint32 item_guidlow = fields2[1].GetUInt32();
+ uint32 item_template = fields2[2].GetUInt32();
ItemPrototype const* itemProto = objmgr.GetItemPrototype(item_template);
if(!itemProto)
@@ -3694,7 +3801,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
}
Item *pItem = NewItemOrBag(itemProto);
- if(!pItem->LoadFromDB(item_guidlow, MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER)))
+ if(!pItem->LoadFromDB(item_guidlow, MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER),resultItems))
{
pItem->FSetState(ITEM_REMOVED);
pItem->SaveToDB(); // it also deletes item object !
@@ -3757,6 +3864,8 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
CharacterDatabase.PExecute("DELETE FROM mail_items WHERE receiver = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_pet WHERE owner = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_pet_declinedname WHERE owner = '%u'",guid);
+ CharacterDatabase.PExecute("DELETE FROM character_achievement WHERE guid = '%u'",guid);
+ CharacterDatabase.PExecute("DELETE FROM character_achievement_progress WHERE guid = '%u'",guid);
CharacterDatabase.CommitTransaction();
//LoginDatabase.PExecute("UPDATE realmcharacters SET numchars = numchars - 1 WHERE acctid = %d AND realmid = %d", accountId, realmID);
@@ -3787,6 +3896,10 @@ void Player::SetMovement(PlayerMovementType pType)
*/
void Player::BuildPlayerRepop()
{
+ WorldPacket data(SMSG_PRE_RESURRECT, GetPackGUID().size());
+ data.append(GetPackGUID());
+ GetSession()->SendPacket(&data);
+
if(getRace() == RACE_NIGHTELF)
CastSpell(this, 20584, true); // 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)
CastSpell(this, 8326, true); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?)
@@ -3831,7 +3944,8 @@ void Player::BuildPlayerRepop()
SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, (float)1.0); //see radius of death player?
- SetByteValue(UNIT_FIELD_BYTES_1, 3, PLAYER_STATE_FLAG_ALWAYS_STAND);
+ // set and clear other
+ SetByteValue(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND);
}
void Player::SendDelayResponse(const uint32 ml_seconds)
@@ -3906,8 +4020,7 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
{
if(Aura* Aur = GetAura(SPELL_ID_PASSIVE_RESURRECTION_SICKNESS,i))
{
- Aur->SetAuraDuration(delta*1000);
- Aur->UpdateAuraDuration();
+ Aur->SetAuraDurationAndUpdate(delta*1000);
}
}
}
@@ -3948,8 +4061,7 @@ void Player::CreateCorpse()
Corpse *corpse = new Corpse( (m_ExtraFlags & PLAYER_EXTRA_PVP_DEATH) ? CORPSE_RESURRECTABLE_PVP : CORPSE_RESURRECTABLE_PVE );
SetPvPDeath(false);
- if(!corpse->Create(objmgr.GenerateLowGuid(HIGHGUID_CORPSE), this, GetMapId(), GetPositionX(),
- GetPositionY(), GetPositionZ(), GetOrientation()))
+ if(!corpse->Create(objmgr.GenerateLowGuid(HIGHGUID_CORPSE), this))
{
delete corpse;
return;
@@ -4445,7 +4557,7 @@ uint32 Player::GetShieldBlockValue() const
{
BaseModGroup modGroup = SHIELD_BLOCK_VALUE;
- float value = GetTotalBaseModValue(modGroup) + GetStat(STAT_STRENGTH)/20 - 1;
+ float value = GetTotalBaseModValue(modGroup) + GetStat(STAT_STRENGTH) * 0.5f - 10;
value = (value < 0) ? 0 : value;
@@ -4634,7 +4746,18 @@ float Player::OCTRegenMPPerSpirit()
void Player::ApplyRatingMod(CombatRating cr, int32 value, bool apply)
{
- ApplyModUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + cr, value, apply);
+ m_baseRatingValue[cr]+=(apply ? value : -value);
+
+ int32 amount = uint32(m_baseRatingValue[cr]);
+ // Apply bonus from SPELL_AURA_MOD_RATING_FROM_STAT
+ // stat used stored in miscValueB for this aura
+ AuraList const& modRatingFromStat = GetAurasByType(SPELL_AURA_MOD_RATING_FROM_STAT);
+ for(AuraList::const_iterator i = modRatingFromStat.begin();i != modRatingFromStat.end(); ++i)
+ if ((*i)->GetMiscValue() & (1<<cr))
+ amount += int32(GetStat(Stats((*i)->GetMiscBValue())) * (*i)->GetModifier()->m_amount / 100.0f);
+ if (amount < 0)
+ amount = 0;
+ SetUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + cr, uint32(amount));
float RatingCoeffecient = GetRatingCoefficient(cr);
float RatingChange = 0.0f;
@@ -4657,16 +4780,13 @@ void Player::ApplyRatingMod(CombatRating cr, int32 value, bool apply)
UpdateBlockPercentage();
break;
case CR_HIT_MELEE:
- RatingChange = value / RatingCoeffecient;
- m_modMeleeHitChance += apply ? RatingChange : -RatingChange;
+ UpdateMeleeHitChances();
break;
case CR_HIT_RANGED:
- RatingChange = value / RatingCoeffecient;
- m_modRangedHitChance += apply ? RatingChange : -RatingChange;
+ UpdateRangedHitChances();
break;
case CR_HIT_SPELL:
- RatingChange = value / RatingCoeffecient;
- m_modSpellHitChance += apply ? RatingChange : -RatingChange;
+ UpdateSpellHitChances();
break;
case CR_CRIT_MELEE:
if(affectStats)
@@ -4764,6 +4884,7 @@ bool Player::UpdateSkill(uint32 skill_id, uint32 step)
new_value = max;
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(new_value,max));
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL);
return true;
}
@@ -4799,7 +4920,7 @@ bool Player::UpdateCraftSkill(uint32 spellid)
if(spellEntry && spellEntry->Mechanic==MECHANIC_DISCOVERY)
{
if(uint32 discoveredSpell = GetSkillDiscoverySpell(_spell_idx->second->skillId, spellid, this))
- learnSpell(discoveredSpell);
+ learnSpell(discoveredSpell,false);
}
uint32 craft_skill_gain = sWorld.getConfig(CONFIG_SKILL_GAIN_CRAFTING);
@@ -4826,6 +4947,7 @@ bool Player::UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLeve
case SKILL_HERBALISM:
case SKILL_LOCKPICKING:
case SKILL_JEWELCRAFTING:
+ case SKILL_INSCRIPTION:
return UpdateSkillPro(SkillId, SkillGainChance(SkillValue, RedLevel+100, RedLevel+50, RedLevel+25)*Multiplicator,gathering_skill_gain);
case SKILL_SKINNING:
if( sWorld.getConfig(CONFIG_SKILL_CHANCE_SKINNING_STEPS)==0)
@@ -4854,6 +4976,11 @@ 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};
+
bool Player::UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step)
{
sLog.outDebug("UpdateSkillPro(SkillId %d, Chance %3.1f%%)", SkillId, Chance/10.0);
@@ -4888,6 +5015,15 @@ bool Player::UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step)
new_value = MaxValue;
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(new_value,MaxValue));
+ for(uint32* bsl = &bonusSkillLevels[0]; *bsl; ++bsl)
+ {
+ if((SkillValue < *bsl && new_value >= *bsl))
+ {
+ learnSkillRewardedSpells( SkillId, new_value);
+ break;
+ }
+ }
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL);
sLog.outDebug("Player::UpdateSkillPro Chance=%3.1f%% taken", Chance/10.0);
return true;
}
@@ -4935,22 +5071,8 @@ void Player::UpdateWeaponSkill (WeaponAttackType attType)
UpdateAllCritPercentages();
}
-void Player::UpdateCombatSkills(Unit *pVictim, WeaponAttackType attType, MeleeHitOutcome outcome, bool defence)
+void Player::UpdateCombatSkills(Unit *pVictim, WeaponAttackType attType, bool defence)
{
-/* Not need, this checked on call this func from trigger system
- switch(outcome)
- {
- case MELEE_HIT_CRIT:
- case MELEE_HIT_DODGE:
- case MELEE_HIT_PARRY:
- case MELEE_HIT_BLOCK:
- case MELEE_HIT_BLOCK_CRIT:
- return;
-
- default:
- break;
- }
-*/
uint32 plevel = getLevel(); // if defense than pVictim == attacker
uint32 greylevel = Trinity::XP::GetGrayLevel(plevel);
uint32 moblevel = pVictim->getLevelForTarget(this);
@@ -5047,7 +5169,7 @@ void Player::UpdateSkillsToMaxSkillsForLevel()
if (GetUInt32Value(PLAYER_SKILL_INDEX(i)))
{
uint32 pskill = GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF;
- if( IsProfessionSkill(pskill) || pskill == SKILL_RIDING )
+ if( IsProfessionOrRidingSkill(pskill))
continue;
uint32 data = GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i));
@@ -5075,7 +5197,11 @@ void Player::SetSkill(uint32 id, uint16 currVal, uint16 maxVal)
if(i<PLAYER_MAX_SKILLS) //has skill
{
if(currVal)
+ {
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(currVal,maxVal));
+ learnSkillRewardedSpells(id, currVal);
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL);
+ }
else //remove
{
// clear skill fields
@@ -5083,27 +5209,11 @@ void Player::SetSkill(uint32 id, uint16 currVal, uint16 maxVal)
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),0);
SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i),0);
- // remove spells that depend on this skill when removing the skill
- for (PlayerSpellMap::const_iterator itr = m_spells.begin(), next = m_spells.begin(); itr != m_spells.end(); itr = next)
- {
- ++next;
- if(itr->second->state == PLAYERSPELL_REMOVED)
- continue;
-
- SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(itr->first);
- SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(itr->first);
-
- for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
- {
- if (_spell_idx->second->skillId == id)
- {
- // this may remove more than one spell (dependents)
- removeSpell(itr->first);
- next = m_spells.begin();
- break;
- }
- }
- }
+ // remove all spells that related to this skill
+ for (uint32 j=0; j<sSkillLineAbilityStore.GetNumRows(); ++j)
+ if(SkillLineAbilityEntry const *pAbility = sSkillLineAbilityStore.LookupEntry(j))
+ if (pAbility->skillId==id)
+ removeSpell(spellmgr.GetFirstSpellInChain(pAbility->spellId));
}
}
else if(currVal) //add
@@ -5123,6 +5233,7 @@ void Player::SetSkill(uint32 id, uint16 currVal, uint16 maxVal)
else
SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id,0));
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(currVal,maxVal));
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL);
// apply skill bonuses
SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i),0);
@@ -5140,7 +5251,7 @@ void Player::SetSkill(uint32 id, uint16 currVal, uint16 maxVal)
(*i)->ApplyModifier(true);
// Learn all spells for skill
- learnSkillRewardedSpells(id);
+ learnSkillRewardedSpells(id, currVal);
return;
}
}
@@ -5238,6 +5349,22 @@ uint16 Player::GetPureSkillValue(uint32 skill) const
return 0;
}
+int16 Player::GetSkillPermBonusValue(uint32 skill) const
+{
+ if(!skill)
+ return 0;
+
+ for (int i = 0; i < PLAYER_MAX_SKILLS; i++)
+ {
+ if ((GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF) == skill)
+ {
+ return SKILL_PERM_BONUS(GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i)));
+ }
+ }
+
+ return 0;
+}
+
int16 Player::GetSkillTempBonusValue(uint32 skill) const
{
if(!skill)
@@ -5419,14 +5546,14 @@ void Player::CheckExploreSystem()
if (isInFlight())
return;
- uint16 areaFlag=MapManager::Instance().GetBaseMap(GetMapId())->GetAreaFlag(GetPositionX(),GetPositionY());
+ uint16 areaFlag=MapManager::Instance().GetBaseMap(GetMapId())->GetAreaFlag(GetPositionX(),GetPositionY(),GetPositionZ());
if(areaFlag==0xffff)
return;
int offset = areaFlag / 32;
if(offset >= 128)
{
- sLog.outError("ERROR: Wrong area flag %u in map data for (X: %f Y: %f) point to field PLAYER_EXPLORED_ZONES_1 + %u ( %u must be < 64 ).",areaFlag,GetPositionX(),GetPositionY(),offset,offset);
+ sLog.outError("ERROR: Wrong area flag %u in map data for (X: %f Y: %f) point to field PLAYER_EXPLORED_ZONES_1 + %u ( %u must be < 128 ).",areaFlag,GetPositionX(),GetPositionY(),offset,offset);
return;
}
@@ -5437,6 +5564,8 @@ void Player::CheckExploreSystem()
{
SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val));
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA);
+
AreaTableEntry const *p = GetAreaEntryByAreaFlagAndMap(areaFlag,GetMapId());
if(!p)
{
@@ -5533,6 +5662,7 @@ void Player::SendFactionState(FactionState const* faction) const
{
WorldPacket data(SMSG_SET_FACTION_STANDING, (16)); // last check 2.4.0
data << (float) 0; // unk 2.4.0
+ data << (uint8) 0; // wotlk 8634
data << (uint32) 1; // count
// for
data << (uint32) faction->ReputationListID;
@@ -5864,7 +5994,8 @@ bool Player::ModifyOneFactionReputation(FactionEntry const* factionEntry, int32
}
}
}
-
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION);
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION);
SendFactionState(&(itr->second));
return true;
@@ -5930,6 +6061,8 @@ bool Player::SetOneFactionReputation(FactionEntry const* factionEntry, int32 sta
SetFactionAtWar(&itr->second,true);
SendFactionState(&(itr->second));
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION);
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION);
return true;
}
return false;
@@ -6128,12 +6261,7 @@ bool Player::RewardHonor(Unit *uVictim, uint32 groupsize, float honor, bool pvpt
victim_guid = 0; // Don't show HK: <rank> message, only log.
}
- if(k_level <= 5)
- k_grey = 0;
- else if( k_level <= 39 )
- k_grey = k_level - 5 - k_level/10;
- else
- k_grey = k_level - 1 - k_level/5;
+ k_grey = Trinity::XP::GetGrayLevel(k_level);
if(v_level<=k_grey)
return false;
@@ -6169,6 +6297,8 @@ bool Player::RewardHonor(Unit *uVictim, uint32 groupsize, float honor, bool pvpt
if(groupsize > 1)
honor /= groupsize;
+ // apply honor multiplier from aura (not stacking-get highest)
+ honor = int32(float(honor) * (float(GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HONOR_GAIN_PCT))+100.0f)/100.0f);
honor *= (((float)urand(8,12))/10); // approx honor: 80% - 120% of real honor
}
@@ -6198,8 +6328,8 @@ bool Player::RewardHonor(Unit *uVictim, uint32 groupsize, float honor, bool pvpt
{
// Check if allowed to receive it in current map
uint8 MapType = sWorld.getConfig(CONFIG_PVP_TOKEN_MAP_TYPE);
- if( (MapType == 1 && !InBattleGround() && !HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP))
- || (MapType == 2 && !HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP))
+ if( (MapType == 1 && !InBattleGround() && !HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
+ || (MapType == 2 && !HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
|| (MapType == 3 && !InBattleGround()) )
return true;
@@ -6257,24 +6387,18 @@ void Player::ModifyArenaPoints( int32 value )
uint32 Player::GetGuildIdFromDB(uint64 guid)
{
- std::ostringstream ss;
- ss<<"SELECT guildid FROM guild_member WHERE guid='"<<guid<<"'";
- QueryResult *result = CharacterDatabase.Query( ss.str().c_str() );
- if( result )
- {
- uint32 v = result->Fetch()[0].GetUInt32();
- delete result;
- return v;
- }
- else
+ QueryResult* result = CharacterDatabase.PQuery("SELECT guildid FROM guild_member WHERE guid='%u'", GUID_LOPART(guid));
+ if(!result)
return 0;
+
+ uint32 id = result->Fetch()[0].GetUInt32();
+ delete result;
+ return id;
}
uint32 Player::GetRankFromDB(uint64 guid)
{
- std::ostringstream ss;
- ss<<"SELECT rank FROM guild_member WHERE guid='"<<guid<<"'";
- QueryResult *result = CharacterDatabase.Query( ss.str().c_str() );
+ QueryResult *result = CharacterDatabase.PQuery( "SELECT rank FROM guild_member WHERE guid='%u'", GUID_LOPART(guid) );
if( result )
{
uint32 v = result->Fetch()[0].GetUInt32();
@@ -6298,10 +6422,8 @@ uint32 Player::GetArenaTeamIdFromDB(uint64 guid, uint8 type)
uint32 Player::GetZoneIdFromDB(uint64 guid)
{
- std::ostringstream ss;
-
- ss<<"SELECT zone FROM characters WHERE guid='"<<GUID_LOPART(guid)<<"'";
- QueryResult *result = CharacterDatabase.Query( ss.str().c_str() );
+ uint32 guidLow = GUID_LOPART(guid);
+ QueryResult *result = CharacterDatabase.PQuery( "SELECT zone FROM characters WHERE guid='%u'", guidLow );
if (!result)
return 0;
Field* fields = result->Fetch();
@@ -6311,22 +6433,19 @@ uint32 Player::GetZoneIdFromDB(uint64 guid)
if (!zone)
{
// stored zone is zero, use generic and slow zone detection
- ss.str("");
- ss<<"SELECT map,position_x,position_y FROM characters WHERE guid='"<<GUID_LOPART(guid)<<"'";
- result = CharacterDatabase.Query(ss.str().c_str());
+ result = CharacterDatabase.PQuery("SELECT map,position_x,position_y,position_z FROM characters WHERE guid='%u'", guidLow);
if( !result )
return 0;
fields = result->Fetch();
- uint32 map = fields[0].GetUInt32();
+ uint32 map = fields[0].GetUInt32();
float posx = fields[1].GetFloat();
float posy = fields[2].GetFloat();
+ float posz = fields[3].GetFloat();
delete result;
- zone = MapManager::Instance().GetZoneId(map,posx,posy);
+ zone = MapManager::Instance().GetZoneId(map,posx,posy,posz);
- ss.str("");
- ss << "UPDATE characters SET zone='"<<zone<<"' WHERE guid='"<<GUID_LOPART(guid)<<"'";
- CharacterDatabase.Execute(ss.str().c_str());
+ CharacterDatabase.PExecute("UPDATE characters SET zone='%u' WHERE guid='%u'", zone, guidLow);
}
return zone;
@@ -6343,14 +6462,14 @@ void Player::UpdateArea(uint32 newArea)
if(area && (area->flags & AREA_FLAG_ARENA))
{
if(!isGameMaster())
- SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP);
+ SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
}
else
{
// remove ffa flag only if not ffapvp realm
// removal in sanctuaries and capitals is handled in zone update
- if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP) && !sWorld.IsFFAPvPRealm())
- RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP);
+ if(HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP) && !sWorld.IsFFAPvPRealm())
+ RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
}
UpdateAreaDependentAuras(newArea);
@@ -6412,13 +6531,13 @@ void Player::UpdateZone(uint32 newZone)
if(zone->flags & AREA_FLAG_SANCTUARY) // in sanctuary
{
- SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_SANCTUARY);
+ SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY);
if(sWorld.IsFFAPvPRealm())
- RemoveFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP);
+ RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
}
else
{
- RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_SANCTUARY);
+ RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY);
}
if(zone->flags & AREA_FLAG_CAPITAL) // in capital city
@@ -6428,7 +6547,7 @@ void Player::UpdateZone(uint32 newZone)
InnEnter(time(0),GetMapId(),0,0,0);
if(sWorld.IsFFAPvPRealm())
- RemoveFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP);
+ RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
}
else // anywhere else
{
@@ -6442,7 +6561,7 @@ void Player::UpdateZone(uint32 newZone)
SetRestType(REST_TYPE_NO);
if(sWorld.IsFFAPvPRealm())
- SetFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP);
+ SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
}
}
else // not in tavern (leave city then)
@@ -6452,7 +6571,7 @@ void Player::UpdateZone(uint32 newZone)
// Set player to FFA PVP when not in rested environment.
if(sWorld.IsFFAPvPRealm())
- SetFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP);
+ SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
}
}
}
@@ -6622,7 +6741,12 @@ void Player::_ApplyItemMods(Item *item, uint8 slot,bool apply)
sLog.outDetail("applying mods for item %u ",item->GetGUIDLow());
- uint32 attacktype = Player::GetAttackBySlot(slot);
+ uint8 attacktype = Player::GetAttackBySlot(slot);
+
+ //check disarm only on mod apply to allow remove item mods
+ if (apply && !CanUseAttackType(attacktype) )
+ return;
+
if(attacktype < MAX_ATTACK)
_ApplyWeaponDependentAuraMods(item,WeaponAttackType(attacktype),apply);
@@ -6640,19 +6764,43 @@ void Player::_ApplyItemMods(Item *item, uint8 slot,bool apply)
sLog.outDebug("_ApplyItemMods complete.");
}
-void Player::_ApplyItemBonuses(ItemPrototype const *proto,uint8 slot,bool apply)
+void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool apply)
{
if(slot >= INVENTORY_SLOT_BAG_END || !proto)
return;
for (int i = 0; i < 10; i++)
{
- float val = float (proto->ItemStat[i].ItemStatValue);
+ uint32 statType = 0;
+ int32 val = 0;
- if(val==0)
+ if(proto->ScalingStatDistribution)
+ {
+ if(ScalingStatDistributionEntry const *ssd = sScalingStatDistributionStore.LookupEntry(proto->ScalingStatDistribution))
+ {
+ statType = ssd->StatMod[i];
+
+ if(uint32 modifier = ssd->Modifier[i])
+ {
+ uint32 level = ((getLevel() > ssd->MaxLevel) ? ssd->MaxLevel : getLevel());
+ if(ScalingStatValuesEntry const *ssv = sScalingStatValuesStore.LookupEntry(level))
+ {
+ uint32 multiplier = ssv->Multiplier[proto->GetScalingStatValuesColumn()];
+ val = (multiplier * modifier) / 10000;
+ }
+ }
+ }
+ }
+ else
+ {
+ statType = proto->ItemStat[i].ItemStatType;
+ val = proto->ItemStat[i].ItemStatValue;
+ }
+
+ if(val == 0)
continue;
- switch (proto->ItemStat[i].ItemStatType)
+ switch (statType)
{
case ITEM_MOD_MANA:
HandleStatModifier(UNIT_MOD_MANA, BASE_VALUE, float(val), apply);
@@ -6770,6 +6918,32 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto,uint8 slot,bool apply)
case ITEM_MOD_EXPERTISE_RATING:
ApplyRatingMod(CR_EXPERTISE, int32(val), apply);
break;
+ case ITEM_MOD_ATTACK_POWER:
+ HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(val), apply);
+ HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(val), apply);
+ break;
+ 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_SPELL_HEALING_DONE:
+ ApplySpellHealingBonus(int32(val), apply);
+ break;
+ case ITEM_MOD_SPELL_DAMAGE_DONE:
+ ApplySpellDamageBonus(int32(val), apply);
+ break;
+ case ITEM_MOD_MANA_REGENERATION:
+ ApplyManaRegenBonus(int32(val), apply);
+ break;
+ case ITEM_MOD_ARMOR_PENETRATION_RATING:
+ ApplyRatingMod(CR_ARMOR_PENETRATION, int32(val), apply);
+ break;
+ case ITEM_MOD_SPELL_POWER:
+ ApplySpellHealingBonus(int32(val), apply);
+ ApplySpellDamageBonus(int32(val), apply);
+ break;
}
}
@@ -6824,7 +6998,15 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto,uint8 slot,bool apply)
SetBaseWeaponDamage(attType, MAXDAMAGE, damage);
}
- if(!IsUseEquipedWeapon(slot==EQUIPMENT_SLOT_MAINHAND))
+ // Druids get feral AP bonus from weapon dps
+ if(getClass() == CLASS_DRUID)
+ {
+ int32 feral_bonus = proto->getFeralBonus();
+ if (feral_bonus > 0)
+ ApplyFeralAPBonus(feral_bonus, apply);
+ }
+
+ if(IsInFeralForm() || !CanUseAttackType(attType))
return;
if (proto->Delay)
@@ -6873,7 +7055,7 @@ void Player::_ApplyWeaponDependentAuraCritMod(Item *item, WeaponAttackType attac
if (item->IsFitToSpellRequirements(aura->GetSpellProto()))
{
- HandleBaseModValue(mod, FLAT_MOD, float (aura->GetModifierValue()), apply);
+ HandleBaseModValue(mod, FLAT_MOD, float (aura->GetModifier()->m_amount), apply);
}
}
@@ -6907,7 +7089,7 @@ void Player::_ApplyWeaponDependentAuraDamageMod(Item *item, WeaponAttackType att
if (item->IsFitToSpellRequirements(aura->GetSpellProto()))
{
- HandleStatModifier(unitMod, unitModType, float(aura->GetModifierValue()),apply);
+ HandleStatModifier(unitMod, unitModType, float(aura->GetModifier()->m_amount),apply);
}
}
@@ -7102,6 +7284,92 @@ void Player::CastItemCombatSpell(Item *item,Unit* Target, WeaponAttackType attTy
}
}
+void Player::CastItemUseSpell(Item *item,SpellCastTargets const& targets,uint8 cast_count, uint32 glyphIndex)
+{
+ ItemPrototype const* proto = item->GetProto();
+ // special learning case
+ if(proto->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN || proto->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN_PET)
+ {
+ uint32 learn_spell_id = proto->Spells[0].SpellId;
+ uint32 learning_spell_id = proto->Spells[1].SpellId;
+
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(learn_spell_id);
+ if(!spellInfo)
+ {
+ sLog.outError("Player::CastItemUseSpell: Item (Entry: %u) in have wrong spell id %u, ignoring ",proto->ItemId, learn_spell_id);
+ SendEquipError(EQUIP_ERR_NONE,item,NULL);
+ return;
+ }
+
+ Spell *spell = new Spell(this, spellInfo, false);
+ spell->m_CastItem = item;
+ spell->m_cast_count = cast_count; //set count of casts
+ spell->m_currentBasePoints[0] = learning_spell_id;
+ spell->prepare(&targets);
+ return;
+ }
+
+ // use triggered flag only for items with many spell casts and for not first cast
+ int count = 0;
+
+ // item spells casted at use
+ for(int i = 0; i < 5; ++i)
+ {
+ _Spell const& spellData = proto->Spells[i];
+
+ // no spell
+ if(!spellData.SpellId)
+ continue;
+
+ // wrong triggering type
+ if( spellData.SpellTrigger != ITEM_SPELLTRIGGER_ON_USE && spellData.SpellTrigger != ITEM_SPELLTRIGGER_ON_NO_DELAY_USE)
+ continue;
+
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellData.SpellId);
+ if(!spellInfo)
+ {
+ sLog.outError("Player::CastItemUseSpell: Item (Entry: %u) in have wrong spell id %u, ignoring",proto->ItemId, spellData.SpellId);
+ continue;
+ }
+
+ Spell *spell = new Spell(this, spellInfo, (count > 0));
+ spell->m_CastItem = item;
+ spell->m_cast_count = cast_count; // set count of casts
+ spell->m_glyphIndex = glyphIndex; // glyph index
+ spell->prepare(&targets);
+
+ ++count;
+ }
+
+ // Item enchantments spells casted at use
+ for(int e_slot = 0; e_slot < MAX_ENCHANTMENT_SLOT; ++e_slot)
+ {
+ uint32 enchant_id = item->GetEnchantmentId(EnchantmentSlot(e_slot));
+ SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
+ if(!pEnchant) continue;
+ for (int s=0;s<3;s++)
+ {
+ if(pEnchant->type[s]!=ITEM_ENCHANTMENT_TYPE_USE_SPELL)
+ continue;
+
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(pEnchant->spellid[s]);
+ if (!spellInfo)
+ {
+ sLog.outError("Player::CastItemUseSpell Enchant %i, cast unknown spell %i", pEnchant->ID, pEnchant->spellid[s]);
+ continue;
+ }
+
+ Spell *spell = new Spell(this, spellInfo, (count > 0));
+ spell->m_CastItem = item;
+ spell->m_cast_count = cast_count; // set count of casts
+ spell->m_glyphIndex = glyphIndex; // glyph index
+ spell->prepare(&targets);
+
+ ++count;
+ }
+ }
+}
+
void Player::_RemoveAllItemMods()
{
sLog.outDebug("_RemoveAllItemMods start.");
@@ -7277,7 +7545,7 @@ void Player::RemovedInsignia(Player* looterPlr)
// We have to convert player corpse to bones, not to be able to resurrect there
// SpawnCorpseBones isn't handy, 'cos it saves player while he in BG
- Corpse *bones = ObjectAccessor::Instance().ConvertCorpseForPlayer(GetGUID());
+ Corpse *bones = ObjectAccessor::Instance().ConvertCorpseForPlayer(GetGUID(),true);
if (!bones)
return;
@@ -7344,11 +7612,11 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
{
sLog.outDebug(" if(lootid)");
loot->clear();
- loot->FillLoot(lootid, LootTemplates_Gameobject, this);
+ loot->FillLoot(lootid, LootTemplates_Gameobject, this, false);
}
if(loot_type == LOOT_FISHING)
- go->getFishLoot(loot);
+ go->getFishLoot(loot,this);
go->SetLootState(GO_ACTIVATED);
}
@@ -7371,7 +7639,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
{
item->m_lootGenerated = true;
loot->clear();
- loot->FillLoot(item->GetProto()->DisenchantID, LootTemplates_Disenchant, this);
+ loot->FillLoot(item->GetProto()->DisenchantID, LootTemplates_Disenchant, this,true);
}
}
else if(loot_type == LOOT_PROSPECTING)
@@ -7382,7 +7650,18 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
{
item->m_lootGenerated = true;
loot->clear();
- loot->FillLoot(item->GetEntry(), LootTemplates_Prospecting, this);
+ loot->FillLoot(item->GetEntry(), LootTemplates_Prospecting, this,true);
+ }
+ }
+ else if(loot_type == LOOT_MILLING)
+ {
+ loot = &item->loot;
+
+ if(!item->m_lootGenerated)
+ {
+ item->m_lootGenerated = true;
+ loot->clear();
+ loot->FillLoot(item->GetEntry(), LootTemplates_Milling, this,true);
}
}
else
@@ -7393,7 +7672,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
{
item->m_lootGenerated = true;
loot->clear();
- loot->FillLoot(item->GetEntry(), LootTemplates_Item, this);
+ loot->FillLoot(item->GetEntry(), LootTemplates_Item, this,true);
loot->generateMoneyLoot(item->GetProto()->MinMoneyLoot,item->GetProto()->MaxMoneyLoot);
}
@@ -7417,7 +7696,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
uint32 pLevel = bones->loot.gold;
bones->loot.clear();
if(GetBattleGround()->GetTypeID() == BATTLEGROUND_AV)
- loot->FillLoot(1, LootTemplates_Creature, this);
+ loot->FillLoot(1, LootTemplates_Creature, this, true);
// It may need a better formula
// Now it works like this: lvl10: ~6copper, lvl70: ~9silver
bones->loot.gold = (uint32)( urand(50, 150) * 0.016f * pow( ((float)pLevel)/5.76f, 2.5f) * sWorld.getRate(RATE_DROP_MONEY) );
@@ -7453,7 +7732,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
loot->clear();
if (uint32 lootid = creature->GetCreatureInfo()->pickpocketLootId)
- loot->FillLoot(lootid, LootTemplates_Pickpocketing, this);
+ loot->FillLoot(lootid, LootTemplates_Pickpocketing, this, false);
// Generate extra money for pick pocket loot
const uint32 a = urand(0, creature->getLevel()/2);
@@ -7483,7 +7762,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
loot->clear();
if (uint32 lootid = creature->GetCreatureInfo()->lootid)
- loot->FillLoot(lootid, LootTemplates_Creature, recipient);
+ loot->FillLoot(lootid, LootTemplates_Creature, recipient, false);
loot->generateMoneyLoot(creature->GetCreatureInfo()->mingold,creature->GetCreatureInfo()->maxgold);
@@ -7513,7 +7792,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
if (loot_type == LOOT_SKINNING)
{
loot->clear();
- loot->FillLoot(creature->GetCreatureInfo()->SkinLootId, LootTemplates_Skinning, this);
+ loot->FillLoot(creature->GetCreatureInfo()->SkinLootId, LootTemplates_Skinning, this, false);
}
// set group rights only for loot_type != LOOT_SKINNING
else
@@ -7547,41 +7826,8 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
SetLootGUID(guid);
- QuestItemList *q_list = 0;
- if (permission != NONE_PERMISSION)
- {
- QuestItemMap const& lootPlayerQuestItems = loot->GetPlayerQuestItems();
- QuestItemMap::const_iterator itr = lootPlayerQuestItems.find(GetGUIDLow());
- if (itr == lootPlayerQuestItems.end())
- q_list = loot->FillQuestLoot(this);
- else
- q_list = itr->second;
- }
-
- QuestItemList *ffa_list = 0;
- if (permission != NONE_PERMISSION)
- {
- QuestItemMap const& lootPlayerFFAItems = loot->GetPlayerFFAItems();
- QuestItemMap::const_iterator itr = lootPlayerFFAItems.find(GetGUIDLow());
- if (itr == lootPlayerFFAItems.end())
- ffa_list = loot->FillFFALoot(this);
- else
- ffa_list = itr->second;
- }
-
- QuestItemList *conditional_list = 0;
- if (permission != NONE_PERMISSION)
- {
- QuestItemMap const& lootPlayerNonQuestNonFFAConditionalItems = loot->GetPlayerNonQuestNonFFAConditionalItems();
- QuestItemMap::const_iterator itr = lootPlayerNonQuestNonFFAConditionalItems.find(GetGUIDLow());
- if (itr == lootPlayerNonQuestNonFFAConditionalItems.end())
- conditional_list = loot->FillNonQuestNonFFAConditionalLoot(this);
- else
- conditional_list = itr->second;
- }
-
- // LOOT_PICKPOCKETING, LOOT_PROSPECTING, LOOT_DISENCHANTING and LOOT_INSIGNIA unsupported by client, sending LOOT_SKINNING instead
- if(loot_type == LOOT_PICKPOCKETING || loot_type == LOOT_DISENCHANTING || loot_type == LOOT_PROSPECTING || loot_type == LOOT_INSIGNIA)
+ // LOOT_PICKPOCKETING, LOOT_PROSPECTING, LOOT_DISENCHANTING, LOOT_INSIGNIA and LOOT_MILLING unsupported by client, sending LOOT_SKINNING instead
+ if(loot_type == LOOT_PICKPOCKETING || loot_type == LOOT_DISENCHANTING || loot_type == LOOT_PROSPECTING || loot_type == LOOT_INSIGNIA || loot_type == LOOT_MILLING)
loot_type = LOOT_SKINNING;
if(loot_type == LOOT_FISHINGHOLE)
@@ -7591,7 +7837,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
data << uint64(guid);
data << uint8(loot_type);
- data << LootView(*loot, q_list, ffa_list, conditional_list, this, permission);
+ data << LootView(*loot, this, permission);
SendDirectMessage(&data);
@@ -7658,46 +7904,46 @@ void Player::SendInitWorldStates(bool forceZone, uint32 forceZoneId)
case 1537:
case 2257:
case 2918:
- NumberOfFields = 6;
+ NumberOfFields = 8;
break;
case 139:
- NumberOfFields = 39;
+ NumberOfFields = 41;
break;
case 1377:
- NumberOfFields = 13;
+ NumberOfFields = 15;
break;
case 2597:
- NumberOfFields = 81;
+ NumberOfFields = 83;
break;
case 3277:
- NumberOfFields = 14;
+ NumberOfFields = 16;
break;
case 3358:
case 3820:
- NumberOfFields = 38;
+ NumberOfFields = 40;
break;
case 3483:
- NumberOfFields = 25;
+ NumberOfFields = 27;
break;
case 3518:
- NumberOfFields = 37;
+ NumberOfFields = 39;
break;
case 3519:
- NumberOfFields = 36;
+ NumberOfFields = 38;
break;
case 3521:
- NumberOfFields = 35;
+ NumberOfFields = 37;
break;
case 3698:
case 3702:
case 3968:
- NumberOfFields = 9;
+ NumberOfFields = 11;
break;
case 3703:
- NumberOfFields = 9;
+ NumberOfFields = 11;
break;
default:
- NumberOfFields = 10;
+ NumberOfFields = 12;
break;
}
@@ -7712,6 +7958,10 @@ void Player::SendInitWorldStates(bool forceZone, uint32 forceZoneId)
data << uint32(0x8d5) << uint32(0x0); // 4
data << uint32(0x8d4) << uint32(0x0); // 5
data << uint32(0x8d3) << uint32(0x0); // 6
+ // 7 1 - Arena season in progress, 0 - end of season
+ data << uint32(0xC77) << uint32(sWorld.getConfig(CONFIG_ARENA_SEASON_IN_PROGRESS));
+ // 8 Arena season id
+ data << uint32(0xF3D) << uint32(sWorld.getConfig(CONFIG_ARENA_SEASON_ID));
if(mapid == 530) // Outland
{
data << uint32(0x9bf) << uint32(0x0); // 7
@@ -8305,7 +8555,8 @@ uint8 Player::FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap
// (this will be replace mainhand weapon at auto equip instead unwonted "you don't known dual wielding" ...
if(CanDualWield())
slots[1] = EQUIPMENT_SLOT_OFFHAND;
- };break;
+ break;
+ };
case INVTYPE_SHIELD:
slots[0] = EQUIPMENT_SLOT_OFFHAND;
break;
@@ -8314,6 +8565,8 @@ uint8 Player::FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap
break;
case INVTYPE_2HWEAPON:
slots[0] = EQUIPMENT_SLOT_MAINHAND;
+ if (CanDualWield() && CanTitanGrip())
+ slots[1] = EQUIPMENT_SLOT_OFFHAND;
break;
case INVTYPE_TABARD:
slots[0] = EQUIPMENT_SLOT_TABARD;
@@ -8359,6 +8612,10 @@ uint8 Player::FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap
if (pClass == CLASS_WARLOCK)
slots[0] = EQUIPMENT_SLOT_RANGED;
break;
+ case ITEM_SUBCLASS_ARMOR_SIGIL:
+ if (pClass == CLASS_DEATH_KNIGHT)
+ slots[0] = EQUIPMENT_SLOT_RANGED;
+ break;
}
break;
}
@@ -8384,14 +8641,8 @@ uint8 Player::FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap
{
if ( slots[i] != NULL_SLOT && !GetItemByPos( INVENTORY_SLOT_BAG_0, slots[i] ) )
{
- // in case 2hand equipped weapon offhand slot empty but not free
- if(slots[i]==EQUIPMENT_SLOT_OFFHAND)
- {
- Item* mainItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND );
- if(!mainItem || mainItem->GetProto()->InventoryType != INVTYPE_2HWEAPON)
- return slots[i];
- }
- else
+ // in case 2hand equipped weapon (without titan grip) offhand slot empty but not free
+ if(slots[i]!=EQUIPMENT_SLOT_OFFHAND || !IsTwoHandUsed())
return slots[i];
}
}
@@ -8441,7 +8692,7 @@ uint8 Player::CanUnequipItems( uint32 item, uint32 count ) const
return EQUIP_ERR_OK;
}
}
- for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++)
+ for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++)
{
pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
if( pItem && pItem->GetEntry() == item )
@@ -8483,7 +8734,7 @@ uint32 Player::GetItemCount( uint32 item, bool inBankAlso, Item* skipItem ) cons
if( pItem && pItem != skipItem && pItem->GetEntry() == item )
count += pItem->GetCount();
}
- for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++)
+ for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++)
{
Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
if( pItem && pItem != skipItem && pItem->GetEntry() == item )
@@ -8543,7 +8794,7 @@ Item* Player::GetItemByGuid( uint64 guid ) const
if( pItem && pItem->GetGUID() == guid )
return pItem;
}
- for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++)
+ for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++)
{
Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
if( pItem && pItem->GetGUID() == guid )
@@ -8589,7 +8840,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 < KEYRING_SLOT_END ) )
+ if( bag == INVENTORY_SLOT_BAG_0 && ( slot < BANK_SLOT_BAG_END || slot >= KEYRING_SLOT_START && slot < QUESTBAG_SLOT_END ) )
return m_items[slot];
else if(bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END
|| bag >= BANK_SLOT_BAG_START && bag < BANK_SLOT_BAG_END )
@@ -8612,14 +8863,14 @@ Item* Player::GetWeaponForAttack(WeaponAttackType attackType, bool useable) cons
default: return NULL;
}
- Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, slot);
+ Item* item = GetUseableItemByPos(INVENTORY_SLOT_BAG_0, slot);
if (!item || item->GetProto()->Class != ITEM_CLASS_WEAPON)
return NULL;
if(!useable)
return item;
- if( item->IsBroken() || !IsUseEquipedWeapon(attackType==BASE_ATTACK) )
+ if( item->IsBroken() || IsInFeralForm())
return NULL;
return item;
@@ -8627,7 +8878,7 @@ Item* Player::GetWeaponForAttack(WeaponAttackType attackType, bool useable) cons
Item* Player::GetShield(bool useable) const
{
- Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
+ Item* item = GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
if (!item || item->GetProto()->Class != ITEM_CLASS_ARMOR)
return NULL;
@@ -8640,7 +8891,7 @@ Item* Player::GetShield(bool useable) const
return item;
}
-uint32 Player::GetAttackBySlot( uint8 slot )
+uint8 Player::GetAttackBySlot( uint8 slot )
{
switch(slot)
{
@@ -8667,7 +8918,7 @@ 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 < KEYRING_SLOT_END ) )
+ if( bag == INVENTORY_SLOT_BAG_0 && ( slot >= KEYRING_SLOT_START && slot < QUESTBAG_SLOT_END ) )
return true;
return false;
}
@@ -8788,7 +9039,7 @@ bool Player::HasItemCount( uint32 item, uint32 count, bool inBankAlso ) const
return true;
}
}
- for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++)
+ for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++)
{
Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
if( pItem && pItem->GetEntry() == item )
@@ -8886,12 +9137,12 @@ uint8 Player::_CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem,
}
// no maximum
- if(pProto->MaxCount == 0)
+ if(pProto->MaxCount <= 0)
return EQUIP_ERR_OK;
uint32 curcount = GetItemCount(pProto->ItemId,true,pItem);
- if( curcount + count > pProto->MaxCount )
+ if (curcount + count > uint32(pProto->MaxCount))
{
if(no_space_count)
*no_space_count = count +curcount - pProto->MaxCount;
@@ -8906,13 +9157,13 @@ bool Player::HasItemTotemCategory( uint32 TotemCategory ) const
Item *pItem;
for(uint8 i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; ++i)
{
- pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
+ pItem = GetUseableItemByPos( INVENTORY_SLOT_BAG_0, i );
if( pItem && IsTotemCategoryCompatiableWith(pItem->GetProto()->TotemCategory,TotemCategory ))
return true;
}
- for(uint8 i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; ++i)
+ for(uint8 i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; ++i)
{
- pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
+ pItem = GetUseableItemByPos( INVENTORY_SLOT_BAG_0, i );
if( pItem && IsTotemCategoryCompatiableWith(pItem->GetProto()->TotemCategory,TotemCategory ))
return true;
}
@@ -8922,7 +9173,7 @@ bool Player::HasItemTotemCategory( uint32 TotemCategory ) const
{
for(uint32 j = 0; j < pBag->GetBagSize(); ++j)
{
- pItem = GetItemByPos( i, j );
+ pItem = GetUseableItemByPos( i, j );
if( pItem && IsTotemCategoryCompatiableWith(pItem->GetProto()->TotemCategory,TotemCategory ))
return true;
}
@@ -8950,6 +9201,18 @@ uint8 Player::_CanStoreItem_InSpecificSlot( uint8 bag, uint8 slot, ItemPosCountV
if(slot >= KEYRING_SLOT_START && slot < KEYRING_SLOT_START+GetMaxKeyringSize() && !(pProto->BagFamily & BAG_FAMILY_MASK_KEYS))
return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
+ // vanitypet case (not use, vanity pets stored as spells)
+ if(slot >= VANITYPET_SLOT_START && slot < VANITYPET_SLOT_END)
+ return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
+
+ // currencytoken case (disabled until proper implement)
+ if(slot >= CURRENCYTOKEN_SLOT_START && slot < CURRENCYTOKEN_SLOT_END && !(false /*pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS*/))
+ return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
+
+ // guestbag case (disabled until proper implement)
+ if(slot >= QUESTBAG_SLOT_START && slot < QUESTBAG_SLOT_END && !(false /*pProto->BagFamily & BAG_FAMILY_MASK_QUEST_ITEMS*/))
+ 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;
@@ -8969,7 +9232,7 @@ uint8 Player::_CanStoreItem_InSpecificSlot( uint8 bag, uint8 slot, ItemPosCountV
}
// non empty stack with space
- need_space = pProto->Stackable;
+ need_space = pProto->GetMaxStackSize();
}
// non empty slot, check item type
else
@@ -8979,10 +9242,11 @@ uint8 Player::_CanStoreItem_InSpecificSlot( uint8 bag, uint8 slot, ItemPosCountV
return EQUIP_ERR_ITEM_CANT_STACK;
// check free space
- if(pItem2->GetCount() >= pProto->Stackable)
+ if(pItem2->GetCount() >= pProto->GetMaxStackSize())
return EQUIP_ERR_ITEM_CANT_STACK;
- need_space = pProto->Stackable - pItem2->GetCount();
+ // free stack space or infinity
+ need_space = pProto->GetMaxStackSize() - pItem2->GetCount();
}
if(need_space > count)
@@ -9036,9 +9300,9 @@ uint8 Player::_CanStoreItem_InBag( uint8 bag, ItemPosCountVec &dest, ItemPrototy
if( pItem2 )
{
- if(pItem2->GetEntry() == pProto->ItemId && pItem2->GetCount() < pProto->Stackable )
+ if(pItem2->GetEntry() == pProto->ItemId && pItem2->GetCount() < pProto->GetMaxStackSize())
{
- uint32 need_space = pProto->Stackable - pItem2->GetCount();
+ uint32 need_space = pProto->GetMaxStackSize() - pItem2->GetCount();
if(need_space > count)
need_space = count;
@@ -9055,7 +9319,7 @@ uint8 Player::_CanStoreItem_InBag( uint8 bag, ItemPosCountVec &dest, ItemPrototy
}
else
{
- uint32 need_space = pProto->Stackable;
+ uint32 need_space = pProto->GetMaxStackSize();
if(need_space > count)
need_space = count;
@@ -9093,9 +9357,9 @@ uint8 Player::_CanStoreItem_InInventorySlots( uint8 slot_begin, uint8 slot_end,
if( pItem2 )
{
- if(pItem2->GetEntry() == pProto->ItemId && pItem2->GetCount() < pProto->Stackable )
+ if(pItem2->GetEntry() == pProto->ItemId && pItem2->GetCount() < pProto->GetMaxStackSize())
{
- uint32 need_space = pProto->Stackable - pItem2->GetCount();
+ uint32 need_space = pProto->GetMaxStackSize() - pItem2->GetCount();
if(need_space > count)
need_space = count;
ItemPosCount newPosition = ItemPosCount((INVENTORY_SLOT_BAG_0 << 8) | j, need_space);
@@ -9111,7 +9375,7 @@ uint8 Player::_CanStoreItem_InInventorySlots( uint8 slot_begin, uint8 slot_end,
}
else
{
- uint32 need_space = pProto->Stackable;
+ uint32 need_space = pProto->GetMaxStackSize();
if(need_space > count)
need_space = count;
@@ -9190,11 +9454,11 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3
if( bag != NULL_BAG )
{
// search stack in bag for merge to
- if( pProto->Stackable > 1 )
+ if( pProto->Stackable != 1 )
{
if( bag == INVENTORY_SLOT_BAG_0 ) // inventory
{
- res = _CanStoreItem_InInventorySlots(KEYRING_SLOT_START,KEYRING_SLOT_END,dest,pProto,count,true,pItem,bag,slot);
+ res = _CanStoreItem_InInventorySlots(KEYRING_SLOT_START,QUESTBAG_SLOT_END,dest,pProto,count,true,pItem,bag,slot);
if(res!=EQUIP_ERR_OK)
{
if(no_space_count)
@@ -9282,6 +9546,53 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3
}
}
+ // Vanity pet case skipped as not used
+
+ /* until proper implementation
+ else if(pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS)
+ {
+ 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;
+ }
+ }
+ */
+ /* until proper implementation
+ else if(pProto->BagFamily & BAG_FAMILY_MASK_QUEST_ITEMS)
+ {
+ res = _CanStoreItem_InInventorySlots(QUESTBAG_SLOT_START,QUESTBAG_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)
{
@@ -9328,9 +9639,9 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3
// not specific bag or have space for partly store only in specific bag
// search stack for merge to
- if( pProto->Stackable > 1 )
+ if( pProto->Stackable != 1 )
{
- res = _CanStoreItem_InInventorySlots(KEYRING_SLOT_START,KEYRING_SLOT_END,dest,pProto,count,true,pItem,bag,slot);
+ res = _CanStoreItem_InInventorySlots(KEYRING_SLOT_START,QUESTBAG_SLOT_END,dest,pProto,count,true,pItem,bag,slot);
if(res!=EQUIP_ERR_OK)
{
if(no_space_count)
@@ -9429,6 +9740,53 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3
}
}
+ // Vanity pet case skipped as not used
+
+ /* until proper implementation
+ else if(false pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS)
+ {
+ 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;
+ }
+ }
+ */
+ /* until proper implementation
+ else if(false pProto->BagFamily & BAG_FAMILY_MASK_QUEST_ITEMS)
+ {
+ res = _CanStoreItem_InInventorySlots(QUESTBAG_SLOT_START,QUESTBAG_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(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++)
{
res = _CanStoreItem_InBag(i,dest,pProto,count,false,false,pItem,bag,slot);
@@ -9498,10 +9856,14 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
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];
+ int inv_quests[QUESTBAG_SLOT_END-QUESTBAG_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));
+ memset(inv_quests,0,sizeof(int)*(QUESTBAG_SLOT_END-QUESTBAG_SLOT_START));
for(int i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++)
{
@@ -9523,6 +9885,28 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
}
}
+ // Vanity pet case skipped as not used
+
+ for(int 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(int i = QUESTBAG_SLOT_START; i < QUESTBAG_SLOT_END; i++)
+ {
+ pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
+
+ if (pItem2 && !pItem2->IsInTrade())
+ {
+ inv_quests[i-QUESTBAG_SLOT_START] = pItem2->GetCount();
+ }
+ }
+
for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++)
{
if(Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i ))
@@ -9566,14 +9950,14 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
return res;
// search stack for merge to
- if( pProto->Stackable > 1 )
+ if( pProto->Stackable != 1 )
{
bool b_found = false;
for(int t = KEYRING_SLOT_START; t < KEYRING_SLOT_END; t++)
{
pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, t );
- if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_keys[t-KEYRING_SLOT_START] + pItem->GetCount() <= pProto->Stackable )
+ if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_keys[t-KEYRING_SLOT_START] + pItem->GetCount() <= pProto->GetMaxStackSize())
{
inv_keys[t-KEYRING_SLOT_START] += pItem->GetCount();
b_found = true;
@@ -9582,10 +9966,36 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
}
if (b_found) continue;
+ // Vanity pet case skipped as not used
+
+ for(int t = CURRENCYTOKEN_SLOT_START; t < CURRENCYTOKEN_SLOT_END; t++)
+ {
+ pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, t );
+ if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && 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 = QUESTBAG_SLOT_START; t < QUESTBAG_SLOT_END; t++)
+ {
+ pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, t );
+ if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_quests[t-QUESTBAG_SLOT_START] + pItem->GetCount() <= pProto->GetMaxStackSize())
+ {
+ inv_quests[t-QUESTBAG_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 );
- if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_slot_items[t-INVENTORY_SLOT_ITEM_START] + pItem->GetCount() <= pProto->Stackable )
+ if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_slot_items[t-INVENTORY_SLOT_ITEM_START] + pItem->GetCount() <= pProto->GetMaxStackSize())
{
inv_slot_items[t-INVENTORY_SLOT_ITEM_START] += pItem->GetCount();
b_found = true;
@@ -9602,7 +10012,7 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
for(uint32 j = 0; j < pBag->GetBagSize(); j++)
{
pItem2 = GetItemByPos( t, j );
- if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_bags[t-INVENTORY_SLOT_BAG_START][j] + pItem->GetCount() <= pProto->Stackable )
+ if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_bags[t-INVENTORY_SLOT_BAG_START][j] + pItem->GetCount() <= pProto->GetMaxStackSize())
{
inv_bags[t-INVENTORY_SLOT_BAG_START][j] += pItem->GetCount();
b_found = true;
@@ -9634,6 +10044,41 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
if (b_found) continue;
+ // Vanity pet case skipped as not used
+
+ /* until proper implementation
+ if(pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS)
+ {
+ 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;
+ */
+ /* until proper implementation
+ if(pProto->BagFamily & BAG_FAMILY_MASK_QUEST_ITEMS)
+ {
+ for(uint32 t = QUESTBAG_SLOT_START; t < QUESTBAG_SLOT_END; ++t)
+ {
+ if( inv_quests[t-QUESTBAG_SLOT_START] == 0 )
+ {
+ inv_quests[t-QUESTBAG_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++)
{
pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, t );
@@ -9819,33 +10264,42 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo
if(eslot == EQUIPMENT_SLOT_OFFHAND)
{
- if( type == INVTYPE_WEAPON || type == INVTYPE_WEAPONOFFHAND )
+ if (type == INVTYPE_WEAPON || type == INVTYPE_WEAPONOFFHAND)
{
if(!CanDualWield())
return EQUIP_ERR_CANT_DUAL_WIELD;
}
-
- Item *mainItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND );
- if(mainItem)
+ else if (type == INVTYPE_2HWEAPON)
{
- if(mainItem->GetProto()->InventoryType == INVTYPE_2HWEAPON)
- return EQUIP_ERR_CANT_EQUIP_WITH_TWOHANDED;
+ if(!CanDualWield() || !CanTitanGrip())
+ return EQUIP_ERR_CANT_DUAL_WIELD;
}
+
+ if(IsTwoHandUsed())
+ return EQUIP_ERR_CANT_EQUIP_WITH_TWOHANDED;
}
// equip two-hand weapon case (with possible unequip 2 items)
if( type == INVTYPE_2HWEAPON )
{
- if(eslot != EQUIPMENT_SLOT_MAINHAND)
+ if (eslot == EQUIPMENT_SLOT_OFFHAND)
+ {
+ if (!CanTitanGrip())
+ return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED;
+ }
+ else if (eslot != EQUIPMENT_SLOT_MAINHAND)
return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED;
- // offhand item must can be stored in inventory for offhand item and it also must be unequipped
- Item *offItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND );
- ItemPosCountVec off_dest;
- 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;
+ if (!CanTitanGrip())
+ {
+ // offhand item must can be stored in inventory for offhand item and it also must be unequipped
+ Item *offItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND );
+ ItemPosCountVec off_dest;
+ 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;
+ }
}
dest = ((INVENTORY_SLOT_BAG_0 << 8) | eslot);
return EQUIP_ERR_OK;
@@ -9917,29 +10371,17 @@ uint8 Player::CanBankItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *p
// in specific slot
if( bag != NULL_BAG && slot != NULL_SLOT )
{
- if( pProto->InventoryType == INVTYPE_BAG )
+ if( slot >= BANK_SLOT_BAG_START && slot < BANK_SLOT_BAG_END )
{
- Bag *pBag = (Bag*)pItem;
- if( pBag )
- {
- if( slot >= BANK_SLOT_BAG_START && slot < BANK_SLOT_BAG_END )
- {
- if( !HasBankBagSlot( slot ) )
- return EQUIP_ERR_MUST_PURCHASE_THAT_BAG_SLOT;
- if( uint8 cantuse = CanUseItem( pItem, not_loading ) != EQUIP_ERR_OK )
- return cantuse;
- }
- else
- {
- if( !pBag->IsEmpty() )
- return EQUIP_ERR_NONEMPTY_BAG_OVER_OTHER_BAG;
- }
- }
- }
- else
- {
- if( slot >= BANK_SLOT_BAG_START && slot < BANK_SLOT_BAG_END )
+ if (!pItem->IsBag())
return EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT;
+
+ Bag *pBag = (Bag*)pItem;
+ if( !HasBankBagSlot( slot ) )
+ return EQUIP_ERR_MUST_PURCHASE_THAT_BAG_SLOT;
+
+ if( uint8 cantuse = CanUseItem( pItem, not_loading ) != EQUIP_ERR_OK )
+ return cantuse;
}
res = _CanStoreItem_InSpecificSlot(bag,slot,dest,pProto,count,swap,pItem);
@@ -9963,7 +10405,7 @@ uint8 Player::CanBankItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *p
}
// search stack in bag for merge to
- if( pProto->Stackable > 1 )
+ if( pProto->Stackable != 1 )
{
if( bag == INVENTORY_SLOT_BAG_0 )
{
@@ -10015,7 +10457,7 @@ uint8 Player::CanBankItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *p
// not specific bag or have space for partly store only in specific bag
// search stack for merge to
- if( pProto->Stackable > 1 )
+ if( pProto->Stackable != 1 )
{
// in slots
res = _CanStoreItem_InInventorySlots(BANK_SLOT_ITEM_START,BANK_SLOT_ITEM_END,dest,pProto,count,true,pItem,bag,slot);
@@ -10765,7 +11207,7 @@ void Player::DestroyItemCount( uint32 item, uint32 count, bool update, bool uneq
}
}
}
- for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++)
+ for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++)
{
pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
if( pItem && pItem->GetEntry() == item )
@@ -10868,7 +11310,7 @@ void Player::DestroyZoneLimitedItem( bool update, uint32 new_zone )
if( pItem && pItem->IsLimitedToAnotherMapOrZone(GetMapId(),new_zone) )
DestroyItem( INVENTORY_SLOT_BAG_0, i, update);
}
- for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++)
+ for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++)
{
Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
if( pItem && pItem->IsLimitedToAnotherMapOrZone(GetMapId(),new_zone) )
@@ -11096,6 +11538,8 @@ void Player::SwapItem( uint16 src, uint16 dst )
return;
}
+ // SRC checks
+
if(pSrcItem->m_lootGenerated) // prevent swap looting item
{
//best error message found for attempting to swap while looting
@@ -11106,8 +11550,8 @@ void Player::SwapItem( uint16 src, uint16 dst )
// check unequip potability for equipped items and bank bags
if(IsEquipmentPos ( src ) || IsBagPos ( src ))
{
- // bags can be swapped with empty bag slots
- uint8 msg = CanUnequipItem( src, !IsBagPos ( src ) || IsBagPos ( dst ));
+ // bags can be swapped with empty bag slots, or with empty bag (items move possibility checked later)
+ uint8 msg = CanUnequipItem( src, !IsBagPos ( src ) || IsBagPos ( dst ) || pDstItem && pDstItem->IsBag() && ((Bag*)pDstItem)->IsEmpty());
if(msg != EQUIP_ERR_OK)
{
SendEquipError( msg, pSrcItem, pDstItem );
@@ -11122,6 +11566,34 @@ void Player::SwapItem( uint16 src, uint16 dst )
return;
}
+ // DST checks
+
+ if (pDstItem)
+ {
+ 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 );
+ return;
+ }
+
+ // check unequip potability for equipped items and bank bags
+ if(IsEquipmentPos ( dst ) || IsBagPos ( dst ))
+ {
+ // bags can be swapped with empty bag slots, or with empty bag (items move possibility checked later)
+ uint8 msg = CanUnequipItem( dst, !IsBagPos ( dst ) || IsBagPos ( src ) || pSrcItem->IsBag() && ((Bag*)pSrcItem)->IsEmpty());
+ if(msg != EQUIP_ERR_OK)
+ {
+ SendEquipError( msg, pSrcItem, pDstItem );
+ return;
+ }
+ }
+ }
+
+ // NOW this is or item move (swap with empty), or swap with another item (including bags in bag possitions)
+ // or swap empty bag with another empty or not empty bag (with items exchange)
+
+ // Move case
if( !pDstItem )
{
if( IsInventoryPos( dst ) )
@@ -11164,140 +11636,187 @@ void Player::SwapItem( uint16 src, uint16 dst )
EquipItem( dest, pSrcItem, true);
AutoUnequipOffhandIfNeed();
}
+
+ return;
}
- else // if (!pDstItem)
+
+ // attempt merge to / fill target item
+ if(!pSrcItem->IsBag() && !pDstItem->IsBag())
{
- 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 );
+ uint8 msg;
+ ItemPosCountVec sDest;
+ uint16 eDest;
+ if( IsInventoryPos( dst ) )
+ msg = CanStoreItem( dstbag, dstslot, sDest, pSrcItem, false );
+ else if( IsBankPos ( dst ) )
+ msg = CanBankItem( dstbag, dstslot, sDest, pSrcItem, false );
+ else if( IsEquipmentPos ( dst ) )
+ msg = CanEquipItem( dstslot, eDest, pSrcItem, false );
+ else
return;
- }
- // check unequip potability for equipped items and bank bags
- if(IsEquipmentPos ( dst ) || IsBagPos ( dst ))
+ // can be merge/fill
+ if(msg == EQUIP_ERR_OK)
{
- // bags can be swapped with empty bag slots
- uint8 msg = CanUnequipItem( dst, !IsBagPos ( dst ) || IsBagPos ( src ) );
- if(msg != EQUIP_ERR_OK)
+ if( pSrcItem->GetCount() + pDstItem->GetCount() <= pSrcItem->GetProto()->GetMaxStackSize())
{
- SendEquipError( msg, pSrcItem, pDstItem );
- return;
- }
- }
-
- // attempt merge to / fill target item
- {
- uint8 msg;
- ItemPosCountVec sDest;
- uint16 eDest;
- if( IsInventoryPos( dst ) )
- msg = CanStoreItem( dstbag, dstslot, sDest, pSrcItem, false );
- else if( IsBankPos ( dst ) )
- msg = CanBankItem( dstbag, dstslot, sDest, pSrcItem, false );
- else if( IsEquipmentPos ( dst ) )
- msg = CanEquipItem( dstslot, eDest, pSrcItem, false );
- else
- return;
+ RemoveItem(srcbag, srcslot, true);
- // can be merge/fill
- if(msg == EQUIP_ERR_OK)
- {
- if( pSrcItem->GetCount() + pDstItem->GetCount() <= pSrcItem->GetProto()->Stackable )
+ if( IsInventoryPos( dst ) )
+ StoreItem( sDest, pSrcItem, true);
+ else if( IsBankPos ( dst ) )
+ BankItem( sDest, pSrcItem, true);
+ else if( IsEquipmentPos ( dst ) )
{
- RemoveItem(srcbag, srcslot, true);
-
- if( IsInventoryPos( dst ) )
- StoreItem( sDest, pSrcItem, true);
- else if( IsBankPos ( dst ) )
- BankItem( sDest, pSrcItem, true);
- else if( IsEquipmentPos ( dst ) )
- {
- EquipItem( eDest, pSrcItem, true);
- AutoUnequipOffhandIfNeed();
- }
+ EquipItem( eDest, pSrcItem, true);
+ AutoUnequipOffhandIfNeed();
}
- else
+ }
+ else
+ {
+ pSrcItem->SetCount( pSrcItem->GetCount() + pDstItem->GetCount() - pSrcItem->GetProto()->GetMaxStackSize());
+ pDstItem->SetCount( pSrcItem->GetProto()->GetMaxStackSize());
+ pSrcItem->SetState(ITEM_CHANGED, this);
+ pDstItem->SetState(ITEM_CHANGED, this);
+ if( IsInWorld() )
{
- pSrcItem->SetCount( pSrcItem->GetCount() + pDstItem->GetCount() - pSrcItem->GetProto()->Stackable );
- pDstItem->SetCount( pSrcItem->GetProto()->Stackable );
- pSrcItem->SetState(ITEM_CHANGED, this);
- pDstItem->SetState(ITEM_CHANGED, this);
- if( IsInWorld() )
- {
- pSrcItem->SendUpdateToPlayer( this );
- pDstItem->SendUpdateToPlayer( this );
- }
+ pSrcItem->SendUpdateToPlayer( this );
+ pDstItem->SendUpdateToPlayer( this );
}
- return;
}
+ return;
}
+ }
- // impossible merge/fill, do real swap
- uint8 msg;
+ // impossible merge/fill, do real swap
+ uint8 msg;
- // check src->dest move possibility
- ItemPosCountVec sDest;
- uint16 eDest;
- if( IsInventoryPos( dst ) )
- msg = CanStoreItem( dstbag, dstslot, sDest, pSrcItem, true );
- else if( IsBankPos( dst ) )
- msg = CanBankItem( dstbag, dstslot, sDest, pSrcItem, true );
- else if( IsEquipmentPos( dst ) )
- {
- msg = CanEquipItem( dstslot, eDest, pSrcItem, true );
- if( msg == EQUIP_ERR_OK )
- msg = CanUnequipItem( eDest, true );
- }
+ // check src->dest move possibility
+ ItemPosCountVec sDest;
+ uint16 eDest;
+ if( IsInventoryPos( dst ) )
+ msg = CanStoreItem( dstbag, dstslot, sDest, pSrcItem, true );
+ else if( IsBankPos( dst ) )
+ msg = CanBankItem( dstbag, dstslot, sDest, pSrcItem, true );
+ else if( IsEquipmentPos( dst ) )
+ {
+ msg = CanEquipItem( dstslot, eDest, pSrcItem, true );
+ if( msg == EQUIP_ERR_OK )
+ msg = CanUnequipItem( eDest, true );
+ }
- if( msg != EQUIP_ERR_OK )
+ if( msg != EQUIP_ERR_OK )
+ {
+ SendEquipError( msg, pSrcItem, pDstItem );
+ return;
+ }
+
+ // check dest->src move possibility
+ ItemPosCountVec sDest2;
+ uint16 eDest2;
+ if( IsInventoryPos( src ) )
+ msg = CanStoreItem( srcbag, srcslot, sDest2, pDstItem, true );
+ else if( IsBankPos( src ) )
+ msg = CanBankItem( srcbag, srcslot, sDest2, pDstItem, true );
+ else if( IsEquipmentPos( src ) )
+ {
+ msg = CanEquipItem( srcslot, eDest2, pDstItem, true);
+ if( msg == EQUIP_ERR_OK )
+ msg = CanUnequipItem( eDest2, true);
+ }
+
+ if( msg != EQUIP_ERR_OK )
+ {
+ SendEquipError( msg, pDstItem, pSrcItem );
+ return;
+ }
+
+ // Check bag swap with item exchange (one from empty in not bag possition (equipped (not possible in fact) or store)
+ if(pSrcItem->IsBag() && pDstItem->IsBag())
+ {
+ Bag* emptyBag = NULL;
+ Bag* fullBag = NULL;
+ if(((Bag*)pSrcItem)->IsEmpty() && !IsBagPos(src))
{
- SendEquipError( msg, pSrcItem, pDstItem );
- return;
+ emptyBag = (Bag*)pSrcItem;
+ fullBag = (Bag*)pDstItem;
}
-
- // check dest->src move possibility
- ItemPosCountVec sDest2;
- uint16 eDest2;
- if( IsInventoryPos( src ) )
- msg = CanStoreItem( srcbag, srcslot, sDest2, pDstItem, true );
- else if( IsBankPos( src ) )
- msg = CanBankItem( srcbag, srcslot, sDest2, pDstItem, true );
- else if( IsEquipmentPos( src ) )
+ else if(((Bag*)pDstItem)->IsEmpty() && !IsBagPos(dst))
{
- msg = CanEquipItem( srcslot, eDest2, pDstItem, true);
- if( msg == EQUIP_ERR_OK )
- msg = CanUnequipItem( eDest2, true);
+ emptyBag = (Bag*)pDstItem;
+ fullBag = (Bag*)pSrcItem;
}
- if( msg != EQUIP_ERR_OK )
+ // bag swap (with items exchange) case
+ if(emptyBag && fullBag)
{
- SendEquipError( msg, pDstItem, pSrcItem );
- return;
- }
+ ItemPrototype const* emotyProto = emptyBag->GetProto();
- // now do moves, remove...
- RemoveItem(dstbag, dstslot, false);
- RemoveItem(srcbag, srcslot, false);
+ uint32 count = 0;
- // add to dest
- if( IsInventoryPos( dst ) )
- StoreItem(sDest, pSrcItem, true);
- else if( IsBankPos( dst ) )
- BankItem(sDest, pSrcItem, true);
- else if( IsEquipmentPos( dst ) )
- EquipItem(eDest, pSrcItem, true);
-
- // add to src
- if( IsInventoryPos( src ) )
- StoreItem(sDest2, pDstItem, true);
- else if( IsBankPos( src ) )
- BankItem(sDest2, pDstItem, true);
- else if( IsEquipmentPos( src ) )
- EquipItem(eDest2, pDstItem, true);
+ for(int i=0; i < fullBag->GetBagSize(); ++i)
+ {
+ Item *bagItem = fullBag->GetItemByPos(i);
+ if (!bagItem)
+ continue;
- AutoUnequipOffhandIfNeed();
+ ItemPrototype const* bagItemProto = bagItem->GetProto();
+ if (!bagItemProto || !ItemCanGoIntoBag(bagItemProto, emotyProto))
+ {
+ // one from items not go to empry target bag
+ SendEquipError( EQUIP_ERR_NONEMPTY_BAG_OVER_OTHER_BAG, pSrcItem, pDstItem );
+ return;
+ }
+
+ ++count;
+ }
+
+
+ if (count > emptyBag->GetBagSize())
+ {
+ // too small targeted bag
+ SendEquipError( EQUIP_ERR_ITEMS_CANT_BE_SWAPPED, pSrcItem, pDstItem );
+ return;
+ }
+
+ // Items swap
+ count = 0; // will pos in new bag
+ for(int i=0; i< fullBag->GetBagSize(); ++i)
+ {
+ Item *bagItem = fullBag->GetItemByPos(i);
+ if (!bagItem)
+ continue;
+
+ fullBag->RemoveItem(i, true);
+ emptyBag->StoreItem(count, bagItem, true);
+ bagItem->SetState(ITEM_CHANGED, this);
+
+ ++count;
+ }
+ }
}
+
+ // now do moves, remove...
+ RemoveItem(dstbag, dstslot, false);
+ RemoveItem(srcbag, srcslot, false);
+
+ // add to dest
+ if( IsInventoryPos( dst ) )
+ StoreItem(sDest, pSrcItem, true);
+ else if( IsBankPos( dst ) )
+ BankItem(sDest, pSrcItem, true);
+ else if( IsEquipmentPos( dst ) )
+ EquipItem(eDest, pSrcItem, true);
+
+ // add to src
+ if( IsInventoryPos( src ) )
+ StoreItem(sDest2, pDstItem, true);
+ else if( IsBankPos( src ) )
+ BankItem(sDest2, pDstItem, true);
+ else if( IsEquipmentPos( src ) )
+ EquipItem(eDest2, pDstItem, true);
+
+ AutoUnequipOffhandIfNeed();
}
void Player::AddItemToBuyBackSlot( Item *pItem )
@@ -11865,6 +12384,40 @@ void Player::ApplyEnchantment(Item *item,EnchantmentSlot slot,bool apply, bool a
((Player*)this)->ApplyRatingMod(CR_EXPERTISE, enchant_amount, apply);
sLog.outDebug("+ %u EXPERTISE", enchant_amount);
break;
+ case ITEM_MOD_ATTACK_POWER:
+ HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(enchant_amount), apply);
+ HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(enchant_amount), apply);
+ sLog.outDebug("+ %u ATTACK_POWER", enchant_amount);
+ break;
+ case ITEM_MOD_RANGED_ATTACK_POWER:
+ HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(enchant_amount), apply);
+ sLog.outDebug("+ %u RANGED_ATTACK_POWER", enchant_amount);
+ break;
+ case ITEM_MOD_FERAL_ATTACK_POWER:
+ ((Player*)this)->ApplyFeralAPBonus(enchant_amount, apply);
+ sLog.outDebug("+ %u FERAL_ATTACK_POWER", enchant_amount);
+ break;
+ case ITEM_MOD_SPELL_HEALING_DONE:
+ ((Player*)this)->ApplySpellHealingBonus(enchant_amount, apply);
+ sLog.outDebug("+ %u SPELL_HEALING_DONE", enchant_amount);
+ break;
+ case ITEM_MOD_SPELL_DAMAGE_DONE:
+ ((Player*)this)->ApplySpellDamageBonus(enchant_amount, apply);
+ sLog.outDebug("+ %u SPELL_DAMAGE_DONE", enchant_amount);
+ break;
+ case ITEM_MOD_MANA_REGENERATION:
+ ((Player*)this)->ApplyManaRegenBonus(enchant_amount, apply);
+ sLog.outDebug("+ %u MANA_REGENERATION", enchant_amount);
+ break;
+ case ITEM_MOD_ARMOR_PENETRATION_RATING:
+ ((Player*)this)->ApplyRatingMod(CR_ARMOR_PENETRATION, enchant_amount, apply);
+ sLog.outDebug("+ %u ARMOR PENETRATION", enchant_amount);
+ break;
+ case ITEM_MOD_SPELL_POWER:
+ ((Player*)this)->ApplySpellHealingBonus(enchant_amount, apply);
+ ((Player*)this)->ApplySpellDamageBonus(enchant_amount, apply);
+ sLog.outDebug("+ %u SPELL_POWER", enchant_amount);
+ break;
default:
break;
}
@@ -11888,8 +12441,14 @@ void Player::ApplyEnchantment(Item *item,EnchantmentSlot slot,bool apply, bool a
}
break;
}
+ case ITEM_ENCHANTMENT_TYPE_USE_SPELL:
+ // processed in Player::CastItemUseSpell
+ break;
+ case ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET:
+ // nothing do..
+ break;
default:
- sLog.outError("Unknown item enchantment display type: %d",enchant_display_type);
+ sLog.outError("Unknown item enchantment (id = %d) display type: %d", enchant_id, enchant_display_type);
break;
} /*switch(enchant_display_type)*/
} /*for*/
@@ -12363,8 +12922,6 @@ void Player::AddQuest( Quest const *pQuest, Object *questGiver )
// if not exist then created with set uState==NEW and rewarded=false
QuestStatusData& questStatusData = mQuestStatus[quest_id];
- if (questStatusData.uState != QUEST_NEW)
- questStatusData.uState = QUEST_CHANGED;
// check for repeatable quests status reset
questStatusData.m_status = QUEST_STATUS_INCOMPLETE;
@@ -12372,18 +12929,18 @@ void Player::AddQuest( Quest const *pQuest, Object *questGiver )
if ( pQuest->HasFlag( QUEST_TRINITY_FLAGS_DELIVER ) )
{
- for(int i = 0; i < QUEST_OBJECTIVES_COUNT; i++)
+ for(int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
questStatusData.m_itemcount[i] = 0;
}
if ( pQuest->HasFlag(QUEST_TRINITY_FLAGS_KILL_OR_CAST | QUEST_TRINITY_FLAGS_SPEAKTO) )
{
- for(int i = 0; i < QUEST_OBJECTIVES_COUNT; i++)
+ for(int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
questStatusData.m_creatureOrGOcount[i] = 0;
}
GiveQuestSourceItem( pQuest );
- AdjustQuestReqItemCount( pQuest );
+ AdjustQuestReqItemCount( pQuest, questStatusData );
if( pQuest->GetRepObjectiveFaction() )
SetFactionVisibleForFactionId(pQuest->GetRepObjectiveFaction());
@@ -12406,6 +12963,9 @@ void Player::AddQuest( Quest const *pQuest, Object *questGiver )
SetQuestSlot(log_slot, quest_id, qtime);
+ if (questStatusData.uState != QUEST_NEW)
+ questStatusData.uState = QUEST_CHANGED;
+
//starting initial quest script
if(questGiver && pQuest->GetQuestStartScript()!=0)
sWorld.ScriptsStart(sQuestStartScripts, pQuest->GetQuestStartScript(), questGiver, this);
@@ -12523,6 +13083,12 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver
SetTitle(titleEntry);
}
+ if(pQuest->GetBonusTalents())
+ {
+ m_questRewardTalentCount+=pQuest->GetBonusTalents();
+ InitTalentForLevel();
+ }
+
// Send reward mail
if(pQuest->GetRewMailTemplateId())
{
@@ -12554,12 +13120,13 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver
Loot questMailLoot;
- questMailLoot.FillLoot(pQuest->GetQuestId(), LootTemplates_QuestMail, this);
+ questMailLoot.FillLoot(pQuest->GetQuestId(), LootTemplates_QuestMail, this,true);
// fill mail
MailItemsInfo mi; // item list preparing
- for(size_t i = 0; mi.size() < MAX_MAIL_ITEMS && i < questMailLoot.items.size(); ++i)
+ uint32 max_slot = questMailLoot.GetMaxSlotInLootFor(this);
+ for(uint32 i = 0; mi.size() < MAX_MAIL_ITEMS && i < max_slot; ++i)
{
if(LootItem* lootitem = questMailLoot.LootItemInSlot(i,this))
{
@@ -12571,23 +13138,14 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver
}
}
- for(size_t i = 0; mi.size() < MAX_MAIL_ITEMS && i < questMailLoot.quest_items.size(); ++i)
- {
- if(LootItem* lootitem = questMailLoot.LootItemInSlot(i+questMailLoot.items.size(),this))
- {
- if(Item* item = Item::CreateItem(lootitem->itemid,lootitem->count,this))
- {
- item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
- mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item);
- }
- }
- }
-
WorldSession::SendMailTo(this, mailType, MAIL_STATIONERY_NORMAL, senderGuidOrEntry, GetGUIDLow(), "", 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE,pQuest->GetRewMailDelaySecs(),pQuest->GetRewMailTemplateId());
}
if(pQuest->IsDaily())
+ {
SetDailyQuestStatus(quest_id);
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST, 1);
+ }
if ( !pQuest->IsRepeatable() )
SetQuestStatus(quest_id, QUEST_STATUS_COMPLETE);
@@ -12600,6 +13158,8 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver
SendQuestReward( pQuest, XP, questGiver );
if (q_status.uState != QUEST_NEW) q_status.uState = QUEST_CHANGED;
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT);
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST);
}
void Player::FailQuest( uint32 quest_id )
@@ -12624,8 +13184,9 @@ void Player::FailTimedQuest( uint32 quest_id )
{
QuestStatusData& q_status = mQuestStatus[quest_id];
- if (q_status.uState != QUEST_NEW) q_status.uState = QUEST_CHANGED;
q_status.m_timer = 0;
+ if (q_status.uState != QUEST_NEW)
+ q_status.uState = QUEST_CHANGED;
IncompleteQuest( quest_id );
@@ -13111,18 +13672,18 @@ uint32 Player::GetReqKillOrCastCurrentCount(uint32 quest_id, int32 entry)
if( !qInfo )
return 0;
- for (int j = 0; j < QUEST_OBJECTIVES_COUNT; j++)
+ for (int j = 0; j < QUEST_OBJECTIVES_COUNT; ++j)
if ( qInfo->ReqCreatureOrGOId[j] == entry )
return mQuestStatus[quest_id].m_creatureOrGOcount[j];
return 0;
}
-void Player::AdjustQuestReqItemCount( Quest const* pQuest )
+void Player::AdjustQuestReqItemCount( Quest const* pQuest, QuestStatusData& questStatusData )
{
if ( pQuest->HasFlag( QUEST_TRINITY_FLAGS_DELIVER ) )
{
- for(int i = 0; i < QUEST_OBJECTIVES_COUNT; i++)
+ for(int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
{
uint32 reqitemcount = pQuest->ReqItemCount[i];
if( reqitemcount != 0 )
@@ -13130,9 +13691,8 @@ void Player::AdjustQuestReqItemCount( Quest const* pQuest )
uint32 quest_id = pQuest->GetQuestId();
uint32 curitemcount = GetItemCount(pQuest->ReqItemId[i],true);
- QuestStatusData& q_status = mQuestStatus[quest_id];
- q_status.m_itemcount[i] = std::min(curitemcount, reqitemcount);
- if (q_status.uState != QUEST_NEW) q_status.uState = QUEST_CHANGED;
+ questStatusData.m_itemcount[i] = std::min(curitemcount, reqitemcount);
+ if (questStatusData.uState != QUEST_NEW) questStatusData.uState = QUEST_CHANGED;
}
}
}
@@ -13225,6 +13785,7 @@ void Player::ItemAddedQuestCheck( uint32 entry, uint32 count )
}
}
UpdateForQuestsGO();
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM, entry);
}
void Player::ItemRemovedQuestCheck( uint32 entry, uint32 count )
@@ -13271,6 +13832,7 @@ void Player::ItemRemovedQuestCheck( uint32 entry, uint32 count )
void Player::KilledMonster( uint32 entry, uint64 guid )
{
uint32 addkillcount = 1;
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, entry, addkillcount);
for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ )
{
uint32 questid = GetQuestSlotQuestId(i);
@@ -13549,13 +14111,12 @@ void Player::SendQuestReward( Quest const *pQuest, uint32 XP, Object * questGive
uint32 questid = pQuest->GetQuestId();
sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_QUEST_COMPLETE quest = %u", questid );
gameeventmgr.HandleQuestComplete(questid);
- WorldPacket data( SMSG_QUESTGIVER_QUEST_COMPLETE, (4+4+4+4+4+4+pQuest->GetRewItemsCount()*8) );
- data << questid;
- data << uint32(0x03);
+ WorldPacket data( SMSG_QUESTGIVER_QUEST_COMPLETE, (4+4+4+4+4) );
+ data << uint32(questid);
if ( getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) )
{
- data << XP;
+ data << uint32(XP);
data << uint32(pQuest->GetRewOrReqMoney());
}
else
@@ -13563,16 +14124,9 @@ void Player::SendQuestReward( Quest const *pQuest, uint32 XP, Object * questGive
data << uint32(0);
data << uint32(pQuest->GetRewOrReqMoney() + int32(pQuest->GetRewMoneyMaxLevel() * sWorld.getRate(RATE_DROP_MONEY)));
}
- data << uint32(0); // new 2.3.0, HonorPoints?
- data << uint32( pQuest->GetRewItemsCount() ); // max is 5
- for (uint32 i = 0; i < pQuest->GetRewItemsCount(); ++i)
- {
- if ( pQuest->RewItemId[i] > 0 )
- data << pQuest->RewItemId[i] << pQuest->RewItemCount[i];
- else
- data << uint32(0) << uint32(0);
- }
+ data << uint32(10*Trinity::Honor::hk_honor_at_level(getLevel(), pQuest->GetRewHonorableKills()));
+ data << uint32(pQuest->GetBonusTalents()); // bonus talents
GetSession()->SendPacket( &data );
if (pQuest->GetQuestCompleteScript() != 0)
@@ -13583,8 +14137,9 @@ void Player::SendQuestFailed( uint32 quest_id )
{
if( quest_id )
{
- WorldPacket data( SMSG_QUESTGIVER_QUEST_FAILED, 4 );
+ WorldPacket data( SMSG_QUESTGIVER_QUEST_FAILED, 4+4 );
data << quest_id;
+ data << uint32(0); // failed reason (4 for inventory is full)
GetSession()->SendPacket( &data );
sLog.outDebug("WORLD: Sent SMSG_QUESTGIVER_QUEST_FAILED");
}
@@ -13623,10 +14178,10 @@ void Player::SendPushToPartyResponse( Player *pPlayer, uint32 msg )
void Player::SendQuestUpdateAddItem( Quest const* pQuest, uint32 item_idx, uint32 count )
{
- WorldPacket data( SMSG_QUESTUPDATE_ADD_ITEM, (4+4) );
+ WorldPacket data( SMSG_QUESTUPDATE_ADD_ITEM, 0 );
sLog.outDebug( "WORLD: Sent SMSG_QUESTUPDATE_ADD_ITEM" );
- data << pQuest->ReqItemId[item_idx];
- data << count;
+ //data << pQuest->ReqItemId[item_idx];
+ //data << count;
GetSession()->SendPacket( &data );
}
@@ -13672,7 +14227,7 @@ bool Player::MinimalLoadFromDB( QueryResult *result, uint32 guid )
if(!LoadValues( fields[1].GetString()))
{
- sLog.outError("ERROR: Player #%d have broken data in `data` field. Can't be loaded.",GUID_LOPART(guid));
+ sLog.outError("ERROR: Player #%d have broken data in `data` field. Can't be loaded for character list.",GUID_LOPART(guid));
if(delete_result) delete result;
return false;
}
@@ -13742,7 +14297,7 @@ void Player::_LoadArenaTeamInfo(QueryResult *result)
ArenaTeam* aTeam = objmgr.GetArenaTeamById(arenateamid);
if(!aTeam)
{
- sLog.outError("FATAL: couldn't load arenateam %u", arenateamid);
+ sLog.outError("Player::_LoadArenaTeamInfo: couldn't load arenateam %u, week %u, season %u, rating %u", arenateamid, played_week, played_season, personal_rating);
continue;
}
uint8 arenaSlot = aTeam->GetSlot();
@@ -13860,8 +14415,8 @@ float Player::GetFloatValueFromDB(uint16 index, uint64 guid)
bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
{
- //// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 [28] [29] 30 31 32 33
- //QueryResult *result = CharacterDatabase.PQuery("SELECT guid, account, data, name, race, class, 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, dungeon_difficulty, arena_pending_points FROM characters WHERE guid = '%u'", guid);
+ //// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 [28] [29] 30 31 32 33 34 35 36 37 38 39 40
+ //QueryResult *result = CharacterDatabase.PQuery("SELECT guid, account, data, name, race, class, 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, dungeon_difficulty, arena_pending_points,bgid,bgteam,bgmap,bgx,bgy,bgz,bgo FROM characters WHERE guid = '%u'", guid);
QueryResult *result = holder->GetResult(PLAYER_LOGIN_QUERY_LOADFROM);
if(!result)
@@ -13930,22 +14485,19 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
//Other way is to saves m_team into characters table.
setFactionForRace(m_race);
SetCharm(0);
+ SetMover(this);
m_class = fields[5].GetUInt8();
- PlayerInfo const *info = objmgr.GetPlayerInfo(m_race, m_class);
- if(!info)
- {
- sLog.outError("Player have incorrect race/class pair. Can't be loaded.");
- delete result;
+ // load home bind and check in same time class/race pair, it used later for restore broken positions
+ if(!_LoadHomeBind(holder->GetResult(PLAYER_LOGIN_QUERY_LOADHOMEBIND)))
return false;
- }
InitPrimaryProffesions(); // to max set before any spell loaded
+ // init saved position, and fix it later if problematic
uint32 transGUID = fields[24].GetUInt32();
Relocate(fields[6].GetFloat(),fields[7].GetFloat(),fields[8].GetFloat(),fields[10].GetFloat());
- SetFallInformation(0, fields[8].GetFloat());
SetMapId(fields[9].GetUInt32());
SetDifficulty(fields[32].GetUInt32()); // may be changed in _LoadGroup
@@ -13980,9 +14532,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
if(!IsPositionValid())
{
sLog.outError("ERROR: Player (guidlow %d) have invalid coordinates (X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.",guid,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
-
- SetMapId(info->mapId);
- Relocate(info->positionX,info->positionY,info->positionZ,0.0f);
+ RelocateToHomebind();
transGUID = 0;
@@ -13992,10 +14542,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
m_movementInfo.t_o = 0.0f;
}
- if(!_LoadHomeBind(holder->GetResult(PLAYER_LOGIN_QUERY_LOADHOMEBIND)))
- return false;
-
- // load the player's map here if it's not already loaded
+ /*// load the player's map here if it's not already loaded
Map *map = GetMap();
if (!map)
{
@@ -14029,12 +14576,55 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
assert(false);
}
}
+ }*/
+
+ uint32 bgid = fields[34].GetUInt32();
+ uint32 bgteam = fields[35].GetUInt32();
+
+ if(bgid) //saved in BattleGround
+ {
+ SetBattleGroundEntryPoint(fields[36].GetUInt32(),fields[37].GetFloat(),fields[38].GetFloat(),fields[39].GetFloat(),fields[40].GetFloat());
+
+ // check entry point and fix to homebind if need
+ MapEntry const* mapEntry = sMapStore.LookupEntry(m_bgEntryPoint.mapid);
+ if(!mapEntry || mapEntry->Instanceable() || !MapManager::IsValidMapCoord(m_bgEntryPoint))
+ SetBattleGroundEntryPoint(m_homebindMapId,m_homebindX,m_homebindY,m_homebindZ,0.0f);
+
+ BattleGround *currentBg = sBattleGroundMgr.GetBattleGround(bgid);
+
+ if(currentBg && currentBg->IsPlayerInBattleGround(GetGUID()))
+ {
+ uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(currentBg->GetTypeID(), currentBg->GetArenaType());
+ uint32 queueSlot = AddBattleGroundQueueId(bgQueueTypeId);
+
+ SetBattleGroundId(currentBg->GetInstanceID());
+ SetBGTeam(bgteam);
+
+ SetInviteForBattleGroundQueueType(bgQueueTypeId,currentBg->GetInstanceID());
+ }
+ else
+ {
+ Relocate(GetBattleGroundEntryPoint());
+ //RemoveArenaAuras(true);
+ }
}
- // since the player may not be bound to the map yet, make sure subsequent
- // getmap calls won't create new maps
- SetInstanceId(map->GetInstanceId());
+ else
+ {
+ MapEntry const* mapEntry = sMapStore.LookupEntry(GetMapId());
+ // if server restart after player save in BG or area
+ // player can have current coordinates in to BG/Arean map, fix this
+ if(!mapEntry || mapEntry->IsBattleGroundOrArena())
+ {
+ // return to BG master
+ SetMapId(fields[36].GetUInt32());
+ Relocate(fields[37].GetFloat(),fields[38].GetFloat(),fields[39].GetFloat(),fields[40].GetFloat());
- SaveRecallPosition();
+ // check entry point and fix to homebind if need
+ mapEntry = sMapStore.LookupEntry(GetMapId());
+ if(!mapEntry || mapEntry->IsBattleGroundOrArena() || !IsPositionValid())
+ RelocateToHomebind();
+ }
+ }
if (transGUID != 0)
{
@@ -14053,8 +14643,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
guid,GetPositionX()+m_movementInfo.t_x,GetPositionY()+m_movementInfo.t_y,
GetPositionZ()+m_movementInfo.t_z,GetOrientation()+m_movementInfo.t_o);
- SetMapId(info->mapId);
- Relocate(info->positionX,info->positionY,info->positionZ,0.0f);
+ RelocateToHomebind();
m_movementInfo.t_x = 0.0f;
m_movementInfo.t_y = 0.0f;
@@ -14083,8 +14672,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
sLog.outError("ERROR: Player (guidlow %d) have invalid transport guid (%u). Teleport to default race/class locations.",
guid,transGUID);
- SetMapId(info->mapId);
- Relocate(info->positionX,info->positionY,info->positionZ,0.0f);
+ RelocateToHomebind();
m_movementInfo.t_x = 0.0f;
m_movementInfo.t_y = 0.0f;
@@ -14095,6 +14683,26 @@ 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 = GetMap();
+
+ // since the player may not be bound to the map yet, make sure subsequent
+ // getmap calls won't create new maps
+ SetInstanceId(map->GetInstanceId());
+
+ // if the player is in an instance and it has been reset in the meantime teleport him to the entrance
+ if(GetInstanceId() && !sInstanceSaveManager.GetInstanceSave(GetInstanceId()))
+ {
+ AreaTrigger const* at = objmgr.GetMapEntranceTrigger(GetMapId());
+ if(at)
+ Relocate(at->target_X, at->target_Y, at->target_Z, at->target_Orientation);
+ else
+ sLog.outError("Player %s(GUID: %u) logged in to a reset instance (map: %u) and there is no aretrigger leading to this map. Thus he can't be ported back to the entrance. This _might_ be an exploit attempt.", GetName(), GetGUIDLow(), GetMapId());
+ }
+
+ SaveRecallPosition();
+
time_t now = time(NULL);
time_t logoutTime = time_t(fields[16].GetUInt64());
@@ -14144,10 +14752,10 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
uint32 extraflags = fields[25].GetUInt32();
m_stableSlots = fields[26].GetUInt32();
- if(m_stableSlots > 2)
+ if(m_stableSlots > 4)
{
- sLog.outError("Player can have not more 2 stable slots, but have in DB %u",uint32(m_stableSlots));
- m_stableSlots = 2;
+ sLog.outError("Player can have not more 4 stable slots, but have in DB %u",uint32(m_stableSlots));
+ m_stableSlots = 4;
}
m_atLoginFlags = fields[27].GetUInt32();
@@ -14171,34 +14779,18 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
// clear charm/summon related fields
SetCharm(NULL);
+ SetMover(NULL);
SetPet(NULL);
- SetCharmerGUID(NULL);
- SetOwnerGUID(NULL);
- SetCreatorGUID(NULL);
+ SetCharmerGUID(0);
+ SetOwnerGUID(0);
+ SetCreatorGUID(0);
// reset some aura modifiers before aura apply
- SetFarSight(NULL);
+ SetFarSightGUID(0);
SetUInt32Value(PLAYER_TRACK_CREATURES, 0 );
SetUInt32Value(PLAYER_TRACK_RESOURCES, 0 );
- // reset skill modifiers and set correct unlearn flags
- for (uint32 i = 0; i < PLAYER_MAX_SKILLS; i++)
- {
- SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i),0);
-
- // set correct unlearn bit
- uint32 id = GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF;
- if(!id) continue;
-
- SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(id);
- if(!pSkill) continue;
-
- // enable unlearn button for primary professions only
- if (pSkill->categoryId == SKILL_CATEGORY_PROFESSION)
- SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id,1));
- else
- SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id,0));
- }
+ _LoadSkills();
// make sure the unit is considered out of combat for proper loading
ClearInCombat();
@@ -14216,6 +14808,8 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
// reset stats before loading any modifiers
InitStatsForLevel();
InitTaxiNodesForLevel();
+ InitGlyphsForLevel();
+ InitRunes();
// apply original stats mods before spell loading or item equipment that call before equip _RemoveStatsMods()
@@ -14223,6 +14817,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
//_LoadMail();
_LoadAuras(holder->GetResult(PLAYER_LOGIN_QUERY_LOADAURAS), time_diff);
+ _LoadGlyphAuras();
// add ghost flag (must be after aura load: PLAYER_FLAGS_GHOST set in aura)
if( HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST) )
@@ -14230,14 +14825,14 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
_LoadSpells(holder->GetResult(PLAYER_LOGIN_QUERY_LOADSPELLS));
- // after spell load
- InitTalentForLevel();
- learnSkillRewardedSpells();
-
// after spell load, learn rewarded spell if need also
_LoadQuestStatus(holder->GetResult(PLAYER_LOGIN_QUERY_LOADQUESTSTATUS));
_LoadDailyQuestStatus(holder->GetResult(PLAYER_LOGIN_QUERY_LOADDAILYQUESTSTATUS));
+ // after spell and quest load
+ InitTalentForLevel();
+ learnDefaultSpells();
+
_LoadTutorials(holder->GetResult(PLAYER_LOGIN_QUERY_LOADTUTORIALS));
// must be before inventory (some items required reputation check)
@@ -14255,9 +14850,6 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
m_social = sSocialMgr.LoadFromDB(holder->GetResult(PLAYER_LOGIN_QUERY_LOADSOCIALLIST), GetGUIDLow());
- //if(!_LoadHomeBind(holder->GetResult(PLAYER_LOGIN_QUERY_LOADHOMEBIND)))
- // return false;
-
// check PLAYER_CHOSEN_TITLE compatibility with PLAYER__FIELD_KNOWN_TITLES
// note: PLAYER__FIELD_KNOWN_TITLES updated at quest status loaded
if(uint32 curTitle = GetUInt32Value(PLAYER_CHOSEN_TITLE))
@@ -14267,7 +14859,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
}
// Not finish taxi flight path
- if(!m_taxi.LoadTaxiDestinationsFromString(taxi_nodes))
+ if(!m_taxi.LoadTaxiDestinationsFromString(taxi_nodes,GetTeam()))
{
// problems with taxi path loading
TaxiNodesEntry const* nodeEntry = NULL;
@@ -14277,8 +14869,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
if(!nodeEntry) // don't know taxi start node, to homebind
{
sLog.outError("Character %u have wrong data in taxi destination list, teleport to homebind.",GetGUIDLow());
- SetMapId(m_homebindMapId);
- Relocate( m_homebindX, m_homebindY, m_homebindZ,0.0f);
+ RelocateToHomebind();
SaveRecallPosition(); // save as recall also to prevent recall and fall from sky
}
else // have start node, to it
@@ -14303,6 +14894,9 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
// flight will started later
}
+ // has to be called after last Relocate() in Player::LoadFromDB
+ SetFallInformation(0, GetPositionZ());
+
_LoadSpellCooldowns(holder->GetResult(PLAYER_LOGIN_QUERY_LOADSPELLCOOLDOWNS));
// Spell code allow apply any auras to dead character in load time in aura/spell/item loading
@@ -14336,6 +14930,28 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
break;
}
+ switch(sWorld.getConfig(CONFIG_GM_VISIBLE_STATE))
+ {
+ default:
+ case 0: SetGMVisible(false); break; // invisible
+ case 1: break; // visible
+ case 2: // save state
+ if(extraflags & PLAYER_EXTRA_GM_INVISIBLE)
+ SetGMVisible(false);
+ break;
+ }
+
+ /*switch(sWorld.getConfig(CONFIG_GM_ACCEPT_TICKETS))
+ {
+ default:
+ case 0: break; // disable
+ case 1: SetAcceptTicket(true); break; // enable
+ case 2: // save state
+ if(extraflags & PLAYER_EXTRA_GM_ACCEPT_TICKETS)
+ SetAcceptTicket(true);
+ break;
+ }*/
+
switch(sWorld.getConfig(CONFIG_GM_CHAT))
{
default:
@@ -14361,6 +14977,8 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
_LoadDeclinedNames(holder->GetResult(PLAYER_LOGIN_QUERY_LOADDECLINEDNAMES));
+ m_achievementMgr.LoadFromDB(holder->GetResult(PLAYER_LOGIN_QUERY_LOADACHIEVEMENTS), holder->GetResult(PLAYER_LOGIN_QUERY_LOADCRITERIAPROGRESS));
+ m_achievementMgr.CheckAllAchievementCriteria();
return true;
}
@@ -14414,10 +15032,6 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff)
for (int i = 0; i < TOTAL_AURAS; i++)
m_modAuras[i].clear();
- // all aura related fields
- for(int i = UNIT_FIELD_AURA; i <= UNIT_FIELD_AURASTATE; ++i)
- SetUInt32Value(i, 0);
-
//QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'",GetGUIDLow());
if(result)
@@ -14463,7 +15077,7 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff)
remaincharges = spellproto->procCharges;
}
else
- remaincharges = -1;
+ remaincharges = 0;
//do not load single target auras (unless they were cast by the player)
if (caster_guid != GetGUID() && IsSingleTargetSpell(spellproto))
@@ -14488,6 +15102,36 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff)
CastSpell(this,SPELL_ID_PASSIVE_BATTLE_STANCE,true);
}
+void Player::_LoadGlyphAuras()
+{
+ for (uint8 i = 0; i <= MAX_GLYPH_SLOT_INDEX; ++i)
+ {
+ if (uint32 glyph = GetGlyph(i))
+ {
+ if (GlyphPropertiesEntry const *gp = sGlyphPropertiesStore.LookupEntry(glyph))
+ {
+ if (GlyphSlotEntry const *gs = sGlyphSlotStore.LookupEntry(GetGlyphSlot(i)))
+ {
+ if(gp->TypeFlags == gs->TypeFlags)
+ {
+ CastSpell(this, gp->SpellId, true);
+ continue;
+ }
+ else
+ sLog.outError("Player %s has glyph with typeflags %u in slot with typeflags %u, removing.", m_name.c_str(), gp->TypeFlags, gs->TypeFlags);
+ }
+ else
+ sLog.outError("Player %s has not existing glyph slot entry %u on index %u", m_name.c_str(), GetGlyphSlot(i), i);
+ }
+ else
+ sLog.outError("Player %s has not existing glyph entry %u on index %u", m_name.c_str(), glyph, i);
+
+ // On any error remove glyph
+ SetGlyph(i, 0);
+ }
+ }
+}
+
void Player::LoadCorpse()
{
if( isAlive() )
@@ -14663,15 +15307,16 @@ void Player::_LoadInventory(QueryResult *result, uint32 timediff)
// load mailed item which should receive current player
void Player::_LoadMailedItems(Mail *mail)
{
- QueryResult* result = CharacterDatabase.PQuery("SELECT item_guid, item_template FROM mail_items WHERE mail_id='%u'", mail->messageID);
+ // data needs to be at first place for Item::LoadFromDB
+ QueryResult* result = CharacterDatabase.PQuery("SELECT data, item_guid, item_template FROM mail_items JOIN item_instance ON item_guid = guid WHERE mail_id='%u'", mail->messageID);
if(!result)
return;
do
{
Field *fields = result->Fetch();
- uint32 item_guid_low = fields[0].GetUInt32();
- uint32 item_template = fields[1].GetUInt32();
+ uint32 item_guid_low = fields[1].GetUInt32();
+ uint32 item_template = fields[2].GetUInt32();
mail->AddItem(item_guid_low, item_template);
@@ -14687,7 +15332,7 @@ void Player::_LoadMailedItems(Mail *mail)
Item *item = NewItemOrBag(proto);
- if(!item->LoadFromDB(item_guid_low, 0))
+ if(!item->LoadFromDB(item_guid_low, 0, result))
{
sLog.outError( "Player::_LoadMailedItems - Item in mail (%u) doesn't exist !!!! - item guid: %u, deleted from mail", mail->messageID, item_guid_low);
CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid = '%u'", item_guid_low);
@@ -14868,6 +15513,9 @@ void Player::_LoadQuestStatus(QueryResult *result)
if(CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(pQuest->GetCharTitleId()))
SetTitle(titleEntry);
}
+
+ if(pQuest->GetBonusTalents())
+ m_questRewardTalentCount+=pQuest->GetBonusTalents();
}
sLog.outDebug("Quest status is {%u} for quest {%u} for player (GUID: %u)", questStatusData.m_status, quest_id, GetGUIDLow());
@@ -14983,11 +15631,7 @@ void Player::_LoadReputation(QueryResult *result)
void Player::_LoadSpells(QueryResult *result)
{
- for (PlayerSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
- delete itr->second;
- m_spells.clear();
-
- //QueryResult *result = CharacterDatabase.PQuery("SELECT spell,slot,active FROM character_spell WHERE guid = '%u'",GetGUIDLow());
+ //QueryResult *result = CharacterDatabase.PQuery("SELECT spell,active,disabled FROM character_spell WHERE guid = '%u'",GetGUIDLow());
if(result)
{
@@ -14995,7 +15639,7 @@ void Player::_LoadSpells(QueryResult *result)
{
Field *fields = result->Fetch();
- addSpell(fields[0].GetUInt16(), fields[2].GetBool(), false, true, fields[1].GetUInt16(), fields[3].GetBool());
+ addSpell(fields[0].GetUInt16(), fields[1].GetBool(), false, false, fields[2].GetBool());
}
while( result->NextRow() );
@@ -15144,29 +15788,29 @@ InstancePlayerBind* Player::BindToInstance(InstanceSave *save, bool permanent, b
void Player::SendRaidInfo()
{
+ uint32 counter = 0;
+
WorldPacket data(SMSG_RAID_INSTANCE_INFO, 4);
- uint32 counter = 0, i;
- for(i = 0; i < TOTAL_DIFFICULTIES; i++)
- for (BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr)
- if(itr->second.perm) counter++;
+ size_t p_counter = data.wpos();
+ data << uint32(counter); // placeholder
- data << counter;
- for(i = 0; i < TOTAL_DIFFICULTIES; i++)
+ for(int i = 0; i < TOTAL_DIFFICULTIES; ++i)
{
for (BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr)
{
if(itr->second.perm)
{
InstanceSave *save = itr->second.save;
- data << (save->GetMapId());
- data << (uint32)(save->GetResetTime() - time(NULL));
- data << save->GetInstanceId();
- data << uint32(counter);
- counter--;
+ data << uint32(save->GetMapId());
+ data << uint32(save->GetResetTime() - time(NULL));
+ data << uint32(save->GetInstanceId());
+ data << uint32(save->GetDifficulty());
+ ++counter;
}
}
}
+ data.put<uint32>(p_counter,counter);
GetSession()->SendPacket(&data);
}
@@ -15252,6 +15896,13 @@ void Player::ConvertInstancesToGroup(Player *player, Group *group, uint64 player
bool Player::_LoadHomeBind(QueryResult *result)
{
+ PlayerInfo const *info = objmgr.GetPlayerInfo(getRace(), getClass());
+ if(!info)
+ {
+ sLog.outError("Player have incorrect race/class pair. Can't be loaded.");
+ return false;
+ }
+
bool ok = false;
//QueryResult *result = CharacterDatabase.PQuery("SELECT map,zone,position_x,position_y,position_z FROM character_homebind WHERE guid = '%u'", GUID_LOPART(playerGuid));
if (result)
@@ -15276,9 +15927,6 @@ bool Player::_LoadHomeBind(QueryResult *result)
if(!ok)
{
- PlayerInfo const *info = objmgr.GetPlayerInfo(getRace(), getClass());
- if(!info) return false;
-
m_homebindMapId = info->mapId;
m_homebindZoneId = info->zoneId;
m_homebindX = info->positionX;
@@ -15306,12 +15954,6 @@ void Player::SaveToDB()
// first save/honor gain after midnight will also update the player's honor fields
UpdateHonorFields();
- // players aren't saved on battleground maps
- uint32 mapid = IsBeingTeleported() ? GetTeleportDest().mapid : GetMapId();
- const MapEntry * me = sMapStore.LookupEntry(mapid);
- if(!me || me->IsBattleGroundOrArena())
- return;
-
int is_save_resting = HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) ? 1 : 0;
//save, far from tavern/city
//save, but in tavern/city
@@ -15326,10 +15968,10 @@ void Player::SaveToDB()
uint32 tmp_displayid = GetDisplayId();
// Set player sit state to standing on save, also stealth and shifted form
- SetByteValue(UNIT_FIELD_BYTES_1, 0, 0); // stand state
+ SetStandState(UNIT_STAND_STATE_STAND); // stand state
+ RemoveStandFlags(UNIT_STAND_FLAGS_ALL); // stand flags?
SetByteValue(UNIT_FIELD_BYTES_2, 3, 0); // shapeshift
- SetByteValue(UNIT_FIELD_BYTES_1, 3, 0); // stand flags?
- RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
+ RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
SetDisplayId(GetNativeDisplayId());
bool inworld = IsInWorld();
@@ -15347,23 +15989,14 @@ void Player::SaveToDB()
"taximask, online, 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, "
- "death_expire_time, taxi_path, arena_pending_points, latency) VALUES ("
+ "death_expire_time, taxi_path, arena_pending_points, latency, bgid, bgteam, bgmap, bgx, bgy, bgz, bgo) VALUES ("
<< GetGUIDLow() << ", "
<< GetSession()->GetAccountId() << ", '"
<< sql_name << "', "
<< m_race << ", "
<< m_class << ", ";
- bool save_to_dest = false;
- if(IsBeingTeleported())
- {
- // don't save to battlegrounds or arenas
- const MapEntry *entry = sMapStore.LookupEntry(GetTeleportDest().mapid);
- if(entry && entry->map_type != MAP_BATTLEGROUND && entry->map_type != MAP_ARENA)
- save_to_dest = true;
- }
-
- if(!save_to_dest)
+ if(!IsBeingTeleported())
{
ss << GetMapId() << ", "
<< (uint32)GetDifficulty() << ", "
@@ -15388,12 +16021,11 @@ void Player::SaveToDB()
ss << GetUInt32Value(i) << " ";
}
- ss << "', '";
+ ss << "', ";
- for( i = 0; i < 8; i++ )
- ss << m_taxi.GetTaximask(i) << " ";
+ ss << m_taxi; // string with TaxiMaskSize numbers
- ss << "', ";
+ ss << ", ";
ss << (inworld ? 1 : 0);
ss << ", ";
@@ -15447,9 +16079,19 @@ void Player::SaveToDB()
ss << ", '";
ss << m_taxi.SaveTaxiDestinationsToString();
- ss << "', '0', '";
+ ss << "', '0', ";
ss << GetSession()->GetLatency();
- ss << "' )";
+ ss << ", ";
+ ss << GetBattleGroundId();
+ ss << ", ";
+ ss << GetBGTeam();
+ ss << ", ";
+ ss << m_bgEntryPoint.mapid << ", "
+ << finiteAlways(m_bgEntryPoint.x) << ", "
+ << finiteAlways(m_bgEntryPoint.y) << ", "
+ << finiteAlways(m_bgEntryPoint.z) << ", "
+ << finiteAlways(m_bgEntryPoint.o);
+ ss << ")";
CharacterDatabase.Execute( ss.str().c_str() );
@@ -15480,7 +16122,7 @@ void Player::SaveToDB()
pet->SavePetToDB(PET_SAVE_AS_CURRENT);
//to prevent access to DB we should cache some data, which is used very often
- CachePlayerInfoMap::iterator _iter = objmgr.m_mPlayerInfoMap.find(GetGUIDLow());
+ /*CachePlayerInfoMap::iterator _iter = objmgr.m_mPlayerInfoMap.find(GetGUIDLow());
if(_iter != objmgr.m_mPlayerInfoMap.end())//skip new players
{
_iter->second->unLevel = getLevel();
@@ -15494,7 +16136,8 @@ void Player::SaveToDB()
_iter->second->unArenaInfoId0 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (0 * 6));
_iter->second->unArenaInfoId1 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (1 * 6));
_iter->second->unArenaInfoId2 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (2 * 6));
- }
+ }*/
+ m_achievementMgr.SaveToDB();
}
// fast save function for item/money cheating preventing - save only inventory and money state
@@ -15572,7 +16215,7 @@ void Player::_SaveAuras()
{
CharacterDatabase.PExecute("INSERT INTO character_aura (guid,caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges) "
"VALUES ('%u', '" I64FMTD "' ,'%u', '%u', '%u', '%d', '%d', '%d', '%d')",
- GetGUIDLow(), itr2->second->GetCasterGUID(), (uint32)itr2->second->GetId(), (uint32)itr2->second->GetEffIndex(), (uint32)itr2->second->GetStackAmount(), itr2->second->GetModifier()->m_amount,int(itr2->second->GetAuraMaxDuration()),int(itr2->second->GetAuraDuration()),int(itr2->second->m_procCharges));
+ GetGUIDLow(), itr2->second->GetCasterGUID(), (uint32)itr2->second->GetId(), (uint32)itr2->second->GetEffIndex(), (uint32)itr2->second->GetStackAmount(), itr2->second->GetModifier()->m_amount ,int(itr2->second->GetAuraMaxDuration()),int(itr2->second->GetAuraDuration()),int(itr2->second->GetAuraCharges()));
}
}
}
@@ -15773,18 +16416,26 @@ void Player::_SaveReputation()
void Player::_SaveSpells()
{
- for (PlayerSpellMap::const_iterator itr = m_spells.begin(), next = m_spells.begin(); itr != m_spells.end(); itr = next)
+ for (PlayerSpellMap::iterator itr = m_spells.begin(), next = m_spells.begin(); itr != m_spells.end();)
{
- ++next;
if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->state == PLAYERSPELL_CHANGED)
CharacterDatabase.PExecute("DELETE FROM character_spell WHERE guid = '%u' and spell = '%u'", GetGUIDLow(), itr->first);
- if (itr->second->state == PLAYERSPELL_NEW || itr->second->state == PLAYERSPELL_CHANGED)
- CharacterDatabase.PExecute("INSERT INTO character_spell (guid,spell,slot,active,disabled) VALUES ('%u', '%u', '%u','%u','%u')", GetGUIDLow(), itr->first, itr->second->slotId,itr->second->active ? 1 : 0,itr->second->disabled ? 1 : 0);
+
+ // add only changed/new not dependent spells
+ if (!itr->second->dependent && (itr->second->state == PLAYERSPELL_NEW || itr->second->state == PLAYERSPELL_CHANGED))
+ CharacterDatabase.PExecute("INSERT INTO character_spell (guid,spell,active,disabled) VALUES ('%u', '%u', '%u', '%u')", GetGUIDLow(), itr->first, itr->second->active ? 1 : 0,itr->second->disabled ? 1 : 0);
if (itr->second->state == PLAYERSPELL_REMOVED)
- _removeSpell(itr->first);
+ {
+ delete itr->second;
+ m_spells.erase(itr++);
+ }
else
+ {
itr->second->state = PLAYERSPELL_UNCHANGED;
+ ++itr;
+ }
+
}
}
@@ -15956,6 +16607,42 @@ void Player::SetFloatValueInDB(uint16 index, float value, uint64 guid)
Player::SetUInt32ValueInDB(index, temp, guid);
}
+void Player::Customize(uint64 guid, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair)
+{
+ Tokens tokens;
+ if(!LoadValuesArrayFromDB(tokens, guid))
+ return;
+
+ uint32 unit_bytes0 = GetUInt32ValueFromArray(tokens, UNIT_FIELD_BYTES_0);
+ uint8 race = unit_bytes0 & 0xFF;
+ uint8 class_ = (unit_bytes0 >> 8) & 0xFF;
+
+ PlayerInfo const* info = objmgr.GetPlayerInfo(race, class_);
+ if(!info)
+ return;
+
+ unit_bytes0 &= ~(0xFF << 16);
+ unit_bytes0 |= (gender << 16);
+ SetUInt32ValueInArray(tokens, UNIT_FIELD_BYTES_0, unit_bytes0);
+
+ SetUInt32ValueInArray(tokens, UNIT_FIELD_DISPLAYID, gender ? info->displayId_f : info->displayId_m);
+ SetUInt32ValueInArray(tokens, UNIT_FIELD_NATIVEDISPLAYID, gender ? info->displayId_f : info->displayId_m);
+
+ SetUInt32ValueInArray(tokens, PLAYER_BYTES, (skin | (face << 8) | (hairStyle << 16) | (hairColor << 24)));
+
+ uint32 player_bytes2 = GetUInt32ValueFromArray(tokens, PLAYER_BYTES_2);
+ player_bytes2 &= ~0xFF;
+ player_bytes2 |= facialHair;
+ SetUInt32ValueInArray(tokens, PLAYER_BYTES_2, player_bytes2);
+
+ uint32 player_bytes3 = GetUInt32ValueFromArray(tokens, PLAYER_BYTES_3);
+ player_bytes3 &= ~0xFF;
+ player_bytes3 |= gender;
+ SetUInt32ValueInArray(tokens, PLAYER_BYTES_3, player_bytes3);
+
+ SaveValuesArrayInDB(tokens, guid);
+}
+
void Player::SendAttackSwingNotStanding()
{
WorldPacket data(SMSG_ATTACKSWING_NOTSTANDING, 0);
@@ -15988,7 +16675,8 @@ void Player::SendAttackSwingBadFacingAttack()
void Player::SendAutoRepeatCancel()
{
- WorldPacket data(SMSG_CANCEL_AUTO_REPEAT, 0);
+ WorldPacket data(SMSG_CANCEL_AUTO_REPEAT, GetPackGUID().size());
+ data.append(GetPackGUID()); // may be it's target guid
GetSession()->SendPacket( &data );
}
@@ -16217,6 +16905,7 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent)
{
WorldPacket data(SMSG_PET_SPELLS, 8);
data << uint64(0);
+ data << uint32(0);
GetSession()->SendPacket(&data);
if(GetGroup())
@@ -16348,65 +17037,79 @@ void Player::PetSpellInitialize()
{
Pet* pet = GetPet();
- if(pet)
- {
- uint8 addlist = 0;
+ if(!pet)
+ return;
- sLog.outDebug("Pet Spells Groups");
+ sLog.outDebug("Pet Spells Groups");
- CreatureInfo const *cinfo = pet->GetCreatureInfo();
+ CharmInfo *charmInfo = pet->GetCharmInfo();
- if(pet->isControlled() && (pet->getPetType() == HUNTER_PET || cinfo && cinfo->type == CREATURE_TYPE_DEMON && getClass() == CLASS_WARLOCK))
- {
- for(PetSpellMap::iterator itr = pet->m_spells.begin();itr != pet->m_spells.end();++itr)
- {
- if(itr->second->state == PETSPELL_REMOVED)
- continue;
- ++addlist;
- }
- }
+ WorldPacket data(SMSG_PET_SPELLS, 8+4+4+4+10*4);
+ data << uint64(pet->GetGUID());
+ data << uint32(pet->GetCreatureInfo()->family); // creature family (required for pet talents)
+ data << uint32(0);
+ data << uint8(charmInfo->GetReactState()) << uint8(charmInfo->GetCommandState()) << uint16(0);
- // first line + actionbar + spellcount + spells + last adds
- WorldPacket data(SMSG_PET_SPELLS, 16+40+1+4*addlist+25);
+ // action bar loop
+ for(uint32 i = 0; i < 10; i++)
+ {
+ data << uint32(charmInfo->GetActionBarEntry(i)->Raw);
+ }
- CharmInfo *charmInfo = pet->GetCharmInfo();
+ size_t spellsCountPos = data.wpos();
- //16
- data << (uint64)pet->GetGUID() << uint32(0x00000000) << uint8(charmInfo->GetReactState()) << uint8(charmInfo->GetCommandState()) << uint16(0);
+ // spells count
+ uint8 addlist = 0;
+ data << uint8(addlist); // placeholder
- for(uint32 i = 0; i < 10; i++) //40
+ if(pet->isControlled() && ((pet->getPetType() == HUNTER_PET) || ((pet->GetCreatureInfo()->type == CREATURE_TYPE_DEMON) && (getClass() == CLASS_WARLOCK))))
+ {
+ // spells loop
+ for (PetSpellMap::iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end(); ++itr)
{
- data << uint16(charmInfo->GetActionBarEntry(i)->SpellOrAction) << uint16(charmInfo->GetActionBarEntry(i)->Type);
+ if(itr->second->state == PETSPELL_REMOVED)
+ continue;
+
+ data << uint16(itr->first);
+ data << uint16(itr->second->active); // pet spell active state isn't boolean
+ ++addlist;
}
+ }
- data << uint8(addlist); //1
+ data.put<uint8>(spellsCountPos, addlist);
- if(addlist && pet->isControlled())
- {
- for (PetSpellMap::iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end(); ++itr)
- {
- if(itr->second->state == PETSPELL_REMOVED)
- continue;
+ uint8 cooldownsCount = pet->m_CreatureSpellCooldowns.size() + pet->m_CreatureCategoryCooldowns.size();
+ data << uint8(cooldownsCount);
- data << uint16(itr->first);
- data << uint16(itr->second->active); // pet spell active state isn't boolean
- }
- }
+ time_t curTime = time(NULL);
- //data << uint8(0x01) << uint32(0x6010) << uint32(0x01) << uint32(0x05) << uint16(0x00); //15
- uint8 count = 3; //1+8+8+8=25
+ for(CreatureSpellCooldowns::const_iterator itr = pet->m_CreatureSpellCooldowns.begin(); itr != pet->m_CreatureSpellCooldowns.end(); ++itr)
+ {
+ time_t cooldown = 0;
- // if count = 0, then end of packet...
- data << count;
- // uint32 value is spell id...
- // uint64 value is constant 0, unknown...
- data << uint32(0x6010) << uint64(0); // if count = 1, 2 or 3
- //data << uint32(0x5fd1) << uint64(0); // if count = 2
- data << uint32(0x8e8c) << uint64(0); // if count = 3
- data << uint32(0x8e8b) << uint64(0); // if count = 3
+ if(itr->second > curTime)
+ cooldown = (itr->second - curTime) * 1000;
- GetSession()->SendPacket(&data);
+ data << uint16(itr->first); // spellid
+ data << uint16(0); // spell category?
+ data << uint32(itr->second); // cooldown
+ data << uint32(0); // category cooldown
}
+
+ for(CreatureSpellCooldowns::const_iterator itr = pet->m_CreatureCategoryCooldowns.begin(); itr != pet->m_CreatureCategoryCooldowns.end(); ++itr)
+ {
+ time_t cooldown = 0;
+
+ if(itr->second > curTime)
+ cooldown = (itr->second - curTime) * 1000;
+
+ data << uint16(itr->first); // spellid
+ data << uint16(0); // spell category?
+ data << uint32(0); // cooldown
+ data << uint32(itr->second); // category cooldown
+ }
+
+ GetSession()->SendPacket(&data);
}
void Player::PossessSpellInitialize()
@@ -16428,7 +17131,10 @@ void Player::PossessSpellInitialize()
WorldPacket data(SMSG_PET_SPELLS, 16+40+1+4*addlist+25);// first line + actionbar + spellcount + spells + last adds
//16
- data << (uint64)charm->GetGUID() << uint32(0x00000000) << uint8(0) << uint8(0) << uint16(0);
+ data << uint64(charm->GetGUID());
+ data << uint32(0x00000000);
+ data << uint32(0);
+ data << uint8(0) << uint8(0) << uint16(0);
for(uint32 i = 0; i < 10; i++) //40
{
@@ -16437,11 +17143,8 @@ void Player::PossessSpellInitialize()
data << uint8(addlist); //1
- uint8 count = 3;
- data << count;
- data << uint32(0x6010) << uint64(0); // if count = 1, 2 or 3
- data << uint32(0x8e8c) << uint64(0); // if count = 3
- data << uint32(0x8e8b) << uint64(0); // if count = 3
+ uint8 count = 0;
+ data << uint8(count); // cooldowns count
GetSession()->SendPacket(&data);
}
@@ -16478,13 +17181,13 @@ void Player::CharmSpellInitialize()
WorldPacket data(SMSG_PET_SPELLS, 16+40+1+4*addlist+25);// first line + actionbar + spellcount + spells + last adds
- data << (uint64)charm->GetGUID() << uint32(0x00000000);
-
+ data << uint64(charm->GetGUID());
+ data << uint32(0x00000000);
+ data << uint32(0);
if(charm->GetTypeId() != TYPEID_PLAYER)
data << uint8(charmInfo->GetReactState()) << uint8(charmInfo->GetCommandState());
else
data << uint8(0) << uint8(0);
-
data << uint16(0);
for(uint32 i = 0; i < 10; i++) //40
@@ -16507,51 +17210,12 @@ void Player::CharmSpellInitialize()
}
}
- uint8 count = 3;
- data << count;
- data << uint32(0x6010) << uint64(0); // if count = 1, 2 or 3
- data << uint32(0x8e8c) << uint64(0); // if count = 3
- data << uint32(0x8e8b) << uint64(0); // if count = 3
+ uint8 count = 0;
+ data << uint8(count); // cooldowns count
GetSession()->SendPacket(&data);
}
-int32 Player::GetTotalFlatMods(uint32 spellId, SpellModOp op)
-{
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId);
- if (!spellInfo) return 0;
- int32 total = 0;
- for (SpellModList::iterator itr = m_spellMods[op].begin(); itr != m_spellMods[op].end(); ++itr)
- {
- SpellModifier *mod = *itr;
-
- if(!IsAffectedBySpellmod(spellInfo,mod))
- continue;
-
- if (mod->type == SPELLMOD_FLAT)
- total += mod->value;
- }
- return total;
-}
-
-int32 Player::GetTotalPctMods(uint32 spellId, SpellModOp op)
-{
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId);
- if (!spellInfo) return 0;
- int32 total = 0;
- for (SpellModList::iterator itr = m_spellMods[op].begin(); itr != m_spellMods[op].end(); ++itr)
- {
- SpellModifier *mod = *itr;
-
- if(!IsAffectedBySpellmod(spellInfo,mod))
- continue;
-
- if (mod->type == SPELLMOD_PCT)
- total += mod->value;
- }
- return total;
-}
-
bool Player::IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mod, Spell const* spell)
{
if (!mod || !spellInfo)
@@ -16569,22 +17233,27 @@ bool Player::IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mo
return false;
}
- return spellmgr.IsAffectedBySpell(spellInfo,mod->spellId,mod->effectId,mod->mask);
+ return spellmgr.IsAffectedByMod(spellInfo, mod);
}
void Player::AddSpellMod(SpellModifier* mod, bool apply)
{
uint16 Opcode= (mod->type == SPELLMOD_FLAT) ? SMSG_SET_FLAT_SPELL_MODIFIER : SMSG_SET_PCT_SPELL_MODIFIER;
- for(int eff=0;eff<64;++eff)
+ uint8 i=0;
+ flag96 _mask;
+ for(int eff=0;eff<96;++eff)
{
- uint64 _mask = uint64(1) << eff;
+ if ((eff!=0) && (eff%32==0))
+ 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)
+ if ((*itr)->type == mod->type && (*itr)->mask & _mask )
val += (*itr)->value;
}
val += apply ? mod->value : -(mod->value);
@@ -16683,6 +17352,27 @@ void Player::RemovePetitionsAndSigns(uint64 guid, uint32 type)
CharacterDatabase.CommitTransaction();
}
+void Player::LeaveAllArenaTeams(uint64 guid)
+{
+ QueryResult *result = CharacterDatabase.PQuery("SELECT arena_team_member.arenateamid FROM arena_team_member JOIN arena_team ON arena_team_member.arenateamid = arena_team.arenateamid WHERE guid='%u'", GUID_LOPART(guid));
+ if(!result)
+ return;
+
+ do
+ {
+ Field *fields = result->Fetch();
+ uint32 at_id = fields[0].GetUInt32();
+ if(at_id != 0)
+ {
+ ArenaTeam * at = objmgr.GetArenaTeamById(at_id);
+ if(at)
+ at->DelMember(guid);
+ }
+ } while (result->NextRow());
+
+ delete result;
+}
+
void Player::SetRestBonus (float rest_bonus_new)
{
// Prevent resting on max level
@@ -16713,7 +17403,7 @@ void Player::HandleStealthedUnitsDetection()
{
std::list<Unit*> stealthedUnits;
Trinity::AnyStealthedCheck u_check;
- Trinity::UnitListSearcher<Trinity::AnyStealthedCheck > searcher(stealthedUnits, u_check);
+ Trinity::UnitListSearcher<Trinity::AnyStealthedCheck > searcher(this, stealthedUnits, u_check);
VisitNearbyObject(World::GetMaxVisibleDistance(), searcher);
for (std::list<Unit*>::iterator i = stealthedUnits.begin(); i != stealthedUnits.end(); ++i)
@@ -16732,7 +17422,7 @@ void Player::HandleStealthedUnitsDetection()
// send data at target visibility change (adding to client)
if((*i)!=this && (*i)->isType(TYPEMASK_UNIT))
{
- SendAuraDurationsForTarget(*i);
+ SendAurasForTarget(*i);
//if(((Unit*)(*i))->isAlive()) //should be always alive
{
if((*i)->GetTypeId()==TYPEID_UNIT)
@@ -17528,6 +18218,10 @@ bool Player::canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList, bool
if (u == this)
return true;
+ // phased visibility (both must phased in same way)
+ if(!InSamePhase(u))
+ return false;
+
// player visible for other player if not logout and at same transport
// including case when player is out of world
bool at_same_transport =
@@ -17726,7 +18420,7 @@ void Player::UpdateVisibilityOf(WorldObject* target)
// send data at target visibility change (adding to client)
if(target!=this && target->isType(TYPEMASK_UNIT))
{
- SendAuraDurationsForTarget((Unit*)target);
+ SendAurasForTarget((Unit*)target);
if(((Unit*)target)->isAlive())
{
if(target->GetTypeId()==TYPEID_UNIT)
@@ -17905,7 +18599,7 @@ void Player::SetGroup(Group *group, int8 subgroup)
void Player::SendInitialPacketsBeforeAddToMap()
{
- WorldPacket data(SMSG_SET_REST_START, 4);
+ WorldPacket data(SMSG_SET_REST_START_OBSOLETE, 4);
data << uint32(0); // unknown, may be rest state time or experience
GetSession()->SendPacket(&data);
@@ -17933,6 +18627,7 @@ void Player::SendInitialPacketsBeforeAddToMap()
SendInitialActionButtons();
SendInitialReputations();
+ m_achievementMgr.SendAllAchievementData();
UpdateZone(GetZoneId());
SendInitWorldStates();
@@ -17943,13 +18638,23 @@ void Player::SendInitialPacketsBeforeAddToMap()
data << (float)0.01666667f; // game speed
GetSession()->SendPacket( &data );
+ data.Initialize(SMSG_TIME_SYNC_REQ, 4); // new 2.0.x, enable movement
+ data << uint32(0x00000000); // on blizz it increments periodically
+ GetSession()->SendPacket(&data);
+
// set fly flag if in fly form or taxi flight to prevent visually drop at ground in showup moment
if(HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED) || isInFlight())
AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
+
+ m_mover = this;
}
void Player::SendInitialPacketsAfterAddToMap()
{
+ WorldPacket data(SMSG_TIME_SYNC_REQ, 4); // new 2.0.x, enable movement
+ data << uint32(0x00000000); // on blizz it increments periodically
+ GetSession()->SendPacket(&data);
+
CastSpell(this, 836, true); // LOGINEFFECT
// set some aura effects that send packet to player client after add player to map
@@ -17980,6 +18685,41 @@ void Player::SendInitialPacketsAfterAddToMap()
SendMessageToSet(&data,true);
}
+ // setup BG group membership if need
+ if(BattleGround* currentBg = GetBattleGround())
+ {
+ // call for invited (join) or listed (relogin) and avoid other cases (GM teleport)
+ if (IsInvitedForBattleGroundInstance(GetBattleGroundId()) ||
+ currentBg->IsPlayerInBattleGround(GetGUID()))
+ {
+ currentBg->PlayerRelogin(this);
+ if(currentBg->GetMapId() == GetMapId()) // we teleported/login to/in bg
+ {
+ uint32 team = currentBg->GetPlayerTeam(GetGUID());
+ if(!team)
+ team = GetTeam();
+ Group* group = currentBg->GetBgRaid(team);
+ if(!group) // first player joined
+ {
+ group = new Group;
+ currentBg->SetBgRaid(team, group);
+ group->Create(GetGUIDLow(), GetName());
+ }
+ else // raid already exist
+ {
+ if(group->IsMember(GetGUID()))
+ {
+ uint8 subgroup = group->GetMemberGroup(GetGUID());
+ SetGroup(group, subgroup);
+ }
+ else
+ currentBg->GetBgRaid(team)->AddMember(GetGUID(), GetName());
+ }
+ }
+ }
+ }
+
+ SendAurasForTarget(this);
SendEnchantmentDurations(); // must be after add to map
SendItemDurations(); // must be after add to map
}
@@ -17992,16 +18732,24 @@ void Player::SendUpdateToOutOfRangeGroupMembers()
group->UpdatePlayerOutOfRange(this);
m_groupUpdateMask = GROUP_UPDATE_FLAG_NONE;
- m_auraUpdateMask = 0;
+ m_auraRaidUpdateMask = 0;
if(Pet *pet = GetPet())
- pet->ResetAuraUpdateMask();
+ pet->ResetAuraUpdateMaskForRaid();
}
-void Player::SendTransferAborted(uint32 mapid, uint16 reason)
+void Player::SendTransferAborted(uint32 mapid, uint8 reason, uint8 arg)
{
WorldPacket data(SMSG_TRANSFER_ABORTED, 4+2);
data << uint32(mapid);
- data << uint16(reason); // transfer abort reason
+ data << uint8(reason); // transfer abort reason
+ switch(reason)
+ {
+ case TRANSFER_ABORT_INSUF_EXPAN_LVL:
+ case TRANSFER_ABORT_DIFFICULTY:
+ case TRANSFER_ABORT_UNIQUE_MESSAGE:
+ data << uint8(arg);
+ break;
+ }
GetSession()->SendPacket(&data);
}
@@ -18067,22 +18815,18 @@ void Player::resetSpells()
learnQuestRewardedSpells();
}
-void Player::learnDefaultSpells(bool loading)
+void Player::learnDefaultSpells()
{
// learn default race/class spells
PlayerInfo const *info = objmgr.GetPlayerInfo(getRace(),getClass());
- std::list<CreateSpellPair>::const_iterator spell_itr;
- for (spell_itr = info->spell.begin(); spell_itr!=info->spell.end(); ++spell_itr)
+ for (PlayerCreateInfoSpells::const_iterator itr = info->spell.begin(); itr!=info->spell.end(); ++itr)
{
- uint16 tspell = spell_itr->first;
- if (tspell)
- {
- sLog.outDebug("PLAYER: Adding initial spell, id = %u",tspell);
- if(loading || !spell_itr->second) // not care about passive spells or loading case
- addSpell(tspell,spell_itr->second);
- else // but send in normal spell in game learn case
- learnSpell(tspell);
- }
+ uint32 tspell = *itr;
+ sLog.outDebug("PLAYER (Class: %u Race: %u): Adding initial spell, id = %u",uint32(getClass()),uint32(getRace()), tspell);
+ if(!IsInWorld()) // will send in INITIAL_SPELLS in list anyway at map add
+ addSpell(tspell,true,true,true,false);
+ else // but send in normal spell in game learn case
+ learnSpell(tspell,true);
}
}
@@ -18174,7 +18918,7 @@ void Player::learnQuestRewardedSpells()
}
}
-void Player::learnSkillRewardedSpells(uint32 skill_id )
+void Player::learnSkillRewardedSpells(uint32 skill_id, uint32 skill_value )
{
uint32 raceMask = getRaceMask();
uint32 classMask = getClassMask();
@@ -18192,35 +18936,67 @@ void Player::learnSkillRewardedSpells(uint32 skill_id )
if (sSpellStore.LookupEntry(pAbility->spellId))
{
- // Ok need learn spell
- learnSpell(pAbility->spellId);
+ // need unlearn spell
+ if (skill_value < pAbility->req_skill_value)
+ removeSpell(pAbility->spellId);
+ // need learn
+ else if (!IsInWorld())
+ addSpell(pAbility->spellId,true,true,true,false);
+ else
+ learnSpell(pAbility->spellId,true);
}
}
}
-void Player::learnSkillRewardedSpells()
+void Player::SendAurasForTarget(Unit *target)
{
- for (uint16 i=0; i < PLAYER_MAX_SKILLS; i++)
- {
- if(!GetUInt32Value(PLAYER_SKILL_INDEX(i)))
- continue;
-
- uint32 pskill = GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF;
+ if(!target || target->GetVisibleAuras()->empty()) // speedup things
+ return;
- learnSkillRewardedSpells(pskill);
- }
-}
+ WorldPacket data(SMSG_AURA_UPDATE_ALL);
+ data.append(target->GetPackGUID());
-void Player::SendAuraDurationsForTarget(Unit* target)
-{
- for(Unit::AuraMap::const_iterator itr = target->GetAuras().begin(); itr != target->GetAuras().end(); ++itr)
+ Unit::VisibleAuraMap const *visibleAuras = target->GetVisibleAuras();
+ for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)
{
- Aura* aura = itr->second;
- if(aura->GetAuraSlot() >= MAX_AURAS || aura->IsPassive() || aura->GetCasterGUID()!=GetGUID())
- continue;
+ Aura * aura=NULL;
+ for (uint8 i=0 ; i<3; i++)
+ {
+ if (itr->second.m_slotAuras[i])
+ {
+ aura=itr->second.m_slotAuras[i];
+ break;
+ }
+ }
+ if(aura)
+ {
+ data << uint8(aura->GetAuraSlot());
+ data << uint32(aura->GetId());
+
+ if(aura->GetId())
+ {
+ // flags
+ data << itr->second.m_Flags;
+ // level
+ data << itr->second.m_Level;
+ // charges
+ data << uint8(aura->GetAuraCharges());
+
+ if(!(itr->second.m_Flags & AFLAG_NOT_CASTER))
+ {
+ data << uint8(0); // packed GUID of someone (caster?)
+ }
- aura->SendAuraDurationForCaster(this);
+ if(itr->second.m_Flags & AFLAG_DURATION) // include aura duration
+ {
+ data << uint32(aura->GetAuraMaxDuration());
+ data << uint32(aura->GetAuraDuration());
+ }
+ }
+ }
}
+
+ GetSession()->SendPacket(&data);
}
void Player::SetDailyQuestStatus( uint32 quest_id )
@@ -18264,7 +19040,7 @@ bool Player::InArena() const
return true;
}
-bool Player::GetBGAccessByLevel(uint32 bgTypeId) const
+bool Player::GetBGAccessByLevel(BattleGroundTypeId bgTypeId) const
{
// get a template bg instead of running one
BattleGround *bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
@@ -18282,15 +19058,15 @@ uint32 Player::GetMinLevelForBattleGroundQueueId(uint32 queue_id)
if(queue_id < 1)
return 0;
- if(queue_id >=6)
- queue_id = 6;
+ if(queue_id >=7)
+ queue_id = 7;
return 10*(queue_id+1);
}
uint32 Player::GetMaxLevelForBattleGroundQueueId(uint32 queue_id)
{
- if(queue_id >=6)
+ if(queue_id >=7)
return 255; // hardcoded max level
return 10*(queue_id+2)-1;
@@ -18302,8 +19078,8 @@ uint32 Player::GetBattleGroundQueueIdFromLevel() const
uint32 level = getLevel();
if(level <= 19)
return 0;
- else if (level > 69)
- return 6;
+ else if (level > 79)
+ return 7;
else
return level/10 - 1; // 20..29 -> 1, 30-39 -> 2, ...
/*
@@ -18333,18 +19109,23 @@ bool Player::IsSpellFitByClassAndRace( uint32 spell_id ) const
SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(spell_id);
SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(spell_id);
+ if(lower==upper)
+ return true;
for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
{
// skip wrong race skills
if( _spell_idx->second->racemask && (_spell_idx->second->racemask & racemask) == 0)
- return false;
+ continue;
// skip wrong class skills
if( _spell_idx->second->classmask && (_spell_idx->second->classmask & classmask) == 0)
- return false;
+ continue;
+
+ return true;
}
- return true;
+
+ return false;
}
bool Player::HasQuestForGO(int32 GOId)
@@ -18449,9 +19230,8 @@ void Player::AutoUnequipOffhandIfNeed()
if(!offItem)
return;
- Item *mainItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND );
-
- if(!mainItem || mainItem->GetProto()->InventoryType != INVTYPE_2HWEAPON)
+ // need unequip for 2h-weapon without TitanGrip
+ if (!IsTwoHandUsed())
return;
ItemPosCountVec off_dest;
@@ -18484,7 +19264,7 @@ bool Player::HasItemFitToSpellReqirements(SpellEntry const* spellInfo, Item cons
case ITEM_CLASS_WEAPON:
{
for(int i= EQUIPMENT_SLOT_MAINHAND; i < EQUIPMENT_SLOT_TABARD; ++i)
- if(Item *item = GetItemByPos( INVENTORY_SLOT_BAG_0, i ))
+ if(Item *item = GetUseableItemByPos( INVENTORY_SLOT_BAG_0, i ))
if(item!=ignoreItem && item->IsFitToSpellRequirements(spellInfo))
return true;
break;
@@ -18493,17 +19273,17 @@ bool Player::HasItemFitToSpellReqirements(SpellEntry const* spellInfo, Item cons
{
// tabard not have dependent spells
for(int i= EQUIPMENT_SLOT_START; i< EQUIPMENT_SLOT_MAINHAND; ++i)
- if(Item *item = GetItemByPos( INVENTORY_SLOT_BAG_0, i ))
+ if(Item *item = GetUseableItemByPos( INVENTORY_SLOT_BAG_0, i ))
if(item!=ignoreItem && item->IsFitToSpellRequirements(spellInfo))
return true;
// shields can be equipped to offhand slot
- if(Item *item = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND))
+ if(Item *item = GetUseableItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND))
if(item!=ignoreItem && item->IsFitToSpellRequirements(spellInfo))
return true;
// ranged slot can have some armor subclasses
- if(Item *item = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED))
+ if(Item *item = GetUseableItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED))
if(item!=ignoreItem && item->IsFitToSpellRequirements(spellInfo))
return true;
@@ -18517,6 +19297,24 @@ bool Player::HasItemFitToSpellReqirements(SpellEntry const* spellInfo, Item cons
return false;
}
+bool Player::CanNoReagentCast(SpellEntry const* spellInfo) const
+{
+ // don't take reagents for spells with SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP
+ if (spellInfo->AttributesEx5 & SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP &&
+ HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION))
+ return true;
+
+ // Check no reagent use mask
+ flag96 noReagentMask;
+ noReagentMask[0] = GetUInt32Value(PLAYER_NO_REAGENT_COST_1);
+ noReagentMask[1] = GetUInt32Value(PLAYER_NO_REAGENT_COST_1+1);
+ noReagentMask[2] = GetUInt32Value(PLAYER_NO_REAGENT_COST_1+2);
+ if (spellInfo->SpellFamilyFlags & noReagentMask)
+ return true;
+
+ return false;
+}
+
void Player::RemoveItemDependentAurasAndCasts( Item * pItem )
{
AuraMap& auras = GetAuras();
@@ -18562,7 +19360,7 @@ uint32 Player::GetResurrectionSpellId()
for(AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr)
{
// Soulstone Resurrection // prio: 3 (max, non death persistent)
- if( prio < 2 && (*itr)->GetSpellProto()->SpellVisual == 99 && (*itr)->GetSpellProto()->SpellIconID == 92 )
+ if( prio < 2 && (*itr)->GetSpellProto()->SpellVisual[0] == 99 && (*itr)->GetSpellProto()->SpellIconID == 92 )
{
switch((*itr)->GetId())
{
@@ -18572,6 +19370,7 @@ uint32 Player::GetResurrectionSpellId()
case 20764: spell_id = 20760; break; // rank 4
case 20765: spell_id = 20761; break; // rank 5
case 27239: spell_id = 27240; break; // rank 6
+ case 47883: spell_id = 47882; break; // rank 7
default:
sLog.outError("Unhandled spell %%u: S.Resurrection",(*itr)->GetId());
continue;
@@ -18594,6 +19393,26 @@ uint32 Player::GetResurrectionSpellId()
return spell_id;
}
+// Used in triggers for check "Only to targets that grant experience or honor" req
+bool Player::isHonorOrXPTarget(Unit* pVictim)
+{
+ uint32 v_level = pVictim->getLevel();
+ uint32 k_grey = Trinity::XP::GetGrayLevel(getLevel());
+
+ // Victim level less gray level
+ if(v_level<=k_grey)
+ return false;
+
+ if(pVictim->GetTypeId() == TYPEID_UNIT)
+ {
+ if (((Creature*)pVictim)->isTotem() ||
+ ((Creature*)pVictim)->isPet() ||
+ ((Creature*)pVictim)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_XP_AT_KILL)
+ return false;
+ }
+ return true;
+}
+
bool Player::RewardPlayerAndGroupAtKill(Unit* pVictim)
{
bool PvP = pVictim->isCharmedOwnedByPlayerOrPlayer();
@@ -18721,6 +19540,9 @@ uint32 Player::GetBaseWeaponSkillValue (WeaponAttackType attType) const
void Player::ResurectUsingRequestData()
{
+ /// Teleport before resurrecting, otherwise the player might get attacked from creatures near his corpse
+ TeleportTo(m_resurrectMap, m_resurrectX, m_resurrectY, m_resurrectZ, GetOrientation());
+
ResurrectPlayer(0.0f,false);
if(GetMaxHealth() > m_resurrectHealth)
@@ -18738,8 +19560,6 @@ void Player::ResurectUsingRequestData()
SetPower(POWER_ENERGY, GetMaxPower(POWER_ENERGY) );
SpawnCorpseBones();
-
- TeleportTo(m_resurrectMap, m_resurrectX, m_resurrectY, m_resurrectZ, GetOrientation());
}
void Player::SetClientControl(Unit* target, uint8 allowMove)
@@ -18753,28 +19573,31 @@ void Player::SetClientControl(Unit* target, uint8 allowMove)
void Player::UpdateZoneDependentAuras( uint32 newZone )
{
// remove new continent flight forms
- if( !isGameMaster() &&
- GetVirtualMapForMapAndZone(GetMapId(),newZone) != 530)
+ if( !IsAllowUseFlyMountsHere() )
{
RemoveSpellsCausingAura(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED);
RemoveSpellsCausingAura(SPELL_AURA_FLY);
}
// Some spells applied at enter into zone (with subzones)
- // Human Illusion
- // NOTE: these are removed by RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CHANGE_MAP);
- if ( newZone == 2367 ) // Old Hillsbrad Foothills
- {
- uint32 spellid = 0;
- // all horde races
- if( GetTeam() == HORDE )
- spellid = getGender() == GENDER_FEMALE ? 35481 : 35480;
- // and some alliance races
- else if( getRace() == RACE_NIGHTELF || getRace() == RACE_DRAENEI )
- spellid = getGender() == GENDER_FEMALE ? 35483 : 35482;
-
- if(spellid && !HasAura(spellid,0) )
- CastSpell(this,spellid,true);
+ switch(newZone)
+ {
+ case 2367: // Old Hillsbrad Foothills
+ {
+ // Human Illusion
+ // NOTE: these are removed by RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CHANGE_MAP);
+ uint32 spellid = 0;
+ // all horde races
+ if( GetTeam() == HORDE )
+ spellid = getGender() == GENDER_FEMALE ? 35481 : 35480;
+ // and some alliance races
+ else if( getRace() == RACE_NIGHTELF || getRace() == RACE_DRAENEI )
+ spellid = getGender() == GENDER_FEMALE ? 35483 : 35482;
+
+ if(spellid && !HasAura(spellid,0) )
+ CastSpell(this,spellid,true);
+ break;
+ }
}
}
@@ -18784,25 +19607,41 @@ void Player::UpdateAreaDependentAuras( uint32 newArea )
for(AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end();)
{
// use m_zoneUpdateId for speed: UpdateArea called from UpdateZone or instead UpdateZone in both cases m_zoneUpdateId up-to-date
- if(!IsSpellAllowedInLocation(iter->second->GetSpellProto(),GetMapId(),m_zoneUpdateId,newArea))
+ if(GetSpellAllowedInLocationError(iter->second->GetSpellProto(),GetMapId(),m_zoneUpdateId,newArea,GetBattleGroundId())!=0)
RemoveAura(iter);
else
++iter;
}
- // unmount if enter in this subzone
- if( newArea == 35)
- RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
- // Dragonmaw Illusion
- else if( newArea == 3759 || newArea == 3966 || newArea == 3939 )
+ // some auras applied at subzone enter
+ switch(newArea)
{
- if( GetDummyAura(40214) )
- {
- if( !HasAura(40216,0) )
- CastSpell(this,40216,true);
- if( !HasAura(42016,0) )
- CastSpell(this,42016,true);
- }
+ // Dragonmaw Illusion
+ case 3759: // Netherwing Ledge
+ case 3939: // Dragonmaw Fortress
+ case 3966: // Dragonmaw Base Camp
+ if( GetDummyAura(40214) )
+ {
+ if( !HasAura(40216,0) )
+ CastSpell(this,40216,true);
+ if( !HasAura(42016,0) )
+ CastSpell(this,42016,true);
+ }
+ break;
+ // Dominion Over Acherus
+ case 4281: // Acherus: The Ebon Hold
+ case 4342: // Acherus: The Ebon Hold
+ if( HasSpell(51721) )
+ if( !HasAura(51721,0) )
+ CastSpell(this,51721,true);
+ break;
+ // Mist of the Kvaldir
+ case 4028: //Riplash Strand
+ case 4029: //Riplash Ruins
+ case 4106: //Garrosh's Landing
+ case 4031: //Pal'ea
+ CastSpell(this,54119,true);
+ break;
}
}
@@ -18937,18 +19776,20 @@ PartyResult Player::CanUninviteFromGroup() const
void Player::UpdateUnderwaterState( Map* m, float x, float y, float z )
{
float water_z = m->GetWaterLevel(x,y);
- float height_z = m->GetHeight(x,y,z, false); // use .map base surface height
+ float terrain_z = m->GetHeight(x,y,z, false); // use .map base surface height
uint8 flag1 = m->GetTerrainType(x,y);
- //!Underwater check, not in water if underground or above water level
- if (height_z <= INVALID_HEIGHT || z < (height_z-2) || z > (water_z - 2) )
- m_isunderwater &= 0x7A;
+ //!Underwater check, not in water if underground or above water level - take UC royal quater for example
+ if (terrain_z <= INVALID_HEIGHT || z < (terrain_z-2) || z > (water_z - 2) )
+ m_isunderwater &= ~UNDERWATER_INWATER;
else if ((z < (water_z - 2)) && (flag1 & 0x01))
- m_isunderwater |= 0x01;
+ m_isunderwater |= UNDERWATER_INWATER;
//!in lava check, anywhere under lava level
- if ((height_z <= INVALID_HEIGHT || z < (height_z - 0)) && (flag1 == 0x00) && IsInWater())
- m_isunderwater |= 0x80;
+ if ((terrain_z <= INVALID_HEIGHT || z < (terrain_z - 0)) && (flag1 == 0x00) && IsInWater())
+ m_isunderwater |= UNDERWATER_INLAVA;
+ else
+ m_isunderwater &= ~UNDERWATER_INLAVA;
}
void Player::SetCanParry( bool value )
@@ -18983,8 +19824,8 @@ bool ItemPosCount::isContainedIn(ItemPosCountVec const& vec) const
void Player::HandleFallDamage(MovementInfo& movementInfo)
{
- if(movementInfo.fallTime < 1500)
- return;
+ //if(movementInfo.fallTime < 1500)
+ // return;
// calculate total z distance of the fall
float z_diff = m_lastFallZ - movementInfo.z;
@@ -18994,7 +19835,7 @@ void Player::HandleFallDamage(MovementInfo& movementInfo)
// 14.57 can be calculated by resolving damageperc formular below to 0
if (z_diff >= 14.57f && !isDead() && !isGameMaster() &&
!HasAuraType(SPELL_AURA_HOVER) && !HasAuraType(SPELL_AURA_FEATHER_FALL) &&
- !HasAuraType(SPELL_AURA_FLY) && !IsImmunedToDamage(SPELL_SCHOOL_MASK_NORMAL,true) )
+ !HasAuraType(SPELL_AURA_FLY) && !IsImmunedToDamage(SPELL_SCHOOL_MASK_NORMAL) )
{
//Safe fall, fall height reduction
int32 safe_fall = GetTotalAuraModifier(SPELL_AURA_SAFE_FALL);
@@ -19089,38 +19930,46 @@ void Player::RemovePossess(bool attack)
}*/
}
-void Player::SetViewport(uint64 guid, bool moveable)
+/*void Player::SetViewport(uint64 guid, bool moveable)
{
WorldPacket data(SMSG_CLIENT_CONTROL_UPDATE, 8+1);
data.appendPackGUID(guid); // Packed guid of object to set client's view to
data << (moveable ? uint8(0x01) : uint8(0x00)); // 0 - can't move; 1 - can move
m_session->SendPacket(&data);
sLog.outDetail("Viewport for "I64FMT" (%s) changed to "I64FMT, GetGUID(), GetName(), guid);
+}*/
+
+void Player::SetBindSight(Unit *target)
+{
+ if(target)
+ target->AddPlayerToVision(this);
+ else
+ target->RemovePlayerFromVision(this);
}
WorldObject* Player::GetFarsightTarget() const
{
// Players can have in farsight field another player's guid, a creature's guid, or a dynamic object's guid
- if (uint64 guid = GetUInt64Value(PLAYER_FARSIGHT))
- return (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*this, guid, TYPEMASK_PLAYER | TYPEMASK_UNIT | TYPEMASK_DYNAMICOBJECT);
+ if(uint64 guid = GetFarSight())
+ return (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*this, guid, TYPEMASK_FARSIGHTOBJ);
return NULL;
}
void Player::RemoveFarsightTarget()
{
- if (WorldObject* fTarget = GetFarsightTarget())
+ if (WorldObject* target = GetFarsightTarget())
{
- if (fTarget->isType(TYPEMASK_PLAYER | TYPEMASK_UNIT))
- ((Unit*)fTarget)->RemovePlayerFromVision(this);
+ if (target->isType(TYPEMASK_PLAYER | TYPEMASK_UNIT))
+ ((Unit*)target)->RemovePlayerFromVision(this);
}
ClearFarsight();
}
void Player::ClearFarsight()
{
- if (GetUInt64Value(PLAYER_FARSIGHT))
+ if(GetFarSight())
{
- SetUInt64Value(PLAYER_FARSIGHT, 0);
+ SetFarSightGUID(0);
WorldPacket data(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, 0);
GetSession()->SendPacket(&data);
}
@@ -19134,7 +19983,7 @@ void Player::SetFarsightTarget(WorldObject* obj)
// Remove the current target if there is one
RemoveFarsightTarget();
- SetUInt64Value(PLAYER_FARSIGHT, obj->GetGUID());
+ SetFarSightGUID(obj->GetGUID());
}
bool Player::isAllowUseBattleGroundObject()
@@ -19149,6 +19998,159 @@ bool Player::isAllowUseBattleGroundObject()
);
}
+uint32 Player::GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair)
+{
+ uint32 level = getLevel();
+
+ if(level > GT_MAX_LEVEL)
+ level = GT_MAX_LEVEL; // max level in this dbc
+
+ uint8 hairstyle = GetByteValue(PLAYER_BYTES, 2);
+ uint8 haircolor = GetByteValue(PLAYER_BYTES, 3);
+ uint8 facialhair = GetByteValue(PLAYER_BYTES_2, 0);
+
+ if((hairstyle == newhairstyle) && (haircolor == newhaircolor) && (facialhair == newfacialhair))
+ return 0;
+
+ GtBarberShopCostBaseEntry const *bsc = sGtBarberShopCostBaseStore.LookupEntry(level - 1);
+
+ if(!bsc) // shouldn't happen
+ return 0xFFFFFFFF;
+
+ float cost = 0;
+
+ if(hairstyle != newhairstyle)
+ cost += bsc->cost; // full price
+
+ if((haircolor != newhaircolor) && (hairstyle == newhairstyle))
+ cost += bsc->cost * 0.5f; // +1/2 of price
+
+ if(facialhair != newfacialhair)
+ cost += bsc->cost * 0.75f; // +3/4 of price
+
+ return uint32(cost);
+}
+
+void Player::InitGlyphsForLevel()
+{
+ for(uint32 i = 0; i < sGlyphSlotStore.GetNumRows(); ++i)
+ if(GlyphSlotEntry const * gs = sGlyphSlotStore.LookupEntry(i))
+ if(gs->Order)
+ SetGlyphSlot(gs->Order - 1, gs->Id);
+
+ uint32 level = getLevel();
+ uint32 value = 0;
+
+ // 0x3F = 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 for 80 level
+ if(level >= 15)
+ value |= (0x01 | 0x02);
+ if(level >= 30)
+ value |= 0x08;
+ if(level >= 50)
+ value |= 0x04;
+ if(level >= 70)
+ value |= 0x10;
+ if(level >= 80)
+ value |= 0x20;
+
+ SetUInt32Value(PLAYER_GLYPHS_ENABLED, value);
+}
+
+void Player::EnterVehicle(Vehicle *vehicle)
+{
+ VehicleEntry const *ve = sVehicleStore.LookupEntry(vehicle->GetVehicleId());
+ if(!ve)
+ return;
+
+ VehicleSeatEntry const *veSeat = sVehicleSeatStore.LookupEntry(ve->m_seatID[0]);
+ if(!veSeat)
+ return;
+
+ vehicle->SetCharmerGUID(GetGUID());
+ vehicle->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+ vehicle->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
+ vehicle->setFaction(getFaction());
+
+ SetCharm(vehicle); // charm
+ SetMover(vehicle);
+ SetFarSightGUID(vehicle->GetGUID()); // set view
+
+ SetClientControl(vehicle, 1); // redirect controls to vehicle
+
+ WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0);
+ GetSession()->SendPacket(&data);
+
+ data.Initialize(MSG_MOVE_TELEPORT_ACK, 30);
+ data.append(GetPackGUID());
+ data << uint32(0); // counter?
+ data << uint32(MOVEMENTFLAG_ONTRANSPORT); // transport
+ data << uint16(0); // special flags
+ data << uint32(getMSTime()); // time
+ data << vehicle->GetPositionX(); // x
+ data << vehicle->GetPositionY(); // y
+ data << vehicle->GetPositionZ(); // z
+ data << vehicle->GetOrientation(); // o
+ // transport part, TODO: load/calculate seat offsets
+ data << uint64(vehicle->GetGUID()); // transport guid
+ data << float(veSeat->m_attachmentOffsetX); // transport offsetX
+ data << float(veSeat->m_attachmentOffsetY); // transport offsetY
+ data << float(veSeat->m_attachmentOffsetZ); // transport offsetZ
+ data << float(0); // transport orientation
+ data << uint32(getMSTime()); // transport time
+ data << uint8(0); // seat
+ // end of transport part
+ data << uint32(0); // fall time
+ GetSession()->SendPacket(&data);
+
+ data.Initialize(SMSG_PET_SPELLS, 8+4+4+4+4*10+1+1);
+ data << uint64(vehicle->GetGUID());
+ data << uint32(0x00000000);
+ data << uint32(0x00000000);
+ data << uint32(0x00000101);
+
+ for(uint32 i = 0; i < 10; ++i)
+ data << uint16(0) << uint8(0) << uint8(i+8);
+
+ data << uint8(0);
+ data << uint8(0);
+ GetSession()->SendPacket(&data);
+}
+
+void Player::ExitVehicle(Vehicle *vehicle)
+{
+ vehicle->SetCharmerGUID(0);
+ vehicle->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+ vehicle->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
+ vehicle->setFaction((GetTeam() == ALLIANCE) ? vehicle->GetCreatureInfo()->faction_A : vehicle->GetCreatureInfo()->faction_H);
+
+ SetCharm(NULL);
+ SetMover(NULL);
+ SetFarSightGUID(0);
+
+ SetClientControl(vehicle, 0);
+
+ WorldPacket data(MSG_MOVE_TELEPORT_ACK, 30);
+ data.append(GetPackGUID());
+ data << uint32(0); // counter?
+ data << uint32(MOVEMENTFLAG_FLY_UNK1); // fly unk
+ data << uint16(0x40); // special flags
+ data << uint32(getMSTime()); // time
+ data << vehicle->GetPositionX(); // x
+ data << vehicle->GetPositionY(); // y
+ data << vehicle->GetPositionZ(); // z
+ data << vehicle->GetOrientation(); // o
+ data << uint32(0); // fall time
+ GetSession()->SendPacket(&data);
+
+ data.Initialize(SMSG_PET_SPELLS, 8+4);
+ data << uint64(0);
+ data << uint32(0);
+ GetSession()->SendPacket(&data);
+
+ // only for flyable vehicles?
+ CastSpell(this, 45472, true); // Parachute
+}
+
bool Player::HasTitle(uint32 bitIndex)
{
if (bitIndex > 128)
@@ -19166,7 +20168,6 @@ void Player::SetTitle(CharTitlesEntry const* title)
SetFlag(PLAYER__FIELD_KNOWN_TITLES+fieldIndexOffset, flag);
}
-
/*-----------------------TRINITY--------------------------*/
bool Player::isTotalImmunity()
{
@@ -19223,3 +20224,207 @@ void Player::UpdateCharmedAI()
Attack(target, true);
}
}
+
+void Player::ConvertRune(uint8 index, uint8 newType)
+{
+ SetCurrentRune(index, newType);
+
+ WorldPacket data(SMSG_CONVERT_RUNE, 2);
+ data << uint8(index);
+ data << uint8(newType);
+ GetSession()->SendPacket(&data);
+}
+
+void Player::ResyncRunes(uint8 count)
+{
+ WorldPacket data(SMSG_RESYNC_RUNES, count * 2);
+ for(uint32 i = 0; i < count; ++i)
+ {
+ data << uint8(GetCurrentRune(i)); // rune type
+ data << uint8(255 - (GetRuneCooldown(i) * 51)); // passed cooldown time (0-255)
+ }
+ GetSession()->SendPacket(&data);
+}
+
+void Player::AddRunePower(uint8 index)
+{
+ WorldPacket data(SMSG_ADD_RUNE_POWER, 4);
+ data << uint32(1 << index); // mask (0x00-0x3F probably)
+ GetSession()->SendPacket(&data);
+}
+
+void Player::InitRunes()
+{
+ if(getClass() != CLASS_DEATH_KNIGHT)
+ return;
+
+ m_runes = new Runes;
+
+ m_runes->runeState = 0;
+
+ for(uint32 i = 0; i < MAX_RUNES; ++i)
+ {
+ SetBaseRune(i, i / 2); // init base types
+ SetCurrentRune(i, i / 2); // init current types
+ SetRuneCooldown(i, 0); // reset cooldowns
+ m_runes->SetRuneState(i);
+ }
+
+ for(uint32 i = 0; i < NUM_RUNE_TYPES; ++i)
+ SetFloatValue(PLAYER_RUNE_REGEN_1 + i, 0.1f);
+}
+
+void Player::AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore const& store, bool broadcast)
+{
+ Loot loot;
+ loot.FillLoot (loot_id,store,this,true);
+
+ uint32 max_slot = loot.GetMaxSlotInLootFor(this);
+ for(uint32 i = 0; i < max_slot; ++i)
+ {
+ LootItem* lootItem = loot.LootItemInSlot(i,this);
+
+ ItemPosCountVec dest;
+ uint8 msg = CanStoreNewItem (bag,slot,dest,lootItem->itemid,lootItem->count);
+ if(msg != EQUIP_ERR_OK && slot != NULL_SLOT)
+ msg = CanStoreNewItem( bag, NULL_SLOT,dest,lootItem->itemid,lootItem->count);
+ if( msg != EQUIP_ERR_OK && bag != NULL_BAG)
+ msg = CanStoreNewItem( NULL_BAG, NULL_SLOT,dest,lootItem->itemid,lootItem->count);
+ if(msg != EQUIP_ERR_OK)
+ {
+ SendEquipError( msg, NULL, NULL );
+ continue;
+ }
+
+ Item* pItem = StoreNewItem (dest,lootItem->itemid,true,lootItem->randomPropertyId);
+ SendNewItem(pItem, lootItem->count, false, false, broadcast);
+ }
+}
+
+uint32 Player::CalculateTalentsPoints() const
+{
+ uint32 base_talent = getLevel() < 10 ? 0 : uint32((getLevel()-9)*sWorld.getRate(RATE_TALENT));
+
+ if(getClass() != CLASS_DEATH_KNIGHT)
+ return base_talent;
+
+ uint32 talentPointsForLevel =
+ (getLevel() < 56 ? 0 : uint32((getLevel()-55)*sWorld.getRate(RATE_TALENT)))
+ + m_questRewardTalentCount;
+
+ if(talentPointsForLevel > base_talent)
+ talentPointsForLevel = base_talent;
+
+ return talentPointsForLevel;
+}
+
+bool Player::IsAllowUseFlyMountsHere() const
+{
+ if (isGameMaster())
+ return true;
+
+ switch(GetVirtualMapForMapAndZone(GetMapId(), GetZoneId()))
+ {
+ case 0:
+ case 1:
+ //if (!sWorld.getConfig(CONFIG_FLYING_MOUNTS_AZEROTH))
+ return false;
+ break;
+ case 530:
+ //if (!sWorld.getConfig(CONFIG_FLYING_MOUNTS_OUTLAND))
+ return false;
+ break;
+ case 571:
+ if(!HasSpell(54197))
+ return false;
+ break;
+ default:
+ //if (!sWorld.getConfig(CONFIG_FLYING_MOUNTS_OTHERS))
+ return false;
+ break;
+ }
+ return true;
+}
+
+void Player::learnSpellHighRank(uint32 spellid)
+{
+ learnSpell(spellid,false);
+
+ if(uint32 next = spellmgr.GetNextSpellInChain(spellid))
+ learnSpellHighRank(next);
+}
+
+void Player::_LoadSkills()
+{
+ // Note: skill data itself loaded from `data` field. This is only cleanup part of load
+
+ // reset skill modifiers and set correct unlearn flags
+ for (uint32 i = 0; i < PLAYER_MAX_SKILLS; i++)
+ {
+ SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i),0);
+
+ // set correct unlearn bit
+ uint32 id = GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF;
+ if(!id) continue;
+
+ SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(id);
+ if(!pSkill) continue;
+
+ // enable unlearn button for primary professions only
+ if (pSkill->categoryId == SKILL_CATEGORY_PROFESSION)
+ SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id,1));
+ else
+ SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id,0));
+
+ uint32 vskill = SKILL_VALUE(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i)));
+
+ learnSkillRewardedSpells(id, vskill);
+ }
+
+ // special settings
+ if(getClass()==CLASS_DEATH_KNIGHT)
+ {
+ uint32 base_level = std::min(getLevel(),sWorld.getConfig (CONFIG_START_HEROIC_PLAYER_LEVEL));
+ if(base_level < 1)
+ base_level = 1;
+ uint32 base_skill = (base_level-1)*5; // 270 at starting level 55
+ if(base_skill < 1)
+ base_skill = 1; // skill mast be known and then > 0 in any case
+
+ if(GetPureSkillValue (SKILL_FIRST_AID) < base_skill)
+ SetSkill(SKILL_FIRST_AID,base_skill, base_skill);
+ if(GetPureSkillValue (SKILL_AXES) < base_skill)
+ SetSkill(SKILL_AXES, base_skill,base_skill);
+ if(GetPureSkillValue (SKILL_DEFENSE) < base_skill)
+ SetSkill(SKILL_DEFENSE, base_skill,base_skill);
+ if(GetPureSkillValue (SKILL_POLEARMS) < base_skill)
+ SetSkill(SKILL_POLEARMS, base_skill,base_skill);
+ if(GetPureSkillValue (SKILL_SWORDS) < base_skill)
+ SetSkill(SKILL_SWORDS, base_skill,base_skill);
+ if(GetPureSkillValue (SKILL_2H_AXES) < base_skill)
+ SetSkill(SKILL_2H_AXES, base_skill,base_skill);
+ if(GetPureSkillValue (SKILL_2H_SWORDS) < base_skill)
+ SetSkill(SKILL_2H_SWORDS, base_skill,base_skill);
+ if(GetPureSkillValue (SKILL_UNARMED) < base_skill)
+ SetSkill(SKILL_UNARMED, base_skill,base_skill);
+ }
+}
+
+uint32 Player::GetPhaseMaskForSpawn() const
+{
+ uint32 phase = PHASEMASK_NORMAL;
+ if(!isGameMaster())
+ phase = GetPhaseMask();
+ else
+ {
+ AuraList const& phases = GetAurasByType(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;
+}
diff --git a/src/game/Player.h b/src/game/Player.h
index a149e559a3a..7d634b997ee 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -35,6 +35,7 @@
#include "Pet.h"
#include "MapReference.h"
#include "Util.h" // for Tokens typedef
+#include "AchievementMgr.h"
#include<string>
#include<vector>
@@ -47,8 +48,11 @@ class Pet;
class PlayerMenu;
class Transport;
class UpdateMask;
+class SpellCastTargets;
class PlayerSocial;
class OutdoorPvP;
+class AchievementMgr;
+class Vehicle;
typedef std::deque<Mail*> PlayerMails;
@@ -62,6 +66,17 @@ enum SpellModType
SPELLMOD_PCT = 108 // SPELL_AURA_ADD_PCT_MODIFIER
};
+// 2^n values, Player::m_isunderwater is a bitmask. These are mangos internal values, they are never send to any client
+enum PlayerUnderwaterState
+{
+ UNDERWATER_NONE = 0x00,
+ UNDERWATER_INWATER = 0x01, // terrain type is water and player is afflicted by it
+ UNDERWATER_WATER_TRIGGER = 0x02, // m_breathTimer has been initialized
+ UNDERWATER_WATER_BREATHB = 0x04, // breathbar has been send to client
+ UNDERWATER_WATER_BREATHB_RETRACTING = 0x10, // breathbar is currently refilling - the player is above water level
+ UNDERWATER_INLAVA = 0x80 // terrain type is lava and player is afflicted by it
+};
+
enum PlayerSpellState
{
PLAYERSPELL_UNCHANGED = 0,
@@ -72,27 +87,26 @@ enum PlayerSpellState
struct PlayerSpell
{
- uint16 slotId : 16;
PlayerSpellState state : 8;
- bool active : 1;
- bool disabled : 1;
+ bool active : 1; // show in spellbook
+ bool dependent : 1; // learned as result another spell learn, skill grow, quest reward, etc
+ bool disabled : 1; // first rank has been learned in result talent learn but currently talent unlearned, save max learned ranks
};
-#define SPELL_WITHOUT_SLOT_ID uint16(-1)
-
+// Spell modifier (used for modify other spells)
struct SpellModifier
{
+ SpellModifier() : charges(0), lastAffected(NULL) {}
SpellModOp op : 8;
SpellModType type : 8;
int16 charges : 16;
int32 value;
- uint64 mask;
+ flag96 mask;
uint32 spellId;
- uint32 effectId;
Spell const* lastAffected;
};
-typedef UNORDERED_MAP<uint16, PlayerSpell*> PlayerSpellMap;
+typedef UNORDERED_MAP<uint32, PlayerSpell*> PlayerSpellMap;
typedef std::list<SpellModifier*> SpellModList;
struct SpellCooldown
@@ -141,8 +155,6 @@ enum ActionButtonType
typedef std::map<uint8,ActionButton> ActionButtonList;
-typedef std::pair<uint16, uint8> CreateSpellPair;
-
struct PlayerCreateInfoItem
{
PlayerCreateInfoItem(uint32 id, uint32 amount) : item_id(id), item_amount(amount) {}
@@ -174,6 +186,8 @@ struct PlayerLevelInfo
uint8 stats[MAX_STATS];
};
+typedef std::list<uint32> PlayerCreateInfoSpells;
+
struct PlayerInfo
{
// existence checked by displayId != 0 // existence checked by displayId != 0
@@ -189,7 +203,7 @@ struct PlayerInfo
uint16 displayId_m;
uint16 displayId_f;
PlayerCreateInfoItems item;
- std::list<CreateSpellPair> spell;
+ PlayerCreateInfoSpells spell;
std::list<uint16> action[4];
PlayerLevelInfo* levelInfo; //[level-1] 0..MaxPlayerLevel-1
@@ -224,6 +238,39 @@ struct Areas
float y2;
};
+#define MAX_RUNES 6
+#define RUNE_COOLDOWN 5 // 5*2=10 sec
+
+enum RuneType
+{
+ RUNE_BLOOD = 0,
+ RUNE_UNHOLY = 1,
+ RUNE_FROST = 2,
+ RUNE_DEATH = 3,
+ NUM_RUNE_TYPES = 4
+};
+
+struct RuneInfo
+{
+ uint8 BaseRune;
+ uint8 CurrentRune;
+ uint8 Cooldown;
+};
+
+struct Runes
+{
+ RuneInfo runes[MAX_RUNES];
+ uint8 runeState; // mask of available runes
+
+ void SetRuneState(uint8 index, bool set = true)
+ {
+ if(set)
+ runeState |= (1 << index); // usable
+ else
+ runeState &= ~(1 << index); // on cooldown
+ }
+};
+
enum FactionFlags
{
FACTION_FLAG_VISIBLE = 0x01, // makes visible in client (set or can be set at interaction with target of this faction)
@@ -328,52 +375,6 @@ enum DrunkenState
DRUNKEN_SMASHED = 3
};
-enum PlayerStateType
-{
- /*
- PLAYER_STATE_DANCE
- PLAYER_STATE_SLEEP
- PLAYER_STATE_SIT
- PLAYER_STATE_STAND
- PLAYER_STATE_READYUNARMED
- PLAYER_STATE_WORK
- PLAYER_STATE_POINT(DNR)
- PLAYER_STATE_NONE // not used or just no state, just standing there?
- PLAYER_STATE_STUN
- PLAYER_STATE_DEAD
- PLAYER_STATE_KNEEL
- PLAYER_STATE_USESTANDING
- PLAYER_STATE_STUN_NOSHEATHE
- PLAYER_STATE_USESTANDING_NOSHEATHE
- PLAYER_STATE_WORK_NOSHEATHE
- PLAYER_STATE_SPELLPRECAST
- PLAYER_STATE_READYRIFLE
- PLAYER_STATE_WORK_NOSHEATHE_MINING
- PLAYER_STATE_WORK_NOSHEATHE_CHOPWOOD
- PLAYER_STATE_AT_EASE
- PLAYER_STATE_READY1H
- PLAYER_STATE_SPELLKNEELSTART
- PLAYER_STATE_SUBMERGED
- */
-
- PLAYER_STATE_NONE = 0,
- PLAYER_STATE_SIT = 1,
- PLAYER_STATE_SIT_CHAIR = 2,
- PLAYER_STATE_SLEEP = 3,
- PLAYER_STATE_SIT_LOW_CHAIR = 4,
- PLAYER_STATE_SIT_MEDIUM_CHAIR = 5,
- PLAYER_STATE_SIT_HIGH_CHAIR = 6,
- PLAYER_STATE_DEAD = 7,
- PLAYER_STATE_KNEEL = 8,
-
- PLAYER_STATE_FORM_ALL = 0x00FF0000,
-
- PLAYER_STATE_FLAG_ALWAYS_STAND = 0x01, // byte 4
- PLAYER_STATE_FLAG_CREEP = 0x02000000,
- PLAYER_STATE_FLAG_UNTRACKABLE = 0x04000000,
- PLAYER_STATE_FLAG_ALL = 0xFF000000,
-};
-
enum PlayerFlags
{
PLAYER_FLAGS_GROUP_LEADER = 0x00000001,
@@ -382,17 +383,25 @@ enum PlayerFlags
PLAYER_FLAGS_GM = 0x00000008,
PLAYER_FLAGS_GHOST = 0x00000010,
PLAYER_FLAGS_RESTING = 0x00000020,
- PLAYER_FLAGS_FFA_PVP = 0x00000080,
+ PLAYER_FLAGS_UNK7 = 0x00000040,
+ PLAYER_FLAGS_UNK8 = 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_UNK1 = 0x00001000, // played long time
- PLAYER_FLAGS_UNK2 = 0x00002000, // played too long time
- PLAYER_FLAGS_UNK3 = 0x00008000, // strange visual effect (2.0.1), looks like PLAYER_FLAGS_GHOST flag
- PLAYER_FLAGS_SANCTUARY = 0x00010000, // player entered sanctuary
- PLAYER_FLAGS_UNK4 = 0x00020000, // taxi benchmark mode (on/off) (2.0.1)
- PLAYER_UNK = 0x00040000, // 2.0.8...
+ PLAYER_FLAGS_UNK13 = 0x00001000, // played long time
+ PLAYER_FLAGS_UNK14 = 0x00002000, // played too long time
+ PLAYER_FLAGS_UNK15 = 0x00004000,
+ PLAYER_FLAGS_UNK16 = 0x00008000, // strange visual effect (2.0.1), looks like PLAYER_FLAGS_GHOST flag
+ PLAYER_FLAGS_UNK17 = 0x00010000, // pre-3.0.3 PLAYER_FLAGS_SANCTUARY flag for player entered sanctuary
+ PLAYER_FLAGS_UNK18 = 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_UNK20 = 0x00080000,
+ PLAYER_FLAGS_UNK21 = 0x00100000,
+ PLAYER_FLAGS_UNK22 = 0x00200000,
+ PLAYER_FLAGS_UNK23 = 0x00400000,
+ PLAYER_ALLOW_ONLY_ABILITY = 0x00800000, // used by bladestorm and killing spree
+ PLAYER_FLAGS_UNK25 = 0x01000000 // disabled all melee ability on tab include autoattack
};
// used for PLAYER__FIELD_KNOWN_TITLES field (uint64), (1<<bit_index) without (-1)
@@ -481,7 +490,8 @@ enum LootType
LOOT_DISENCHANTING = 5, // unsupported by client, sending LOOT_SKINNING instead
LOOT_PROSPECTING = 6, // unsupported by client, sending LOOT_SKINNING instead
LOOT_INSIGNIA = 7, // unsupported by client, sending LOOT_SKINNING instead
- LOOT_FISHINGHOLE = 8 // unsupported by client, sending LOOT_FISHING instead
+ LOOT_FISHINGHOLE = 8, // unsupported by client, sending LOOT_FISHING instead
+ LOOT_MILLING = 9 // unsupported by client, sending LOOT_SKINNING instead
};
enum MirrorTimerType
@@ -511,7 +521,8 @@ enum AtLoginFlags
AT_LOGIN_NONE = 0,
AT_LOGIN_RENAME = 1,
AT_LOGIN_RESET_SPELLS = 2,
- AT_LOGIN_RESET_TALENTS = 4
+ AT_LOGIN_RESET_TALENTS = 4,
+ AT_LOGIN_CUSTOMIZE = 8
};
typedef std::map<uint32, QuestStatusData> QuestStatusMap;
@@ -543,7 +554,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 = 118,
+ PLAYER_SLOT_END = 200,
PLAYER_SLOTS_COUNT = (PLAYER_SLOT_END - PLAYER_SLOT_START)
};
@@ -671,12 +682,30 @@ enum KeyRingSlots
KEYRING_SLOT_END = 118
};
+enum VanityPetSlots
+{
+ VANITYPET_SLOT_START = 118, // not use, vanity pets stored as spells
+ VANITYPET_SLOT_END = 136 // not alloed any content in.
+};
+
+enum CurrencyTokenSlots
+{
+ CURRENCYTOKEN_SLOT_START = 136,
+ CURRENCYTOKEN_SLOT_END = 168
+};
+
+enum QuestBagSlots
+{
+ QUESTBAG_SLOT_START = 168,
+ QUESTBAG_SLOT_END = 200
+};
+
struct ItemPosCount
{
- ItemPosCount(uint16 _pos, uint8 _count) : pos(_pos), count(_count) {}
+ ItemPosCount(uint16 _pos, uint32 _count) : pos(_pos), count(_count) {}
bool isContainedIn(std::vector<ItemPosCount> const& vec) const;
uint16 pos;
- uint8 count;
+ uint32 count;
};
typedef std::vector<ItemPosCount> ItemPosCountVec;
@@ -689,14 +718,15 @@ enum TradeSlots
enum TransferAbortReason
{
- TRANSFER_ABORT_MAX_PLAYERS = 0x0001, // Transfer Aborted: instance is full
- TRANSFER_ABORT_NOT_FOUND = 0x0002, // Transfer Aborted: instance not found
- TRANSFER_ABORT_TOO_MANY_INSTANCES = 0x0003, // You have entered too many instances recently.
- TRANSFER_ABORT_ZONE_IN_COMBAT = 0x0005, // Unable to zone in while an encounter is in progress.
- TRANSFER_ABORT_INSUF_EXPAN_LVL1 = 0x0106, // You must have TBC expansion installed to access this area.
- TRANSFER_ABORT_DIFFICULTY1 = 0x0007, // Normal difficulty mode is not available for %s.
- TRANSFER_ABORT_DIFFICULTY2 = 0x0107, // Heroic difficulty mode is not available for %s.
- TRANSFER_ABORT_DIFFICULTY3 = 0x0207 // Epic difficulty mode is not available for %s.
+ TRANSFER_ABORT_ERROR = 0x00,
+ TRANSFER_ABORT_MAX_PLAYERS = 0x01, // Transfer Aborted: instance is full
+ TRANSFER_ABORT_NOT_FOUND = 0x02, // Transfer Aborted: instance not found
+ TRANSFER_ABORT_TOO_MANY_INSTANCES = 0x03, // You have entered too many instances recently.
+ TRANSFER_ABORT_ZONE_IN_COMBAT = 0x05, // Unable to zone in while an encounter is in progress.
+ TRANSFER_ABORT_INSUF_EXPAN_LVL = 0x06, // You must have <TBC,WotLK> expansion installed to access this area.
+ TRANSFER_ABORT_DIFFICULTY = 0x07, // <Normal,Heroic,Epic> difficulty mode is not available for %s.
+ TRANSFER_ABORT_UNIQUE_MESSAGE = 0x08, // Until you've escaped TLK's grasp, you cannot leave this place!
+ TRANSFER_ABORT_TOO_MANY_REALM_INSTANCES = 0x09 // Additional instances cannot be launched, please try again later.
};
enum InstanceResetWarningType
@@ -710,15 +740,16 @@ enum InstanceResetWarningType
struct MovementInfo
{
// common
- //uint32 flags;
- uint8 unk1;
+ uint32 flags;
+ uint16 unk1;
uint32 time;
float x, y, z, o;
// transport
uint64 t_guid;
float t_x, t_y, t_z, t_o;
uint32 t_time;
- // swimming and unk
+ int8 t_seat;
+ // swimming and unknown
float s_pitch;
// last fall time
uint32 fallTime;
@@ -729,17 +760,17 @@ struct MovementInfo
MovementInfo()
{
- //flags =
+ flags = 0;
time = t_time = fallTime = 0;
unk1 = 0;
x = y = z = o = t_x = t_y = t_z = t_o = s_pitch = j_unk = j_sinAngle = j_cosAngle = j_xyspeed = u_unk1 = 0.0f;
t_guid = 0;
}
- /*void SetMovementFlags(uint32 _flags)
+ void SetMovementFlags(uint32 _flags)
{
flags = _flags;
- }*/
+ }
};
// flags that use in movement check for example at spell casting
@@ -812,10 +843,12 @@ enum PlayerLoginQueryIndex
PLAYER_LOGIN_QUERY_LOADDECLINEDNAMES = 16,
PLAYER_LOGIN_QUERY_LOADGUILD = 17,
PLAYER_LOGIN_QUERY_LOADARENAINFO = 18,
-
- MAX_PLAYER_LOGIN_QUERY
+ PLAYER_LOGIN_QUERY_LOADACHIEVEMENTS = 19,
+ PLAYER_LOGIN_QUERY_LOADCRITERIAPROGRESS = 20,
+ MAX_PLAYER_LOGIN_QUERY = 21
};
+
// Player summoning auto-decline time (in secs)
#define MAX_PLAYER_SUMMON_DELAY (2*MINUTE)
#define MAX_MONEY_AMOUNT (0x7FFFFFFF-1)
@@ -836,11 +869,9 @@ class TRINITY_DLL_SPEC PlayerTaxi
PlayerTaxi();
~PlayerTaxi() {}
// Nodes
- void InitTaxiNodesForLevel(uint32 race, uint32 level);
+ void InitTaxiNodesForLevel(uint32 race, uint32 chrClass, uint32 level);
void LoadTaxiMask(const char* data);
- void SaveTaxiMask(const char* data);
- uint32 GetTaximask( uint8 index ) const { return m_taximask[index]; }
bool IsTaximaskNodeKnown(uint32 nodeidx) const
{
uint8 field = uint8((nodeidx - 1) / 32);
@@ -862,7 +893,7 @@ class TRINITY_DLL_SPEC PlayerTaxi
void AppendTaximaskTo(ByteBuffer& data,bool all);
// Destinations
- bool LoadTaxiDestinationsFromString(const std::string& values);
+ bool LoadTaxiDestinationsFromString(const std::string& values, uint32 team);
std::string SaveTaxiDestinationsToString();
void ClearTaxiDestinations() { m_TaxiDestinations.clear(); }
@@ -876,11 +907,15 @@ class TRINITY_DLL_SPEC PlayerTaxi
return GetTaxiDestination();
}
bool empty() const { return m_TaxiDestinations.empty(); }
+
+ friend std::ostringstream& operator<< (std::ostringstream& ss, PlayerTaxi const& taxi);
private:
TaxiMask m_taximask;
std::deque<uint32> m_TaxiDestinations;
};
+std::ostringstream& operator<< (std::ostringstream& ss, PlayerTaxi const& taxi);
+
class TRINITY_DLL_SPEC Player : public Unit
{
friend class WorldSession;
@@ -898,23 +933,6 @@ class TRINITY_DLL_SPEC Player : public Unit
void AddToWorld();
void RemoveFromWorld();
- void SetViewport(uint64 guid, bool movable);
- void RemovePossess(bool attack = true);
- void StopCharmOrPossess()
- {
- if(isPossessing())
- RemovePossess(true);
- else if(GetCharm())
- Uncharm();
- }
- WorldObject* GetFarsightTarget() const;
- void ClearFarsight();
- void RemoveFarsightTarget();
- void SetFarsightTarget(WorldObject* target);
- // Controls if vision is currently on farsight object, updated in FAR_SIGHT opcode
- void SetFarsightVision(bool apply) { m_farsightVision = apply; }
- bool HasFarsightVision() const { return m_farsightVision; }
-
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options = 0);
bool TeleportTo(WorldLocation const &loc, uint32 options = 0)
@@ -945,7 +963,7 @@ class TRINITY_DLL_SPEC Player : public Unit
void SendInitialPacketsBeforeAddToMap();
void SendInitialPacketsAfterAddToMap();
- void SendTransferAborted(uint32 mapid, uint16 reason);
+ void SendTransferAborted(uint32 mapid, uint8 reason, uint8 arg = 0);
void SendInstanceResetWarning(uint32 mapid, uint32 time);
bool CanInteractWithNPCs(bool alive = true) const;
@@ -958,10 +976,12 @@ class TRINITY_DLL_SPEC Player : public Unit
std::string afkMsg;
std::string dndMsg;
+ uint32 GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair);
+
PlayerSocial *GetSocial() { return m_social; }
PlayerTaxi m_taxi;
- void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(getRace(),getLevel()); }
+ void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(getRace(), getClass(), getLevel()); }
bool ActivateTaxiPathTo(std::vector<uint32> const& nodes, uint32 mount_id = 0 , Creature* npc = NULL);
// mount_id can be used in scripting calls
bool isAcceptWhispers() const { return m_ExtraFlags & PLAYER_EXTRA_ACCEPT_WHISPERS; }
@@ -1021,6 +1041,7 @@ class TRINITY_DLL_SPEC Player : public Unit
void AddGuardian(Pet* pet) { m_guardianPets.insert(pet->GetGUID()); }
GuardianPetList const& GetGuardians() const { return m_guardianPets; }
void Uncharm();
+ uint32 GetPhaseMaskForSpawn() const; // used for proper set phase for DB at GM-mode creature/GO spawn
void Say(const std::string& text, const uint32 language);
void Yell(const std::string& text, const uint32 language);
@@ -1039,9 +1060,15 @@ class TRINITY_DLL_SPEC Player : public Unit
Item* GetItemByGuid( uint64 guid ) const;
Item* GetItemByPos( uint16 pos ) const;
Item* GetItemByPos( uint8 bag, uint8 slot ) const;
+ inline Item* GetUseableItemByPos( uint8 bag, uint8 slot ) const //Does additional check for disarmed weapons
+ {
+ if (!CanUseAttackType(GetAttackBySlot(slot)))
+ return NULL;
+ return GetItemByPos(bag, slot);
+ }
Item* GetWeaponForAttack(WeaponAttackType attackType, bool useable = false) const;
Item* GetShield(bool useable = false) const;
- static uint32 GetAttackBySlot( uint8 slot ); // MAX_ATTACK if not weapon slot
+ static uint8 GetAttackBySlot( uint8 slot ); // MAX_ATTACK if not weapon slot
std::vector<Item *> &GetItemUpdateQueue() { return m_itemUpdateQueue; }
static bool IsInventoryPos( uint16 pos ) { return IsInventoryPos(pos >> 8,pos & 255); }
static bool IsInventoryPos( uint8 bag, uint8 slot );
@@ -1055,6 +1082,7 @@ class TRINITY_DLL_SPEC Player : public Unit
bool HasBankBagSlot( uint8 slot ) const;
bool HasItemCount( uint32 item, uint32 count, bool inBankAlso = false ) const;
bool HasItemFitToSpellReqirements(SpellEntry const* spellInfo, Item const* ignoreItem = NULL);
+ bool CanNoReagentCast(SpellEntry const* spellInfo) const;
Item* GetItemOrItemWithGemEquipped( uint32 item ) const;
uint8 CanTakeMoreSimilarItems(Item* pItem) const { return _CanTakeMoreSimilarItems(pItem->GetEntry(),pItem->GetCount(),pItem); }
uint8 CanTakeMoreSimilarItems(uint32 entry, uint32 count) const { return _CanTakeMoreSimilarItems(entry,count,NULL); }
@@ -1086,6 +1114,8 @@ class TRINITY_DLL_SPEC Player : public Unit
Item* EquipItem( uint16 pos, Item *pItem, bool update );
void AutoUnequipOffhandIfNeed();
bool StoreNewItemInBestSlots(uint32 item_id, uint32 item_count);
+ void AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore const& store, bool broadcast = false);
+ void AutoStoreLoot(uint32 loot_id, LootStore const& store, bool broadcast = false) { AutoStoreLoot(NULL_BAG,NULL_SLOT,loot_id,store,broadcast); }
uint8 _CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count = NULL) const;
uint8 _CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 entry, uint32 count, Item *pItem = NULL, bool swap = false, uint32* no_space_count = NULL ) const;
@@ -1128,10 +1158,10 @@ class TRINITY_DLL_SPEC Player : public Unit
uint32 GetWeaponProficiency() const { return m_WeaponProficiency; }
uint32 GetArmorProficiency() const { return m_ArmorProficiency; }
bool IsInFeralForm() const { return m_form == FORM_CAT || m_form == FORM_BEAR || m_form == FORM_DIREBEAR; }
- bool IsUseEquipedWeapon( bool mainhand ) const
+ bool IsTwoHandUsed() const
{
- // disarm applied only to mainhand weapon
- return !IsInFeralForm() && (!mainhand || !HasFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISARMED) );
+ Item* mainItem = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
+ return mainItem && mainItem->GetProto()->InventoryType == INVTYPE_2HWEAPON && !CanTitanGrip();
}
void SendNewItem( Item *item, uint32 count, bool received, bool created, bool broadcast = false );
bool BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint64 bagguid, uint8 slot);
@@ -1230,7 +1260,6 @@ class TRINITY_DLL_SPEC Player : public Unit
}
}
uint32 GetReqKillOrCastCurrentCount(uint32 quest_id, int32 entry);
- void AdjustQuestReqItemCount( Quest const* pQuest );
void AreaExploredOrEventHappens( uint32 questId );
void GroupEventHappens( uint32 questId, WorldObject const* pEventObject );
void ItemAddedQuestCheck( uint32 entry, uint32 count );
@@ -1267,6 +1296,7 @@ class TRINITY_DLL_SPEC Player : public Unit
/*********************************************************/
bool LoadFromDB(uint32 guid, SqlQueryHolder *holder);
+
bool MinimalLoadFromDB(QueryResult *result, uint32 guid);
static bool LoadValuesArrayFromDB(Tokens& data,uint64 guid);
static uint32 GetUInt32ValueFromArray(Tokens const& data, uint16 index);
@@ -1288,6 +1318,7 @@ class TRINITY_DLL_SPEC Player : public Unit
static void SetFloatValueInArray(Tokens& data,uint16 index, float value);
static void SetUInt32ValueInDB(uint16 index, uint32 value, uint64 guid);
static void SetFloatValueInDB(uint16 index, float value, uint64 guid);
+ static void Customize(uint64 guid, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair);
static void SavePositionInDB(uint32 mapid, float x,float y,float z,float o,uint32 zone,uint64 guid);
bool m_mailsLoaded;
@@ -1344,7 +1375,7 @@ class TRINITY_DLL_SPEC Player : public Unit
void SetSelection(const uint64 &guid) { m_curSelection = guid; SetUInt64Value(UNIT_FIELD_TARGET, guid); }
uint8 GetComboPoints() { return m_comboPoints; }
- uint64 GetComboTarget() { return m_comboTarget; }
+ const uint64& GetComboTarget() const { return m_comboTarget; }
void AddComboPoints(Unit* target, int8 count);
void ClearComboPoints();
@@ -1380,10 +1411,7 @@ class TRINITY_DLL_SPEC Player : public Unit
Item* GetMItem(uint32 id)
{
ItemMap::const_iterator itr = mMitems.find(id);
- if (itr != mMitems.end())
- return itr->second;
-
- return NULL;
+ return itr != mMitems.end() ? itr->second : NULL;
}
void AddMItem(Item* it)
@@ -1395,30 +1423,28 @@ class TRINITY_DLL_SPEC Player : public Unit
bool RemoveMItem(uint32 id)
{
- ItemMap::iterator i = mMitems.find(id);
- if (i == mMitems.end())
- return false;
-
- mMitems.erase(i);
- return true;
+ return mMitems.erase(id) ? true : false;
}
void PetSpellInitialize();
void CharmSpellInitialize();
void PossessSpellInitialize();
bool HasSpell(uint32 spell) const;
+ bool HasActiveSpell(uint32 spell) const; // show in spellbook
TrainerSpellState GetTrainerSpellState(TrainerSpell const* trainer_spell) const;
bool IsSpellFitByClassAndRace( uint32 spell_id ) const;
+ bool IsNeedCastPassiveSpellAtLearn(SpellEntry const* spellInfo) const;
void SendProficiency(uint8 pr1, uint32 pr2);
void SendInitialSpells();
- bool addSpell(uint32 spell_id, bool active, bool learning = true, bool loading = false, uint16 slot_id=SPELL_WITHOUT_SLOT_ID, bool disabled = false);
- void learnSpell(uint32 spell_id);
- void removeSpell(uint32 spell_id, bool disabled = false);
+ bool addSpell(uint32 spell_id, bool active, bool learning, bool dependent, bool disabled);
+ void learnSpell(uint32 spell_id, bool dependent);
+ void removeSpell(uint32 spell_id, bool disabled = false, bool update_action_bar_for_low_rank = false);
void resetSpells();
- void learnDefaultSpells(bool loading = false);
+ void learnDefaultSpells();
void learnQuestRewardedSpells();
void learnQuestRewardedSpells(Quest const* quest);
+ void learnSpellHighRank(uint32 spellid);
uint32 GetFreeTalentPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS1); }
void SetFreeTalentPoints(uint32 points) { SetUInt32Value(PLAYER_CHARACTER_POINTS1,points); }
@@ -1426,6 +1452,14 @@ class TRINITY_DLL_SPEC Player : public Unit
uint32 resetTalentsCost() const;
void InitTalentForLevel();
+ uint32 CalculateTalentsPoints() const;
+
+ 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); }
+ void SetGlyph(uint8 slot, uint32 glyph) { SetUInt32Value(PLAYER_FIELD_GLYPHS_1 + slot, glyph); }
+ uint32 GetGlyph(uint8 slot) { return GetUInt32Value(PLAYER_FIELD_GLYPHS_1 + slot); }
+
uint32 GetFreePrimaryProffesionPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS2); }
void SetFreePrimaryProffesions(uint16 profs) { SetUInt32Value(PLAYER_CHARACTER_POINTS2,profs); }
void InitPrimaryProffesions();
@@ -1434,8 +1468,6 @@ class TRINITY_DLL_SPEC Player : public Unit
PlayerSpellMap & GetSpellMap() { return m_spells; }
void AddSpellMod(SpellModifier* mod, bool apply);
- int32 GetTotalFlatMods(uint32 spellId, SpellModOp op);
- int32 GetTotalPctMods(uint32 spellId, SpellModOp op);
bool IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mod, Spell const* spell = NULL);
template <class T> T ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell const* spell = NULL);
void RemoveSpellMods(Spell const* spell);
@@ -1540,6 +1572,7 @@ class TRINITY_DLL_SPEC Player : public Unit
static uint32 GetArenaTeamIdFromDB(uint64 guid, uint8 slot);
void SetArenaTeamIdInvited(uint32 ArenaTeamId) { m_ArenaTeamIdInvited = ArenaTeamId; }
uint32 GetArenaTeamIdInvited() { return m_ArenaTeamIdInvited; }
+ static void LeaveAllArenaTeams(uint64 guid);
void SetDifficulty(uint32 dungeon_difficulty) { m_dungeonDifficulty = dungeon_difficulty; }
uint8 GetDifficulty() { return m_dungeonDifficulty; }
@@ -1565,9 +1598,12 @@ class TRINITY_DLL_SPEC Player : public Unit
void UpdateArmor();
void UpdateMaxHealth();
void UpdateMaxPower(Powers power);
+ void ApplyFeralAPBonus(int32 amount, bool apply);
void UpdateAttackPowerAndDamage(bool ranged = false);
void UpdateShieldBlockValue();
void UpdateDamagePhysical(WeaponAttackType attType);
+ void ApplySpellDamageBonus(int32 amount, bool apply);
+ void ApplySpellHealingBonus(int32 amount, bool apply);
void UpdateSpellDamageAndHealingBonus();
void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, float& min_damage, float& max_damage);
@@ -1585,6 +1621,8 @@ class TRINITY_DLL_SPEC Player : public Unit
uint32 GetRangedCritDamageReduction(uint32 damage) const;
uint32 GetSpellCritDamageReduction(uint32 damage) const;
uint32 GetDotDamageReduction(uint32 damage) const;
+ uint32 GetBaseSpellDamageBonus() { return m_baseSpellDamage;}
+ uint32 GetBaseSpellHealingBonus() { return m_baseSpellHealing;}
float GetExpertiseDodgeOrParryReduction(WeaponAttackType attType) const;
void UpdateBlockPercentage();
@@ -1592,9 +1630,14 @@ class TRINITY_DLL_SPEC Player : public Unit
void UpdateAllCritPercentages();
void UpdateParryPercentage();
void UpdateDodgePercentage();
+ void UpdateMeleeHitChances();
+ void UpdateRangedHitChances();
+ void UpdateSpellHitChances();
+
void UpdateAllSpellCritChances();
void UpdateSpellCritChance(uint32 school);
void UpdateExpertise(WeaponAttackType attType);
+ void ApplyManaRegenBonus(int32 amount, bool apply);
void UpdateManaRegen();
const uint64& GetLootGUID() const { return m_lootGuid; }
@@ -1671,18 +1714,18 @@ class TRINITY_DLL_SPEC Player : public Unit
void UpdateDefense();
void UpdateWeaponSkill (WeaponAttackType attType);
- void UpdateCombatSkills(Unit *pVictim, WeaponAttackType attType, MeleeHitOutcome outcome, bool defence);
+ void UpdateCombatSkills(Unit *pVictim, WeaponAttackType attType, bool defence);
void SetSkill(uint32 id, uint16 currVal, uint16 maxVal);
- uint16 GetMaxSkillValue(uint32 skill) const; // max + perm. bonus
+ uint16 GetMaxSkillValue(uint32 skill) const; // max + perm. bonus + temp bonus
uint16 GetPureMaxSkillValue(uint32 skill) const; // max
uint16 GetSkillValue(uint32 skill) const; // skill value + perm. bonus + temp bonus
uint16 GetBaseSkillValue(uint32 skill) const; // skill value + perm. bonus
uint16 GetPureSkillValue(uint32 skill) const; // skill value
+ int16 GetSkillPermBonusValue(uint32 skill) const;
int16 GetSkillTempBonusValue(uint32 skill) const;
bool HasSkill(uint32 skill) const;
- void learnSkillRewardedSpells( uint32 id );
- void learnSkillRewardedSpells();
+ void learnSkillRewardedSpells(uint32 id, uint32 value);
void SetDontMove(bool dontMove);
bool GetDontMove() const { return m_dontMove; }
@@ -1696,6 +1739,7 @@ class TRINITY_DLL_SPEC Player : public Unit
bool IsAtGroupRewardDistance(WorldObject const* pRewardSource) const;
bool RewardPlayerAndGroupAtKill(Unit* pVictim);
+ bool isHonorOrXPTarget(Unit* pVictim);
FactionStateList m_factions;
ForcedReactions m_forcedReactions;
@@ -1762,6 +1806,8 @@ class TRINITY_DLL_SPEC Player : public Unit
void SetCanParry(bool value);
bool CanBlock() const { return m_canBlock; }
void SetCanBlock(bool value);
+ bool CanTitanGrip() const { return m_canTitanGrip ; }
+ void SetCanTitanGrip(bool value) { m_canTitanGrip = value; }
void SetRegularAttackTime();
void SetBaseModValue(BaseModGroup modGroup, BaseModType modType, float value) { m_auraBaseMod[modGroup][modType] = value; }
@@ -1790,12 +1836,13 @@ class TRINITY_DLL_SPEC Player : public Unit
void ApplyEquipSpell(SpellEntry const* spellInfo, Item* item, bool apply, bool form_change = false);
void UpdateEquipSpellsAtFormChange();
void CastItemCombatSpell(Item *item,Unit* Target, WeaponAttackType attType);
+ void CastItemUseSpell(Item *item,SpellCastTargets const& targets,uint8 cast_count, uint32 glyphIndex);
void SendInitWorldStates(bool force = false, uint32 forceZoneId = 0);
void SendUpdateWorldState(uint32 Field, uint32 Value);
void SendDirectMessage(WorldPacket *data);
- void SendAuraDurationsForTarget(Unit* target);
+ void SendAurasForTarget(Unit *target);
PlayerMenu* PlayerTalkClass;
std::vector<ItemSetEffect *> ItemSetEff;
@@ -1892,18 +1939,10 @@ class TRINITY_DLL_SPEC Player : public Unit
return true;
return false;
}
- uint32 GetBattleGroundEntryPointMap() const { return m_bgEntryPointMap; }
- float GetBattleGroundEntryPointX() const { return m_bgEntryPointX; }
- float GetBattleGroundEntryPointY() const { return m_bgEntryPointY; }
- float GetBattleGroundEntryPointZ() const { return m_bgEntryPointZ; }
- float GetBattleGroundEntryPointO() const { return m_bgEntryPointO; }
+ WorldLocation const& GetBattleGroundEntryPoint() const { return m_bgEntryPoint; }
void SetBattleGroundEntryPoint(uint32 Map, float PosX, float PosY, float PosZ, float PosO )
{
- m_bgEntryPointMap = Map;
- m_bgEntryPointX = PosX;
- m_bgEntryPointY = PosY;
- m_bgEntryPointZ = PosZ;
- m_bgEntryPointO = PosO;
+ m_bgEntryPoint = WorldLocation(Map,PosX,PosY,PosZ,PosO);
}
void SetBGTeam(uint32 team) { m_bgTeam = team; }
@@ -1915,7 +1954,7 @@ class TRINITY_DLL_SPEC Player : public Unit
void ReportedAfkBy(Player* reporter);
void ClearAfkReports() { m_bgAfkReporter.clear(); }
- bool GetBGAccessByLevel(uint32 bgTypeId) const;
+ bool GetBGAccessByLevel(BattleGroundTypeId bgTypeId) const;
bool isAllowUseBattleGroundObject();
bool isTotalImmunity();
@@ -1956,6 +1995,7 @@ class TRINITY_DLL_SPEC Player : public Unit
MovementInfo m_movementInfo;
uint32 m_lastFallTime;
float m_lastFallZ;
+ Unit *m_mover;
void SetFallInformation(uint32 time, float z)
{
m_lastFallTime = time;
@@ -1966,6 +2006,7 @@ class TRINITY_DLL_SPEC Player : public Unit
bool CanFly() const { return HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY); }
bool IsFlying() const { return HasUnitMovementFlag(MOVEMENTFLAG_FLYING); }
+ bool IsAllowUseFlyMountsHere() const;
void HandleDrowning();
void HandleFallDamage(MovementInfo& movementInfo);
@@ -1973,8 +2014,30 @@ class TRINITY_DLL_SPEC Player : public Unit
void SetClientControl(Unit* target, uint8 allowMove);
+ void EnterVehicle(Vehicle *vehicle);
+ void ExitVehicle(Vehicle *vehicle);
+
+ //void SetViewport(uint64 guid, bool movable);
+ void SetMover(Unit* target) { m_mover = target ? target : this; }
+ void RemovePossess(bool attack = true);
+ void StopCharmOrPossess()
+ {
+ if(isPossessing())
+ RemovePossess(true);
+ else if(GetCharm())
+ Uncharm();
+ }
+
uint64 GetFarSight() const { return GetUInt64Value(PLAYER_FARSIGHT); }
- void SetFarSight(uint64 guid) { SetUInt64Value(PLAYER_FARSIGHT, guid); }
+ void SetFarSightGUID(uint64 guid) { SetUInt64Value(PLAYER_FARSIGHT, guid); }
+ void SetBindSight(Unit *target);
+ WorldObject* GetFarsightTarget() const;
+ void ClearFarsight();
+ void RemoveFarsightTarget();
+ void SetFarsightTarget(WorldObject* target);
+ // Controls if vision is currently on farsight object, updated in FAR_SIGHT opcode
+ void SetFarsightVision(bool apply) { m_farsightVision = apply; }
+ bool HasFarsightVision() const { return m_farsightVision; }
// Transports
Transport * GetTransport() const { return m_transport; }
@@ -1985,6 +2048,7 @@ class TRINITY_DLL_SPEC Player : public Unit
float GetTransOffsetZ() const { return m_movementInfo.t_z; }
float GetTransOffsetO() const { return m_movementInfo.t_o; }
uint32 GetTransTime() const { return m_movementInfo.t_time; }
+ int8 GetTransSeat() const { return m_movementInfo.t_seat; }
uint32 GetSaveTimer() const { return m_nextSave; }
void SetSaveTimer(uint32 timer) { m_nextSave = timer; }
@@ -2003,6 +2067,7 @@ class TRINITY_DLL_SPEC Player : public Unit
float m_homebindX;
float m_homebindY;
float m_homebindZ;
+ void RelocateToHomebind() { SetMapId(m_homebindMapId); Relocate(m_homebindX,m_homebindY,m_homebindZ); }
// currently visible objects at player client
typedef std::set<uint64> ClientGUIDs;
@@ -2036,7 +2101,6 @@ class TRINITY_DLL_SPEC Player : public Unit
uint32 GetOldPetSpell() const { return m_oldpetspell; }
void SetOldPetSpell(uint32 petspell) { m_oldpetspell = petspell; }
-
/*********************************************************/
/*** INSTANCE SYSTEM ***/
/*********************************************************/
@@ -2069,11 +2133,10 @@ class TRINITY_DLL_SPEC Player : public Unit
GroupReference& GetGroupRef() { return m_group; }
void SetGroup(Group *group, int8 subgroup = -1);
uint8 GetSubGroup() const { return m_group.getSubGroup(); }
- uint32 GetGroupUpdateFlag() { return m_groupUpdateMask; }
+ uint32 GetGroupUpdateFlag() const { return m_groupUpdateMask; }
void SetGroupUpdateFlag(uint32 flag) { m_groupUpdateMask |= flag; }
- uint64 GetAuraUpdateMask() { return m_auraUpdateMask; }
- void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); }
- void UnsetAuraUpdateMask(uint8 slot) { m_auraUpdateMask &= ~(uint64(1) << slot); }
+ const uint64& GetAuraUpdateMaskForRaid() const { return m_auraRaidUpdateMask; }
+ void SetAuraUpdateMaskForRaid(uint8 slot) { m_auraRaidUpdateMask |= (uint64(1) << slot); }
Player* GetNextRandomRaidMember(float radius);
PartyResult CanUninviteFromGroup() const;
@@ -2085,6 +2148,18 @@ class TRINITY_DLL_SPEC Player : public Unit
WorldLocation& GetTeleportDest() { return m_teleport_dest; }
DeclinedName const* GetDeclinedNames() const { return m_declinedname; }
+ uint8 GetRunesState() const { return m_runes->runeState; }
+ uint8 GetBaseRune(uint8 index) const { return m_runes->runes[index].BaseRune; }
+ uint8 GetCurrentRune(uint8 index) const { return m_runes->runes[index].CurrentRune; }
+ uint8 GetRuneCooldown(uint8 index) const { return m_runes->runes[index].Cooldown; }
+ void SetBaseRune(uint8 index, uint8 baseRune) { m_runes->runes[index].BaseRune = baseRune; }
+ void SetCurrentRune(uint8 index, uint8 currentRune) { m_runes->runes[index].CurrentRune = currentRune; }
+ void SetRuneCooldown(uint8 index, uint8 cooldown) { m_runes->runes[index].Cooldown = cooldown; m_runes->SetRuneState(index, (cooldown == 0) ? true : false); }
+ void ConvertRune(uint8 index, uint8 newType);
+ void ResyncRunes(uint8 count);
+ void AddRunePower(uint8 index);
+ void InitRunes();
+ AchievementMgr& GetAchievementMgr() { return m_achievementMgr; }
bool HasTitle(uint32 bitIndex);
bool HasTitle(CharTitlesEntry const* title) { return HasTitle(title->bit_index); }
void SetTitle(CharTitlesEntry const* title);
@@ -2106,11 +2181,7 @@ class TRINITY_DLL_SPEC Player : public Unit
uint32 invitedToInstance;
};
BgBattleGroundQueueID_Rec m_bgBattleGroundQueueID[PLAYER_MAX_BATTLEGROUND_QUEUES];
- uint32 m_bgEntryPointMap;
- float m_bgEntryPointX;
- float m_bgEntryPointY;
- float m_bgEntryPointZ;
- float m_bgEntryPointO;
+ WorldLocation m_bgEntryPoint;
std::set<uint32> m_bgAfkReporter;
uint8 m_bgAfkReportedCount;
@@ -2134,6 +2205,7 @@ class TRINITY_DLL_SPEC Player : public Unit
void _LoadActions(QueryResult *result);
void _LoadAuras(QueryResult *result, uint32 timediff);
+ void _LoadGlyphAuras();
void _LoadBoundInstances(QueryResult *result);
void _LoadInventory(QueryResult *result, uint32 timediff);
void _LoadMailInit(QueryResult *resultUnread, QueryResult *resultDelivery);
@@ -2143,6 +2215,7 @@ class TRINITY_DLL_SPEC Player : public Unit
void _LoadDailyQuestStatus(QueryResult *result);
void _LoadGroup(QueryResult *result);
void _LoadReputation(QueryResult *result);
+ void _LoadSkills();
void _LoadSpells(QueryResult *result);
void _LoadTutorials(QueryResult *result);
void _LoadFriendList(QueryResult *result);
@@ -2184,7 +2257,6 @@ class TRINITY_DLL_SPEC Player : public Unit
time_t m_lastHonorUpdateTime;
void outDebugValues() const;
- bool _removeSpell(uint16 spell_id);
uint64 m_lootGuid;
uint32 m_race;
@@ -2221,6 +2293,11 @@ class TRINITY_DLL_SPEC Player : public Unit
ActionButtonList m_actionButtons;
float m_auraBaseMod[BASEMOD_END][MOD_END];
+ int16 m_baseRatingValue[MAX_COMBAT_RATING];
+ uint16 m_baseSpellDamage;
+ uint16 m_baseSpellHealing;
+ uint16 m_baseFeralAP;
+ uint16 m_baseManaRegen;
SpellModList m_spellMods[MAX_SPELLMOD];
int32 m_SpellModRemoveCount;
@@ -2254,7 +2331,6 @@ class TRINITY_DLL_SPEC Player : public Unit
bool m_DailyQuestChanged;
time_t m_lastDailyQuestTime;
- uint32 m_regenTimer;
uint32 m_breathTimer;
uint32 m_drunkTimer;
uint16 m_drunk;
@@ -2273,8 +2349,10 @@ class TRINITY_DLL_SPEC Player : public Unit
uint32 m_ArmorProficiency;
bool m_canParry;
bool m_canBlock;
+ bool m_canTitanGrip;
uint8 m_swingErrorMsg;
float m_ammoDPS;
+
////////////////////Rest System/////////////////////
int time_inn_enter;
uint32 inn_pos_mapid;
@@ -2291,6 +2369,7 @@ class TRINITY_DLL_SPEC Player : public Unit
uint32 m_resetTalentsCost;
time_t m_resetTalentsTime;
uint32 m_usedTalentCount;
+ uint32 m_questRewardTalentCount;
// Social
PlayerSocial *m_social;
@@ -2299,7 +2378,7 @@ class TRINITY_DLL_SPEC Player : public Unit
GroupReference m_group;
Group *m_groupInvite;
uint32 m_groupUpdateMask;
- uint64 m_auraUpdateMask;
+ uint64 m_auraRaidUpdateMask;
// Temporarily removed pet cache
uint32 m_temporaryUnsummonedPetNumber;
@@ -2321,6 +2400,8 @@ class TRINITY_DLL_SPEC Player : public Unit
bool m_farsightVision;
DeclinedName *m_declinedname;
+ Runes *m_runes;
+ AchievementMgr m_achievementMgr;
private:
// internal common parts for CanStore/StoreItem functions
uint8 _CanStoreItem_InSpecificSlot( uint8 bag, uint8 slot, ItemPosCountVec& dest, ItemPrototype const *pProto, uint32& count, bool swap, Item *pSrcItem ) const;
@@ -2328,6 +2409,8 @@ class TRINITY_DLL_SPEC Player : public Unit
uint8 _CanStoreItem_InInventorySlots( uint8 slot_begin, uint8 slot_end, ItemPosCountVec& dest, ItemPrototype const *pProto, uint32& count, bool merge, Item *pSrcItem, uint8 skip_bag, uint8 skip_slot ) const;
Item* _StoreItem( uint16 pos, Item *pItem, uint32 count, bool clone, bool update );
+ void AdjustQuestReqItemCount( Quest const* pQuest, QuestStatusData& questStatusData );
+
GridReference<Player> m_gridRef;
MapReference m_mapRef;
diff --git a/src/game/PlayerDump.cpp b/src/game/PlayerDump.cpp
index fb22e963ca0..d698e8c293c 100644
--- a/src/game/PlayerDump.cpp
+++ b/src/game/PlayerDump.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/PlayerDump.h b/src/game/PlayerDump.h
index c8335216716..365406beede 100644
--- a/src/game/PlayerDump.h
+++ b/src/game/PlayerDump.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/PointMovementGenerator.cpp b/src/game/PointMovementGenerator.cpp
index a4795974e96..bcc25987e56 100644
--- a/src/game/PointMovementGenerator.cpp
+++ b/src/game/PointMovementGenerator.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/PointMovementGenerator.h b/src/game/PointMovementGenerator.h
index 8a3f0da675f..08050b24e3d 100644
--- a/src/game/PointMovementGenerator.h
+++ b/src/game/PointMovementGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/PossessedAI.cpp b/src/game/PossessedAI.cpp
index f291221216a..7ac36a37352 100644
--- a/src/game/PossessedAI.cpp
+++ b/src/game/PossessedAI.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
- * Thanks to the original authors: MaNGOS <http://www.mangosproject.org/>
+ * Thanks to the original authors: 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
diff --git a/src/game/PossessedAI.h b/src/game/PossessedAI.h
index 5c4a670c200..5671cfa912d 100644
--- a/src/game/PossessedAI.h
+++ b/src/game/PossessedAI.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
- * Thanks to the original authors: MaNGOS <http://www.mangosproject.org/>
+ * Thanks to the original authors: 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
diff --git a/src/game/QueryHandler.cpp b/src/game/QueryHandler.cpp
index 9f9eecc2234..681318a9de9 100644
--- a/src/game/QueryHandler.cpp
+++ b/src/game/QueryHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -33,6 +33,7 @@
#include "NPCHandler.h"
#include "ObjectAccessor.h"
#include "Pet.h"
+#include "MapManager.h"
void WorldSession::SendNameQueryOpcode(Player *p)
{
@@ -185,7 +186,6 @@ void WorldSession::HandleCreatureQueryOpcode( WorldPacket & recv_data )
data << (uint32)ci->type;
data << (uint32)ci->family; // family wdbFeild9
data << (uint32)ci->rank; // rank wdbFeild10
- data << (uint32)0; // unknown wdbFeild11
data << (uint32)ci->PetSpellDataId; // Id from CreatureSpellData.dbc wdbField12
data << (uint32)ci->Modelid1; // Modelid1
data << (uint32)ci->Modelid2; // Modelid2
@@ -276,20 +276,43 @@ void WorldSession::HandleCorpseQueryOpcode(WorldPacket & /*recv_data*/)
Corpse *corpse = GetPlayer()->GetCorpse();
- uint8 found = 1;
if(!corpse)
- found = 0;
+ {
+ WorldPacket data(MSG_CORPSE_QUERY, 1);
+ data << uint8(0); // corpse not found
+ SendPacket(&data);
+ return;
+ }
- WorldPacket data(MSG_CORPSE_QUERY, (1+found*(5*4)));
- data << uint8(found);
- if(found)
+ int32 mapid = corpse->GetMapId();
+ float x = corpse->GetPositionX();
+ float y = corpse->GetPositionY();
+ float z = corpse->GetPositionZ();
+ int32 corpsemapid = _player->GetMapId();
+
+ if(Map *map = MapManager::Instance().FindMap(corpse->GetMapId(), corpse->GetInstanceId()))
{
- data << corpse->GetMapId();
- data << corpse->GetPositionX();
- data << corpse->GetPositionY();
- data << corpse->GetPositionZ();
- data << _player->GetMapId();
+ if(map->IsDungeon())
+ {
+ if(!map->GetEntrancePos(mapid, x, y))
+ return;
+
+ Map *entrance_map = MapManager::Instance().GetMap(mapid, _player);
+ if(!entrance_map)
+ return;
+
+ z = entrance_map->GetHeight(x, y, MAX_HEIGHT);
+ corpsemapid = corpse->GetMapId();
+ }
}
+
+ WorldPacket data(MSG_CORPSE_QUERY, 1+(5*4));
+ data << uint8(1); // corpse found
+ data << int32(mapid);
+ data << float(x);
+ data << float(y);
+ data << float(z);
+ data << int32(corpsemapid);
SendPacket(&data);
}
diff --git a/src/game/QuestDef.cpp b/src/game/QuestDef.cpp
index 4dd202bc344..d07b56c6157 100644
--- a/src/game/QuestDef.cpp
+++ b/src/game/QuestDef.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -44,88 +44,90 @@ Quest::Quest(Field * questRecord)
QuestFlags = questRecord[17].GetUInt16();
uint32 SpecialFlags = questRecord[18].GetUInt16();
CharTitleId = questRecord[19].GetUInt32();
- PrevQuestId = questRecord[20].GetInt32();
- NextQuestId = questRecord[21].GetInt32();
- ExclusiveGroup = questRecord[22].GetInt32();
- NextQuestInChain = questRecord[23].GetUInt32();
- SrcItemId = questRecord[24].GetUInt32();
- SrcItemCount = questRecord[25].GetUInt32();
- SrcSpell = questRecord[26].GetUInt32();
- Title = questRecord[27].GetCppString();
- Details = questRecord[28].GetCppString();
- Objectives = questRecord[29].GetCppString();
- OfferRewardText = questRecord[30].GetCppString();
- RequestItemsText = questRecord[31].GetCppString();
- EndText = questRecord[32].GetCppString();
+ PlayersSlain = questRecord[20].GetUInt32();
+ BonusTalents = questRecord[21].GetUInt32();
+ PrevQuestId = questRecord[22].GetInt32();
+ NextQuestId = questRecord[23].GetInt32();
+ ExclusiveGroup = questRecord[24].GetInt32();
+ NextQuestInChain = questRecord[25].GetUInt32();
+ SrcItemId = questRecord[26].GetUInt32();
+ SrcItemCount = questRecord[27].GetUInt32();
+ SrcSpell = questRecord[28].GetUInt32();
+ Title = questRecord[29].GetCppString();
+ Details = questRecord[30].GetCppString();
+ Objectives = questRecord[31].GetCppString();
+ OfferRewardText = questRecord[32].GetCppString();
+ RequestItemsText = questRecord[33].GetCppString();
+ EndText = questRecord[34].GetCppString();
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
- ObjectiveText[i] = questRecord[33+i].GetCppString();
+ ObjectiveText[i] = questRecord[35+i].GetCppString();
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
- ReqItemId[i] = questRecord[37+i].GetUInt32();
+ ReqItemId[i] = questRecord[39+i].GetUInt32();
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
- ReqItemCount[i] = questRecord[41+i].GetUInt32();
+ ReqItemCount[i] = questRecord[43+i].GetUInt32();
for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
- ReqSourceId[i] = questRecord[45+i].GetUInt32();
+ ReqSourceId[i] = questRecord[47+i].GetUInt32();
for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
- ReqSourceCount[i] = questRecord[49+i].GetUInt32();
+ ReqSourceCount[i] = questRecord[51+i].GetUInt32();
for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
- ReqSourceRef[i] = questRecord[53+i].GetUInt32();
+ ReqSourceRef[i] = questRecord[55+i].GetUInt32();
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
- ReqCreatureOrGOId[i] = questRecord[57+i].GetInt32();
+ ReqCreatureOrGOId[i] = questRecord[59+i].GetInt32();
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
- ReqCreatureOrGOCount[i] = questRecord[61+i].GetUInt32();
+ ReqCreatureOrGOCount[i] = questRecord[63+i].GetUInt32();
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
- ReqSpell[i] = questRecord[65+i].GetUInt32();
+ ReqSpell[i] = questRecord[67+i].GetUInt32();
for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
- RewChoiceItemId[i] = questRecord[69+i].GetUInt32();
+ RewChoiceItemId[i] = questRecord[71+i].GetUInt32();
for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
- RewChoiceItemCount[i] = questRecord[75+i].GetUInt32();
+ RewChoiceItemCount[i] = questRecord[78+i].GetUInt32();
for (int i = 0; i < QUEST_REWARDS_COUNT; ++i)
- RewItemId[i] = questRecord[81+i].GetUInt32();
+ RewItemId[i] = questRecord[85+i].GetUInt32();
for (int i = 0; i < QUEST_REWARDS_COUNT; ++i)
- RewItemCount[i] = questRecord[85+i].GetUInt32();
+ RewItemCount[i] = questRecord[89+i].GetUInt32();
for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
- RewRepFaction[i] = questRecord[89+i].GetUInt32();
+ RewRepFaction[i] = questRecord[93+i].GetUInt32();
for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
- RewRepValue[i] = questRecord[94+i].GetInt32();
-
- RewHonorableKills = questRecord[99].GetUInt32();
- RewOrReqMoney = questRecord[100].GetInt32();
- RewMoneyMaxLevel = questRecord[101].GetUInt32();
- RewSpell = questRecord[102].GetUInt32();
- RewSpellCast = questRecord[103].GetUInt32();
- RewMailTemplateId = questRecord[104].GetUInt32();
- RewMailDelaySecs = questRecord[105].GetUInt32();
- PointMapId = questRecord[106].GetUInt32();
- PointX = questRecord[107].GetFloat();
- PointY = questRecord[108].GetFloat();
- PointOpt = questRecord[109].GetUInt32();
+ RewRepValue[i] = questRecord[98+i].GetInt32();
+
+ RewHonorableKills = questRecord[103].GetUInt32();
+ RewOrReqMoney = questRecord[104].GetInt32();
+ RewMoneyMaxLevel = questRecord[105].GetUInt32();
+ RewSpell = questRecord[106].GetUInt32();
+ RewSpellCast = questRecord[107].GetUInt32();
+ RewMailTemplateId = questRecord[108].GetUInt32();
+ RewMailDelaySecs = questRecord[109].GetUInt32();
+ PointMapId = questRecord[110].GetUInt32();
+ PointX = questRecord[111].GetFloat();
+ PointY = questRecord[112].GetFloat();
+ PointOpt = questRecord[113].GetUInt32();
for (int i = 0; i < QUEST_EMOTE_COUNT; ++i)
- DetailsEmote[i] = questRecord[110+i].GetUInt32();
+ DetailsEmote[i] = questRecord[114+i].GetUInt32();
- IncompleteEmote = questRecord[114].GetUInt32();
- CompleteEmote = questRecord[115].GetUInt32();
+ IncompleteEmote = questRecord[118].GetUInt32();
+ CompleteEmote = questRecord[119].GetUInt32();
for (int i = 0; i < QUEST_EMOTE_COUNT; ++i)
- OfferRewardEmote[i] = questRecord[116+i].GetInt32();
+ OfferRewardEmote[i] = questRecord[120+i].GetInt32();
- QuestStartScript = questRecord[120].GetUInt32();
- QuestCompleteScript = questRecord[121].GetUInt32();
+ QuestStartScript = questRecord[124].GetUInt32();
+ QuestCompleteScript = questRecord[125].GetUInt32();
QuestFlags |= SpecialFlags << 16;
@@ -164,18 +166,20 @@ uint32 Quest::XPValue( Player *pPlayer ) const
uint32 pLevel = pPlayer->getLevel();
uint32 qLevel = QuestLevel;
float fullxp = 0;
- if (qLevel >= 65)
+ if (qLevel >= 15)
fullxp = RewMoneyMaxLevel / 6.0f;
- else if (qLevel == 64)
+ else if (qLevel == 14)
fullxp = RewMoneyMaxLevel / 4.8f;
- else if (qLevel == 63)
- fullxp = RewMoneyMaxLevel / 3.6f;
- else if (qLevel == 62)
+ else if (qLevel == 13)
+ fullxp = RewMoneyMaxLevel / 3.666f;
+ else if (qLevel == 12)
fullxp = RewMoneyMaxLevel / 2.4f;
- else if (qLevel == 61)
+ else if (qLevel == 11)
fullxp = RewMoneyMaxLevel / 1.2f;
- else if (qLevel > 0 && qLevel <= 60)
+ else if (qLevel >= 1 && qLevel <= 10)
fullxp = RewMoneyMaxLevel / 0.6f;
+ else if (qLevel == 0)
+ fullxp = RewMoneyMaxLevel;
if( pLevel <= qLevel + 5 )
return (uint32)fullxp;
diff --git a/src/game/QuestDef.h b/src/game/QuestDef.h
index 52f58c2c87e..3b5e7b1a3d9 100644
--- a/src/game/QuestDef.h
+++ b/src/game/QuestDef.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -35,7 +35,7 @@ class ObjectMgr;
#define QUEST_OBJECTIVES_COUNT 4
#define QUEST_SOURCE_ITEM_IDS_COUNT 4
-#define QUEST_REWARD_CHOICES_COUNT 6
+#define QUEST_REWARD_CHOICES_COUNT 7
#define QUEST_REWARDS_COUNT 4
#define QUEST_DEPLINK_COUNT 10
#define QUEST_REPUTATIONS_COUNT 5
@@ -44,30 +44,33 @@ class ObjectMgr;
enum QuestFailedReasons
{
INVALIDREASON_DONT_HAVE_REQ = 0,
- INVALIDREASON_QUEST_FAILED_LOW_LEVEL = 1, //You are not high enough level for that quest.
- INVALIDREASON_QUEST_FAILED_WRONG_RACE = 6, //That quest is not available to your race.
- INVALIDREASON_QUEST_ALREADY_DONE = 7, //You have completed that quest.
- INVALIDREASON_QUEST_ONLY_ONE_TIMED = 12, //You can only be on one timed quest at a time.
- INVALIDREASON_QUEST_ALREADY_ON = 13, //You are already on that quest
- INVALIDREASON_QUEST_FAILED_EXPANSION = 16, //This quest requires an expansion enabled account.
- INVALIDREASON_QUEST_ALREADY_ON2 = 18, //You are already on that quest
- INVALIDREASON_QUEST_FAILED_MISSING_ITEMS = 21, //You don't have the required items with you. Check storage.
- INVALIDREASON_QUEST_FAILED_NOT_ENOUGH_MONEY = 23, //You don't have enough money for that quest.
- INVALIDREASON_DAILY_QUESTS_REMAINING = 26, //You have already completed 10 daily quests today
- INVALIDREASON_QUEST_FAILED_CAIS = 27, //You cannot complete quests once you have reached tired time
+ INVALIDREASON_QUEST_FAILED_LOW_LEVEL = 1, // You are not high enough level for that quest.
+ INVALIDREASON_QUEST_FAILED_WRONG_RACE = 6, // That quest is not available to your race.
+ INVALIDREASON_QUEST_ALREADY_DONE = 7, // You have completed that quest.
+ INVALIDREASON_QUEST_ONLY_ONE_TIMED = 12, // You can only be on one timed quest at a time.
+ INVALIDREASON_QUEST_ALREADY_ON = 13, // You are already on that quest.
+ INVALIDREASON_QUEST_FAILED_EXPANSION = 16, // This quest requires an expansion enabled account.
+ INVALIDREASON_QUEST_ALREADY_ON2 = 18, // You are already on that quest.
+ INVALIDREASON_QUEST_FAILED_MISSING_ITEMS = 21, // You don't have the required items with you. Check storage.
+ INVALIDREASON_QUEST_FAILED_NOT_ENOUGH_MONEY = 23, // You don't have enough money for that quest.
+ INVALIDREASON_DAILY_QUESTS_REMAINING = 26, // You have already completed 25 daily quests today.
+ INVALIDREASON_QUEST_FAILED_CAIS = 27, // You cannot complete quests once you have reached tired time.
+ INVALIDREASON_DAILY_QUEST_COMPLETED_TODAY = 29 // You have completed that daily quest today.
};
enum QuestShareMessages
{
- QUEST_PARTY_MSG_SHARING_QUEST = 0,
- QUEST_PARTY_MSG_CANT_TAKE_QUEST = 1,
- QUEST_PARTY_MSG_ACCEPT_QUEST = 2,
- QUEST_PARTY_MSG_REFUSE_QUEST = 3,
- QUEST_PARTY_MSG_TOO_FAR = 4,
- QUEST_PARTY_MSG_BUSY = 5,
- QUEST_PARTY_MSG_LOG_FULL = 6,
- QUEST_PARTY_MSG_HAVE_QUEST = 7,
- QUEST_PARTY_MSG_FINISH_QUEST = 8,
+ QUEST_PARTY_MSG_SHARING_QUEST = 0,
+ QUEST_PARTY_MSG_CANT_TAKE_QUEST = 1,
+ QUEST_PARTY_MSG_ACCEPT_QUEST = 2,
+ QUEST_PARTY_MSG_DECLINE_QUEST = 3,
+ QUEST_PARTY_MSG_BUSY = 4,
+ QUEST_PARTY_MSG_LOG_FULL = 5,
+ QUEST_PARTY_MSG_HAVE_QUEST = 6,
+ QUEST_PARTY_MSG_FINISH_QUEST = 7,
+ QUEST_PARTY_MSG_CANT_BE_SHARED_TODAY = 8,
+ QUEST_PARTY_MSG_SHARING_TIMER_EXPIRED = 9,
+ QUEST_PARTY_MSG_NOT_IN_PARTY = 10
};
enum __QuestTradeSkill
@@ -190,6 +193,8 @@ class Quest
int32 GetExclusiveGroup() const { return ExclusiveGroup; }
uint32 GetNextQuestInChain() const { return NextQuestInChain; }
uint32 GetCharTitleId() const { return CharTitleId; }
+ uint32 GetPlayersSlain() const { return PlayersSlain; }
+ uint32 GetBonusTalents() const { return BonusTalents; }
uint32 GetSrcItemId() const { return SrcItemId; }
uint32 GetSrcItemCount() const { return SrcItemCount; }
uint32 GetSrcSpell() const { return SrcSpell; }
@@ -277,6 +282,8 @@ class Quest
uint32 LimitTime;
uint32 QuestFlags;
uint32 CharTitleId;
+ uint32 PlayersSlain;
+ uint32 BonusTalents;
int32 PrevQuestId;
int32 NextQuestId;
int32 ExclusiveGroup;
diff --git a/src/game/QuestHandler.cpp b/src/game/QuestHandler.cpp
index abb285e6dbb..98d4972c406 100644
--- a/src/game/QuestHandler.cpp
+++ b/src/game/QuestHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -180,7 +180,7 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode( WorldPacket & recv_data )
bool destroyItem = true;
for(int i = 0; i < QUEST_OBJECTIVES_COUNT; i++)
{
- if ((qInfo->ReqItemId[i] == ((Item*)pObject)->GetEntry()) && (((Item*)pObject)->GetProto()->MaxCount != 0))
+ if ((qInfo->ReqItemId[i] == ((Item*)pObject)->GetEntry()) && (((Item*)pObject)->GetProto()->MaxCount > 0))
{
destroyItem = false;
break;
@@ -451,12 +451,6 @@ void WorldSession::HandleQuestPushToParty(WorldPacket& recvPacket)
_player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_SHARING_QUEST);
- if( _player->GetDistance( pPlayer ) > 10 )
- {
- _player->SendPushToPartyResponse( pPlayer, QUEST_PARTY_MSG_TOO_FAR );
- continue;
- }
-
if( !pPlayer->SatisfyQuestStatus( pQuest, false ) )
{
_player->SendPushToPartyResponse( pPlayer, QUEST_PARTY_MSG_HAVE_QUEST );
diff --git a/src/game/RandomMovementGenerator.cpp b/src/game/RandomMovementGenerator.cpp
index 0679d1381db..0e85c1911a5 100644
--- a/src/game/RandomMovementGenerator.cpp
+++ b/src/game/RandomMovementGenerator.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/RandomMovementGenerator.h b/src/game/RandomMovementGenerator.h
index ed34b96f608..e2d2a5005fb 100644
--- a/src/game/RandomMovementGenerator.h
+++ b/src/game/RandomMovementGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/ReactorAI.cpp b/src/game/ReactorAI.cpp
index 29b07f60b00..02799431991 100644
--- a/src/game/ReactorAI.cpp
+++ b/src/game/ReactorAI.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/ReactorAI.h b/src/game/ReactorAI.h
index cea1e8dcdb5..e549bfc7243 100644
--- a/src/game/ReactorAI.h
+++ b/src/game/ReactorAI.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/ScriptCalls.cpp b/src/game/ScriptCalls.cpp
index 4bd305917b2..78d63c460ce 100644
--- a/src/game/ScriptCalls.cpp
+++ b/src/game/ScriptCalls.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -86,7 +86,8 @@ bool LoadScriptingModule(char const* libName)
return false;
}
- printf("Scripts Library %s was successfully loaded.\n",name.c_str());
+ sLog.outString();
+ sLog.outString( ">>> Scripts Library %s was successfully loaded.\n", name.c_str() );
//heh we are still there :P we have a valid library
//we reload script
diff --git a/src/game/ScriptCalls.h b/src/game/ScriptCalls.h
index 52b2f27f218..216a694936f 100644
--- a/src/game/ScriptCalls.h
+++ b/src/game/ScriptCalls.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h
index e0e3a5ba077..aa9d4fe153f 100644
--- a/src/game/SharedDefines.h
+++ b/src/game/SharedDefines.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -24,6 +24,9 @@
#include "Platform/Define.h"
#include <cassert>
+#define MaNGOS Trinity
+#define GetMangosString GetTrinityString
+
enum Gender
{
GENDER_MALE = 0,
@@ -88,7 +91,8 @@ enum Classes
#define CLASSMASK_ALL_PLAYABLE \
((1<<(CLASS_WARRIOR-1))|(1<<(CLASS_PALADIN-1))|(1<<(CLASS_HUNTER-1))| \
(1<<(CLASS_ROGUE-1)) |(1<<(CLASS_PRIEST-1)) |(1<<(CLASS_SHAMAN-1))| \
- (1<<(CLASS_MAGE-1)) |(1<<(CLASS_WARLOCK-1))|(1<<(CLASS_DRUID-1)) )
+ (1<<(CLASS_MAGE-1)) |(1<<(CLASS_WARLOCK-1))|(1<<(CLASS_DRUID-1)) | \
+ (1<<(CLASS_DEATH_KNIGHT-1)) )
#define CLASSMASK_WAND_USERS ((1<<(CLASS_PRIEST-1))|(1<<(CLASS_MAGE-1))|(1<<(CLASS_WARLOCK-1)))
@@ -134,11 +138,12 @@ enum Powers
POWER_FOCUS = 2,
POWER_ENERGY = 3,
POWER_HAPPINESS = 4,
- POWER_RUNES = 5,
+ POWER_RUNE = 5,
+ POWER_RUNIC_POWER = 6,
POWER_HEALTH = 0xFFFFFFFE // (-2 as signed value)
};
-#define MAX_POWERS 5 // not count POWER_RUNES for now
+#define MAX_POWERS 7
enum SpellSchools
{
@@ -199,10 +204,11 @@ enum ItemQualities
ITEM_QUALITY_RARE = 3, //BLUE
ITEM_QUALITY_EPIC = 4, //PURPLE
ITEM_QUALITY_LEGENDARY = 5, //ORANGE
- ITEM_QUALITY_ARTIFACT = 6 //LIGHT YELLOW
+ ITEM_QUALITY_ARTIFACT = 6, //LIGHT YELLOW
+ ITEM_QUALITY_HEIRLOOM = 7
};
-#define MAX_ITEM_QUALITY 7
+#define MAX_ITEM_QUALITY 8
enum SpellCategory
{
@@ -217,7 +223,7 @@ enum SpellCategory
#define SPELL_ATTR_UNK0 0x00000001 // 0
#define SPELL_ATTR_RANGED 0x00000002 // 1 All ranged abilities have this flag
#define SPELL_ATTR_ON_NEXT_SWING_1 0x00000004 // 2 on next swing
-#define SPELL_ATTR_UNK3 0x00000008 // 3 not set in 2.4.2
+#define SPELL_ATTR_UNK3 0x00000008 // 3 not set in 3.0.3
#define SPELL_ATTR_UNK4 0x00000010 // 4
#define SPELL_ATTR_UNK5 0x00000020 // 5 trade spells?
#define SPELL_ATTR_PASSIVE 0x00000040 // 6 Passive spell
@@ -257,7 +263,7 @@ enum SpellCategory
#define SPELL_ATTR_EX_NEGATIVE 0x00000080 // 7
#define SPELL_ATTR_EX_NOT_IN_COMBAT_TARGET 0x00000100 // 8 Spell req target not to be in combat state
#define SPELL_ATTR_EX_UNK9 0x00000200 // 9
-#define SPELL_ATTR_EX_UNK10 0x00000400 // 10
+#define SPELL_ATTR_EX_NO_INITIAL_AGGRO 0x00000400 // 10 no generates threat on cast 100%
#define SPELL_ATTR_EX_UNK11 0x00000800 // 11
#define SPELL_ATTR_EX_UNK12 0x00001000 // 12
#define SPELL_ATTR_EX_UNK13 0x00002000 // 13
@@ -272,7 +278,7 @@ enum SpellCategory
#define SPELL_ATTR_EX_REQ_COMBO_POINTS2 0x00400000 // 22 Req combo points on target
#define SPELL_ATTR_EX_UNK23 0x00800000 // 23
#define SPELL_ATTR_EX_UNK24 0x01000000 // 24 Req fishing pole??
-#define SPELL_ATTR_EX_UNK25 0x02000000 // 25 not set in 2.4.2
+#define SPELL_ATTR_EX_UNK25 0x02000000 // 25
#define SPELL_ATTR_EX_UNK26 0x04000000 // 26
#define SPELL_ATTR_EX_UNK27 0x08000000 // 27
#define SPELL_ATTR_EX_UNK28 0x10000000 // 28
@@ -282,20 +288,20 @@ enum SpellCategory
#define SPELL_ATTR_EX2_UNK0 0x00000001 // 0
#define SPELL_ATTR_EX2_UNK1 0x00000002 // 1
-#define SPELL_ATTR_EX2_UNK2 0x00000004 // 2 boss spells?
+#define SPELL_ATTR_EX2_CANT_REFLECTED 0x00000004 // 2 ? used for detect can or not spell reflected
#define SPELL_ATTR_EX2_UNK3 0x00000008 // 3
#define SPELL_ATTR_EX2_UNK4 0x00000010 // 4
-#define SPELL_ATTR_EX2_UNK5 0x00000020 // 5
+#define SPELL_ATTR_EX2_AUTOREPEAT_FLAG 0x00000020 // 5
#define SPELL_ATTR_EX2_UNK6 0x00000040 // 6
#define SPELL_ATTR_EX2_UNK7 0x00000080 // 7
-#define SPELL_ATTR_EX2_UNK8 0x00000100 // 8 not set in 2.4.2
+#define SPELL_ATTR_EX2_UNK8 0x00000100 // 8 not set in 3.0.3
#define SPELL_ATTR_EX2_UNK9 0x00000200 // 9
#define SPELL_ATTR_EX2_UNK10 0x00000400 // 10
#define SPELL_ATTR_EX2_HEALTH_FUNNEL 0x00000800 // 11
#define SPELL_ATTR_EX2_UNK12 0x00001000 // 12
#define SPELL_ATTR_EX2_UNK13 0x00002000 // 13
#define SPELL_ATTR_EX2_UNK14 0x00004000 // 14
-#define SPELL_ATTR_EX2_UNK15 0x00008000 // 15 not set in 2.4.2
+#define SPELL_ATTR_EX2_UNK15 0x00008000 // 15 not set in 3.0.3
#define SPELL_ATTR_EX2_TAME_BEAST 0x00010000 // 16
#define SPELL_ATTR_EX2_NOT_RESET_AUTOSHOT 0x00020000 // 17 Hunters Shot and Stings only have this flag
#define SPELL_ATTR_EX2_UNK18 0x00040000 // 18 Only Revive pet - possible req dead pet
@@ -308,7 +314,7 @@ enum SpellCategory
#define SPELL_ATTR_EX2_UNK25 0x02000000 // 25
#define SPELL_ATTR_EX2_UNK26 0x04000000 // 26 unaffected by school immunity
#define SPELL_ATTR_EX2_UNK27 0x08000000 // 27
-#define SPELL_ATTR_EX2_UNK28 0x10000000 // 28
+#define SPELL_ATTR_EX2_UNK28 0x10000000 // 28 no breaks stealth if it fails??
#define SPELL_ATTR_EX2_CANT_CRIT 0x20000000 // 29 Spell can't crit
#define SPELL_ATTR_EX2_UNK30 0x40000000 // 30
#define SPELL_ATTR_EX2_FOOD 0x80000000 // 31 food, well-fed, and a few others
@@ -329,8 +335,8 @@ enum SpellCategory
#define SPELL_ATTR_EX3_UNK13 0x00002000 // 13
#define SPELL_ATTR_EX3_UNK14 0x00004000 // 14 "Honorless Target" only this spells have this flag
#define SPELL_ATTR_EX3_UNK15 0x00008000 // 15 Auto Shoot, Shoot, Throw, - this is autoshot flag
-#define SPELL_ATTR_EX3_UNK16 0x00010000 // 16
-#define SPELL_ATTR_EX3_NO_INITIAL_AGGRO 0x00020000 // 17 no initial aggro
+#define SPELL_ATTR_EX3_UNK16 0x00010000 // 16 no triggers effects that trigger on casting a spell??
+#define SPELL_ATTR_EX3_UNK17 0x00020000 // 17 no triggers effects that trigger on casting a spell??
#define SPELL_ATTR_EX3_UNK18 0x00040000 // 18
#define SPELL_ATTR_EX3_UNK19 0x00080000 // 19
#define SPELL_ATTR_EX3_DEATH_PERSISTENT 0x00100000 // 20 Death persistent spells
@@ -338,7 +344,7 @@ enum SpellCategory
#define SPELL_ATTR_EX3_REQ_WAND 0x00400000 // 22 Req wand
#define SPELL_ATTR_EX3_UNK23 0x00800000 // 23
#define SPELL_ATTR_EX3_REQ_OFFHAND 0x01000000 // 24 Req offhand weapon
-#define SPELL_ATTR_EX3_UNK25 0x02000000 // 25
+#define SPELL_ATTR_EX3_UNK25 0x02000000 // 25 no cause spell pushback ?
#define SPELL_ATTR_EX3_UNK26 0x04000000 // 26
#define SPELL_ATTR_EX3_UNK27 0x08000000 // 27
#define SPELL_ATTR_EX3_UNK28 0x10000000 // 28
@@ -350,7 +356,7 @@ enum SpellCategory
#define SPELL_ATTR_EX4_UNK1 0x00000002 // 1 proc on finishing move?
#define SPELL_ATTR_EX4_UNK2 0x00000004 // 2
#define SPELL_ATTR_EX4_UNK3 0x00000008 // 3
-#define SPELL_ATTR_EX4_UNK4 0x00000010 // 4
+#define SPELL_ATTR_EX4_UNK4 0x00000010 // 4 This will no longer cause guards to attack on use??
#define SPELL_ATTR_EX4_UNK5 0x00000020 // 5
#define SPELL_ATTR_EX4_UNK6 0x00000040 // 6
#define SPELL_ATTR_EX4_UNK7 0x00000080 // 7
@@ -388,7 +394,7 @@ enum SpellCategory
#define SPELL_ATTR_EX5_UNK6 0x00000040 // 6
#define SPELL_ATTR_EX5_UNK7 0x00000080 // 7
#define SPELL_ATTR_EX5_UNK8 0x00000100 // 8
-#define SPELL_ATTR_EX5_UNK9 0x00000200 // 9
+#define SPELL_ATTR_EX5_START_PERIODIC_AT_APPLY 0x00000200 // 9 begin periodic tick at aura apply
#define SPELL_ATTR_EX5_UNK10 0x00000400 // 10
#define SPELL_ATTR_EX5_UNK11 0x00000800 // 11
#define SPELL_ATTR_EX5_UNK12 0x00001000 // 12
@@ -413,37 +419,39 @@ enum SpellCategory
#define SPELL_ATTR_EX5_UNK31 0x80000000 // 31 Forces all nearby enemies to focus attacks caster
#define SPELL_ATTR_EX6_UNK0 0x00000001 // 0 Only Move spell have this flag
-#define SPELL_ATTR_EX6_UNK1 0x00000002 // 1 not set in 2.4.2
+#define SPELL_ATTR_EX6_UNK1 0x00000002 // 1 not set in 3.0.3
#define SPELL_ATTR_EX6_UNK2 0x00000004 // 2
#define SPELL_ATTR_EX6_UNK3 0x00000008 // 3
-#define SPELL_ATTR_EX6_UNK4 0x00000010 // 4 not set in 2.4.2
+#define SPELL_ATTR_EX6_UNK4 0x00000010 // 4
#define SPELL_ATTR_EX6_UNK5 0x00000020 // 5
#define SPELL_ATTR_EX6_UNK6 0x00000040 // 6
#define SPELL_ATTR_EX6_UNK7 0x00000080 // 7
#define SPELL_ATTR_EX6_UNK8 0x00000100 // 8
-#define SPELL_ATTR_EX6_UNK9 0x00000200 // 9 not set in 2.4.2
+#define SPELL_ATTR_EX6_UNK9 0x00000200 // 9
#define SPELL_ATTR_EX6_UNK10 0x00000400 // 10
#define SPELL_ATTR_EX6_UNK11 0x00000800 // 11
-#define SPELL_ATTR_EX6_UNK12 0x00001000 // 12 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK13 0x00002000 // 13 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK14 0x00004000 // 14 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK15 0x00008000 // 15 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK16 0x00010000 // 16 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK17 0x00020000 // 17 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK18 0x00040000 // 18 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK19 0x00080000 // 19 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK20 0x00100000 // 20 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK21 0x00200000 // 21 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK22 0x00400000 // 22 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK23 0x00800000 // 23 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK24 0x01000000 // 24 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK25 0x02000000 // 25 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK26 0x04000000 // 26 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK27 0x08000000 // 27 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK28 0x10000000 // 28 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK29 0x20000000 // 29 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK30 0x40000000 // 30 not set in 2.4.2
-#define SPELL_ATTR_EX6_UNK31 0x80000000 // 31 not set in 2.4.2
+#define SPELL_ATTR_EX6_UNK12 0x00001000 // 12
+#define SPELL_ATTR_EX6_UNK13 0x00002000 // 13
+#define SPELL_ATTR_EX6_UNK14 0x00004000 // 14
+#define SPELL_ATTR_EX6_UNK15 0x00008000 // 15 not set in 3.0.3
+#define SPELL_ATTR_EX6_UNK16 0x00010000 // 16
+#define SPELL_ATTR_EX6_UNK17 0x00020000 // 17
+#define SPELL_ATTR_EX6_UNK18 0x00040000 // 18
+#define SPELL_ATTR_EX6_UNK19 0x00080000 // 19
+#define SPELL_ATTR_EX6_UNK20 0x00100000 // 20
+#define SPELL_ATTR_EX6_UNK21 0x00200000 // 21
+#define SPELL_ATTR_EX6_UNK22 0x00400000 // 22
+#define SPELL_ATTR_EX6_UNK23 0x00800000 // 23 not set in 3.0.3
+#define SPELL_ATTR_EX6_UNK24 0x01000000 // 24 not set in 3.0.3
+#define SPELL_ATTR_EX6_UNK25 0x02000000 // 25 not set in 3.0.3
+#define SPELL_ATTR_EX6_UNK26 0x04000000 // 26 not set in 3.0.3
+#define SPELL_ATTR_EX6_UNK27 0x08000000 // 27 not set in 3.0.3
+#define SPELL_ATTR_EX6_UNK28 0x10000000 // 28 not set in 3.0.3
+#define SPELL_ATTR_EX6_UNK29 0x20000000 // 29 not set in 3.0.3
+#define SPELL_ATTR_EX6_UNK30 0x40000000 // 30 not set in 3.0.3
+#define SPELL_ATTR_EX6_UNK31 0x80000000 // 31 not set in 3.0.3
+
+#define MAX_GLYPH_SLOT_INDEX 5
enum SheathTypes
{
@@ -562,11 +570,11 @@ enum SpellEffects
SPELL_EFFECT_DISPEL = 38,
SPELL_EFFECT_LANGUAGE = 39,
SPELL_EFFECT_DUAL_WIELD = 40,
- SPELL_EFFECT_SUMMON_WILD = 41,
- SPELL_EFFECT_SUMMON_GUARDIAN = 42,
+ SPELL_EFFECT_JUMP = 41,
+ SPELL_EFFECT_JUMP2 = 42,
SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER= 43,
SPELL_EFFECT_SKILL_STEP = 44,
- SPELL_EFFECT_UNDEFINED_45 = 45,
+ SPELL_EFFECT_ADD_HONOR = 45,
SPELL_EFFECT_SPAWN = 46,
SPELL_EFFECT_TRADE_SKILL = 47,
SPELL_EFFECT_STEALTH = 48,
@@ -586,16 +594,16 @@ enum SpellEffects
SPELL_EFFECT_POWER_BURN = 62,
SPELL_EFFECT_THREAT = 63,
SPELL_EFFECT_TRIGGER_SPELL = 64,
- SPELL_EFFECT_HEALTH_FUNNEL = 65,
- SPELL_EFFECT_POWER_FUNNEL = 66,
+ SPELL_EFFECT_APPLY_AREA_AURA_RAID = 65,
+ SPELL_EFFECT_CREATE_MANA_GEM = 66,
SPELL_EFFECT_HEAL_MAX_HEALTH = 67,
SPELL_EFFECT_INTERRUPT_CAST = 68,
SPELL_EFFECT_DISTRACT = 69,
SPELL_EFFECT_PULL = 70,
SPELL_EFFECT_PICKPOCKET = 71,
SPELL_EFFECT_ADD_FARSIGHT = 72,
- SPELL_EFFECT_SUMMON_POSSESSED = 73,
- SPELL_EFFECT_SUMMON_TOTEM = 74,
+ SPELL_EFFECT_UNTRAIN_TALENTS = 73,
+ SPELL_EFFECT_APPLY_GLYPH = 74,
SPELL_EFFECT_HEAL_MECHANICAL = 75,
SPELL_EFFECT_SUMMON_OBJECT_WILD = 76,
SPELL_EFFECT_SCRIPT_EFFECT = 77,
@@ -608,17 +616,17 @@ enum SpellEffects
SPELL_EFFECT_STUCK = 84,
SPELL_EFFECT_SUMMON_PLAYER = 85,
SPELL_EFFECT_ACTIVATE_OBJECT = 86,
- SPELL_EFFECT_SUMMON_TOTEM_SLOT1 = 87,
- SPELL_EFFECT_SUMMON_TOTEM_SLOT2 = 88,
- SPELL_EFFECT_SUMMON_TOTEM_SLOT3 = 89,
- SPELL_EFFECT_SUMMON_TOTEM_SLOT4 = 90,
+ SPELL_EFFECT_WMO_DAMAGE = 87,
+ SPELL_EFFECT_WMO_REPAIR = 88,
+ SPELL_EFFECT_WMO_CHANGE = 89,
+ SPELL_EFFECT_KILL_CREDIT = 90,
SPELL_EFFECT_THREAT_ALL = 91,
SPELL_EFFECT_ENCHANT_HELD_ITEM = 92,
SPELL_EFFECT_SUMMON_PHANTASM = 93, //unused
SPELL_EFFECT_SELF_RESURRECT = 94,
SPELL_EFFECT_SKINNING = 95,
SPELL_EFFECT_CHARGE = 96,
- SPELL_EFFECT_SUMMON_CRITTER = 97,
+ SPELL_EFFECT_97 = 97,
SPELL_EFFECT_KNOCK_BACK = 98,
SPELL_EFFECT_DISENCHANT = 99,
SPELL_EFFECT_INEBRIATE = 100,
@@ -633,7 +641,7 @@ enum SpellEffects
SPELL_EFFECT_SUMMON_DEAD_PET = 109,
SPELL_EFFECT_DESTROY_ALL_TOTEMS = 110,
SPELL_EFFECT_DURABILITY_DAMAGE = 111,
- SPELL_EFFECT_SUMMON_DEMON = 112,
+ SPELL_EFFECT_112 = 112,
SPELL_EFFECT_RESURRECT_NEW = 113,
SPELL_EFFECT_ATTACK_ME = 114,
SPELL_EFFECT_DURABILITY_DAMAGE_PCT = 115,
@@ -655,19 +663,19 @@ enum SpellEffects
SPELL_EFFECT_131 = 131,
SPELL_EFFECT_132 = 132,
SPELL_EFFECT_UNLEARN_SPECIALIZATION = 133,
- SPELL_EFFECT_KILL_CREDIT = 134,
+ SPELL_EFFECT_KILL_CREDIT2 = 134,
SPELL_EFFECT_135 = 135,
SPELL_EFFECT_HEAL_PCT = 136,
SPELL_EFFECT_ENERGIZE_PCT = 137,
SPELL_EFFECT_138 = 138,
- SPELL_EFFECT_139 = 139,
+ SPELL_EFFECT_CLEAR_QUEST = 139,
SPELL_EFFECT_FORCE_CAST = 140,
SPELL_EFFECT_141 = 141,
SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE = 142,
SPELL_EFFECT_APPLY_AREA_AURA_OWNER = 143,
SPELL_EFFECT_KNOCK_BACK_2 = 144,
SPELL_EFFECT_145 = 145,
- SPELL_EFFECT_146 = 146,
+ SPELL_EFFECT_ACTIVATE_RUNE = 146,
SPELL_EFFECT_QUEST_FAIL = 147,
SPELL_EFFECT_148 = 148,
SPELL_EFFECT_149 = 149,
@@ -675,7 +683,13 @@ enum SpellEffects
SPELL_EFFECT_TRIGGER_SPELL_2 = 151,
SPELL_EFFECT_152 = 152,
SPELL_EFFECT_153 = 153,
- TOTAL_SPELL_EFFECTS = 154
+ SPELL_EFFECT_154 = 154,
+ SPELL_EFFECT_TITAN_GRIP = 155,
+ SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC = 156,
+ SPELL_EFFECT_CREATE_ITEM_2 = 157,
+ SPELL_EFFECT_MILLING = 158,
+ SPELL_EFFECT_ALLOW_RENAME_PET = 159,
+ TOTAL_SPELL_EFFECTS = 160
};
// Spell aura states
@@ -685,25 +699,28 @@ enum AuraState
AURA_STATE_DEFENSE = 1, // C |
AURA_STATE_HEALTHLESS_20_PERCENT = 2, // CcT |
AURA_STATE_BERSERKING = 3, // C T |
- //AURA_STATE_UNKNOWN4 = 4, // c t| some limitation to charge spells (?) and target test spells
+ AURA_STATE_FROZEN = 4, // c t| frozen target
AURA_STATE_JUDGEMENT = 5, // C |
//AURA_STATE_UNKNOWN6 = 6, // | not used
AURA_STATE_HUNTER_PARRY = 7, // C |
AURA_STATE_ROGUE_ATTACK_FROM_STEALTH = 7, // C | FIX ME: not implemented yet!
- //AURA_STATE_UNKNOWN7c = 7, // c | random/focused bursts spells (?)
+ //AURA_STATE_UNKNOWN7 = 7, // c | random/focused bursts spells (?)
//AURA_STATE_UNKNOWN8 = 8, // | not used
//AURA_STATE_UNKNOWN9 = 9, // | not used
AURA_STATE_WARRIOR_VICTORY_RUSH = 10, // C | warrior victory rush
- AURA_STATE_HUNTER_CRIT_STRIKE = 10, // C | hunter crit strike
- AURA_STATE_CRIT = 11, // C |
+ //AURA_STATE_UNKNOWN11 = 11, // t|
AURA_STATE_FAERIE_FIRE = 12, // c t|
AURA_STATE_HEALTHLESS_35_PERCENT = 13, // C T |
AURA_STATE_IMMOLATE = 14, // T |
AURA_STATE_SWIFTMEND = 15, // T |
AURA_STATE_DEADLY_POISON = 16, // T |
- AURA_STATE_FORBEARANCE = 17, // c t|
- AURA_STATE_WEAKENED_SOUL = 18, // t|
- AURA_STATE_HYPOTHERMIA = 19 // c |
+ AURA_STATE_ENRAGE = 17, // C |
+ //AURA_STATE_UNKNOWN18 = 18, // C t|
+ //AURA_STATE_UNKNOWN19 = 19, // | not used
+ //AURA_STATE_UNKNOWN20 = 20, // c | only (45317 Suicide)
+ //AURA_STATE_UNKNOWN21 = 21, // | not used
+ //AURA_STATE_UNKNOWN22 = 22, // C | not implemented yet (Requires Evasive Charges to use)
+ AURA_STATE_HEALTH_ABOVE_75_PERCENT = 23, // C |
};
// Spell mechanics
@@ -711,11 +728,11 @@ enum Mechanics
{
MECHANIC_NONE = 0,
MECHANIC_CHARM = 1,
- MECHANIC_CONFUSED = 2,
+ MECHANIC_DISORIENTED = 2,
MECHANIC_DISARM = 3,
MECHANIC_DISTRACT = 4,
MECHANIC_FEAR = 5,
- MECHANIC_FUMBLE = 6,
+ MECHANIC_GRIP = 6,
MECHANIC_ROOT = 7,
MECHANIC_PACIFY = 8, //0 spells use this mechanic
MECHANIC_SILENCE = 9,
@@ -731,7 +748,7 @@ enum Mechanics
MECHANIC_SHIELD = 19,
MECHANIC_SHACKLE = 20,
MECHANIC_MOUNT = 21,
- MECHANIC_PERSUADE = 22, //0 spells use this mechanic
+ MECHANIC_INFECTED = 22,
MECHANIC_TURN = 23,
MECHANIC_HORROR = 24,
MECHANIC_INVULNERABILITY = 25,
@@ -739,12 +756,13 @@ enum Mechanics
MECHANIC_DAZE = 27,
MECHANIC_DISCOVERY = 28,
MECHANIC_IMMUNE_SHIELD = 29, // Divine (Blessing) Shield/Protection and Ice Block
- MECHANIC_SAPPED = 30
+ MECHANIC_SAPPED = 30,
+ MECHANIC_ENRAGED = 31
};
// Used for spell 42292 Immune Movement Impairment and Loss of Control (0x49967da6)
#define IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK ( \
- (1<<MECHANIC_CHARM )|(1<<MECHANIC_CONFUSED )|(1<<MECHANIC_FEAR )| \
+ (1<<MECHANIC_CHARM )|(1<<MECHANIC_DISORIENTED )|(1<<MECHANIC_FEAR )| \
(1<<MECHANIC_ROOT )|(1<<MECHANIC_PACIFY )|(1<<MECHANIC_SLEEP )| \
(1<<MECHANIC_SNARE )|(1<<MECHANIC_STUN )|(1<<MECHANIC_FREEZE)| \
(1<<MECHANIC_KNOCKOUT)|(1<<MECHANIC_POLYMORPH)|(1<<MECHANIC_BANISH)| \
@@ -764,7 +782,8 @@ enum DispelType
DISPEL_ALL = 7,
DISPEL_SPE_NPC_ONLY = 8,
DISPEL_ENRAGE = 9,
- DISPEL_ZG_TICKET = 10
+ DISPEL_ZG_TICKET = 10,
+ DESPEL_OLD_UNUSED = 11
};
#define DISPEL_ALL_MASK ( (1<<DISPEL_MAGIC) | (1<<DISPEL_CURSE) | (1<<DISPEL_DISEASE) | (1<<DISPEL_POISON) )
@@ -790,10 +809,9 @@ enum Targets
{
TARGET_SELF = 1,
TARGET_UNIT_CASTER = 1,
- TARGET_RANDOM_ENEMY_CHAIN_IN_AREA = 2, // only one spell has that, but regardless, it's a target type after all
- //TARGET_UNIT_NEARBY_ENEMY
- TARGET_UNIT_SINGLE_UNKNOWN = 3,
- TARGET_UNIT_NEARBY_ALLY = 4,
+ TARGET_UNIT_NEARBY_ENEMY = 2,
+ TARGET_UNIT_NEARBY_ALLY = 3,
+ TARGET_UNIT_NEARBY_ALLY_UNK = 4,
TARGET_PET = 5,
TARGET_UNIT_PET = 5,
TARGET_CHAIN_DAMAGE = 6,
@@ -816,7 +834,6 @@ enum Targets
TARGET_UNIT_PARTY_CASTER = 20,
TARGET_SINGLE_FRIEND = 21,
TARGET_UNIT_TARGET_ALLY = 21,
- TARGET_ALL_AROUND_CASTER = 22, // used only in TargetA, target selection dependent from TargetB
TARGET_DEST_CASTER = 22,
TARGET_GAMEOBJECT = 23,
//TARGET_OBJECT_OPEN
@@ -986,9 +1003,10 @@ enum GameobjectTypes
GAMEOBJECT_TYPE_BARBER_CHAIR = 32,
GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING = 33,
GAMEOBJECT_TYPE_GUILD_BANK = 34,
+ GAMEOBJECT_TYPE_TRAPDOOR = 35
};
-#define MAX_GAMEOBJECT_TYPE 35 // sending to client this or greater value can crash client.
+#define MAX_GAMEOBJECT_TYPE 36 // sending to client this or greater value can crash client.
#define GAMEOBJECT_FISHINGNODE_ENTRY 35591 // Better to define it somewhere instead of hardcoding everywhere
@@ -1555,7 +1573,9 @@ enum LockType
LOCKTYPE_BLASTING = 16,
LOCKTYPE_SLOW_OPEN = 17,
LOCKTYPE_SLOW_CLOSE = 18,
- LOCKTYPE_FISHING = 19
+ LOCKTYPE_FISHING = 19,
+ LOCKTYPE_INSCRIPTION = 20,
+ LOCKTYPE_OPEN_FROM_VEHICLE = 21
};
enum TrainerType // this is important type for npcs!
@@ -1568,6 +1588,7 @@ enum TrainerType // this is important
#define MAX_TRAINER_TYPE 4
+// CreatureType.dbc
enum CreatureType
{
CREATURE_TYPE_BEAST = 1,
@@ -1587,6 +1608,7 @@ enum CreatureType
uint32 const CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD = (1 << (CREATURE_TYPE_HUMANOID-1)) | (1 << (CREATURE_TYPE_UNDEAD-1));
+// CreatureFamily.dbc
enum CreatureFamily
{
CREATURE_FAMILY_WOLF = 1,
@@ -1598,6 +1620,7 @@ enum CreatureFamily
CREATURE_FAMILY_CARRION_BIRD = 7,
CREATURE_FAMILY_CRAB = 8,
CREATURE_FAMILY_GORILLA = 9,
+ CREATURE_FAMILY_HORSE_CUSTOM = 10, // not exist in DBC but used for horse like beasts in DB
CREATURE_FAMILY_RAPTOR = 11,
CREATURE_FAMILY_TALLSTRIDER = 12,
CREATURE_FAMILY_FELHUNTER = 15,
@@ -1609,7 +1632,7 @@ enum CreatureFamily
CREATURE_FAMILY_IMP = 23,
CREATURE_FAMILY_BAT = 24,
CREATURE_FAMILY_HYENA = 25,
- CREATURE_FAMILY_OWL = 26,
+ CREATURE_FAMILY_BIRD_OF_PREY = 26,
CREATURE_FAMILY_WIND_SERPENT = 27,
CREATURE_FAMILY_REMOTE_CONTROL = 28,
CREATURE_FAMILY_FELGUARD = 29,
@@ -1619,14 +1642,24 @@ enum CreatureFamily
CREATURE_FAMILY_SPOREBAT = 33,
CREATURE_FAMILY_NETHER_RAY = 34,
CREATURE_FAMILY_SERPENT = 35,
- CREATURE_FAMILY_SEA_LION = 36
+ CREATURE_FAMILY_MOTH = 37,
+ CREATURE_FAMILY_CHIMAERA = 38,
+ CREATURE_FAMILY_DEVILSAUR = 39,
+ CREATURE_FAMILY_GHOUL = 40,
+ CREATURE_FAMILY_SILITHID = 41,
+ CREATURE_FAMILY_WORM = 42,
+ CREATURE_FAMILY_RHINO = 43,
+ CREATURE_FAMILY_WASP = 44,
+ CREATURE_FAMILY_CORE_HOUND = 45,
+ CREATURE_FAMILY_SPIRIT_BEAST = 46
};
enum CreatureTypeFlags
{
- CREATURE_TYPEFLAGS_TAMEABLE = 0x0001,
- CREATURE_TYPEFLAGS_HERBLOOT = 0x0100,
- CREATURE_TYPEFLAGS_MININGLOOT = 0x0200
+ CREATURE_TYPEFLAGS_TAMEABLE = 0x0001,
+ CREATURE_TYPEFLAGS_HERBLOOT = 0x0100,
+ CREATURE_TYPEFLAGS_MININGLOOT = 0x0200,
+ CREATURE_TYPEFLAGS_ENGINEERLOOT = 0x8000
};
enum CreatureEliteType
@@ -1651,6 +1684,8 @@ enum QuestTypes
QUEST_TYPE_LEGENDARY = 83,
QUEST_TYPE_ESCORT = 84,
QUEST_TYPE_HEROIC = 85,
+ QUEST_TYPE_RAID_10 = 88,
+ QUEST_TYPE_RAID_25 = 89
};
// values based at QuestSort.dbc
@@ -1661,7 +1696,7 @@ enum QuestSort
QUEST_SORT_SEASONAL = 22,
QUEST_SORT_UNDERCITY_OLD = 23,
QUEST_SORT_HERBALISM = 24,
- QUEST_SORT_SCARLET_MONASTERY_OLD= 25,
+ QUEST_SORT_BATTLEGROUNDS = 25,
QUEST_SORT_ULDAMN_OLD = 41,
QUEST_SORT_WARLOCK = 61,
QUEST_SORT_WARRIOR = 81,
@@ -1690,22 +1725,26 @@ enum QuestSort
QUEST_SORT_REPUTATION = 367,
QUEST_SORT_INVASION = 368,
QUEST_SORT_MIDSUMMER = 369,
- QUEST_SORT_BREWFEST = 370
+ QUEST_SORT_BREWFEST = 370,
+ QUEST_SORT_INSCRIPTION = 371,
+ QUEST_SORT_DEATH_KNIGHT = 372,
+ QUEST_SORT_JEWELCRAFTING = 373
};
inline uint8 ClassByQuestSort(int32 QuestSort)
{
switch(QuestSort)
{
- case QUEST_SORT_WARLOCK: return CLASS_WARLOCK;
- case QUEST_SORT_WARRIOR: return CLASS_WARRIOR;
- case QUEST_SORT_SHAMAN: return CLASS_SHAMAN;
- case QUEST_SORT_PALADIN: return CLASS_PALADIN;
- case QUEST_SORT_MAGE: return CLASS_MAGE;
- case QUEST_SORT_ROGUE: return CLASS_ROGUE;
- case QUEST_SORT_HUNTER: return CLASS_HUNTER;
- case QUEST_SORT_PRIEST: return CLASS_PRIEST;
- case QUEST_SORT_DRUID: return CLASS_DRUID;
+ case QUEST_SORT_WARLOCK: return CLASS_WARLOCK;
+ case QUEST_SORT_WARRIOR: return CLASS_WARRIOR;
+ case QUEST_SORT_SHAMAN: return CLASS_SHAMAN;
+ case QUEST_SORT_PALADIN: return CLASS_PALADIN;
+ case QUEST_SORT_MAGE: return CLASS_MAGE;
+ case QUEST_SORT_ROGUE: return CLASS_ROGUE;
+ case QUEST_SORT_HUNTER: return CLASS_HUNTER;
+ case QUEST_SORT_PRIEST: return CLASS_PRIEST;
+ case QUEST_SORT_DRUID: return CLASS_DRUID;
+ case QUEST_SORT_DEATH_KNIGHT: return CLASS_DEATH_KNIGHT;
}
return 0;
}
@@ -1717,7 +1756,6 @@ enum SkillType
SKILL_ARMS = 26,
SKILL_COMBAT = 38,
SKILL_SUBTLETY = 39,
- SKILL_POISONS = 40,
SKILL_SWORDS = 43,
SKILL_AXES = 44,
SKILL_BOWS = 45,
@@ -1725,8 +1763,8 @@ enum SkillType
SKILL_BEAST_MASTERY = 50,
SKILL_SURVIVAL = 51,
SKILL_MACES = 54,
- SKILL_HOLY = 56,
SKILL_2H_SWORDS = 55,
+ SKILL_HOLY = 56,
SKILL_SHADOW = 78,
SKILL_DEFENSE = 95,
SKILL_LANG_COMMON = 98,
@@ -1782,24 +1820,20 @@ enum SkillType
SKILL_PET_BOAR = 211,
SKILL_PET_CROCILISK = 212,
SKILL_PET_CARRION_BIRD = 213,
- SKILL_PET_GORILLA = 215,
SKILL_PET_CRAB = 214,
+ SKILL_PET_GORILLA = 215,
SKILL_PET_RAPTOR = 217,
SKILL_PET_TALLSTRIDER = 218,
SKILL_RACIAL_UNDED = 220,
- SKILL_WEAPON_TALENTS = 222,
SKILL_CROSSBOWS = 226,
- SKILL_SPEARS = 227,
SKILL_WANDS = 228,
SKILL_POLEARMS = 229,
SKILL_PET_SCORPID = 236,
SKILL_ARCANE = 237,
- SKILL_OPEN_LOCK = 242,
SKILL_PET_TURTLE = 251,
SKILL_ASSASSINATION = 253,
SKILL_FURY = 256,
SKILL_PROTECTION = 257,
- SKILL_BEAST_TRAINING = 261,
SKILL_PROTECTION2 = 267,
SKILL_PET_TALENTS = 270,
SKILL_PLATE_MAIL = 293,
@@ -1829,7 +1863,7 @@ enum SkillType
SKILL_LOCKPICKING = 633,
SKILL_PET_BAT = 653,
SKILL_PET_HYENA = 654,
- SKILL_PET_OWL = 655,
+ SKILL_PET_BIRD_OF_PREY = 655,
SKILL_PET_WIND_SERPENT = 656,
SKILL_LANG_GUTTERSPEAK = 673,
SKILL_RIDING_KODO = 713,
@@ -1849,10 +1883,27 @@ enum SkillType
SKILL_PET_WARP_STALKER = 766,
SKILL_PET_RAVAGER = 767,
SKILL_PET_SERPENT = 768,
- SKILL_INTERNAL = 769
+ SKILL_INTERNAL = 769,
+ SKILL_DK_BLOOD = 770,
+ SKILL_DK_FROST = 771,
+ SKILL_DK_UNHOLY = 772,
+ SKILL_INSCRIPTION = 773,
+ SKILL_PET_MOTH = 775,
+ SKILL_RUNEFORGING = 776,
+ SKILL_MOUNTS = 777,
+ SKILL_COMPANIONS = 778,
+ SKILL_PET_EXOTIC_CHIMAERA = 780,
+ SKILL_PET_EXOTIC_DEVILSAUR = 781,
+ SKILL_PET_GHOUL = 782,
+ SKILL_PET_EXOTIC_SILITHID = 783,
+ SKILL_PET_EXOTIC_WORM = 784,
+ SKILL_PET_WASP = 785,
+ SKILL_PET_EXOTIC_RHINO = 786,
+ SKILL_PET_EXOTIC_CORE_HOUND = 787,
+ SKILL_PET_EXOTIC_SPIRIT_BEAST = 788
};
-#define MAX_SKILL_TYPE 770
+#define MAX_SKILL_TYPE 789
inline uint32 SkillByQuestSort(int32 QuestSort)
{
@@ -1867,25 +1918,27 @@ inline uint32 SkillByQuestSort(int32 QuestSort)
case QUEST_SORT_TAILORING: return SKILL_TAILORING;
case QUEST_SORT_COOKING: return SKILL_COOKING;
case QUEST_SORT_FIRST_AID: return SKILL_FIRST_AID;
+ case QUEST_SORT_JEWELCRAFTING: return SKILL_JEWELCRAFTING;
+ case QUEST_SORT_INSCRIPTION: return SKILL_INSCRIPTION;
}
return 0;
}
enum SkillCategory
{
- SKILL_CATEGORY_ATTRIBUTES = 5,
- SKILL_CATEGORY_WEAPON = 6,
- SKILL_CATEGORY_CLASS = 7,
- SKILL_CATEGORY_ARMOR = 8,
- SKILL_CATEGORY_SECONDARY = 9, // secondary professions
+ SKILL_CATEGORY_ATTRIBUTES = 5,
+ SKILL_CATEGORY_WEAPON = 6,
+ SKILL_CATEGORY_CLASS = 7,
+ SKILL_CATEGORY_ARMOR = 8,
+ SKILL_CATEGORY_SECONDARY = 9, // secondary professions
SKILL_CATEGORY_LANGUAGES = 10,
SKILL_CATEGORY_PROFESSION = 11, // primary professions
- SKILL_CATEGORY_NOT_DISPLAYED = 12
+ SKILL_CATEGORY_GENERIC = 12
};
enum TotemCategory
{
- TC_SKINNING_SKIFE = 1,
+ TC_SKINNING_SKIFE_OLD = 1,
TC_EARTH_TOTEM = 2,
TC_AIR_TOTEM = 3,
TC_FIRE_TOTEM = 4,
@@ -1895,15 +1948,28 @@ enum TotemCategory
TC_GOLDEN_ROD = 8,
TC_TRUESILVER_ROD = 9,
TC_ARCANITE_ROD = 10,
- TC_MINING_PICK = 11,
+ TC_MINING_PICK_OLD = 11,
TC_PHILOSOPHERS_STONE = 12,
- TC_BLACKSMITH_HAMMER = 13,
+ TC_BLACKSMITH_HAMMER_OLD = 13,
TC_ARCLIGHT_SPANNER = 14,
TC_GYROMATIC_MA = 15,
TC_MASTER_TOTEM = 21,
TC_FEL_IRON_ROD = 41,
TC_ADAMANTITE_ROD = 62,
- TC_ETERNIUM_ROD = 63
+ TC_ETERNIUM_ROD = 63,
+ TC_HOLLOW_QUILL = 81,
+ TC_RUNED_AZURITE_ROD = 101,
+ TC_VIRTUOSO_INKING_SET = 121,
+ TC_DRUMS = 141,
+ TC_GNOMISH_ARMY_KNIFE = 161,
+ TC_BLACKSMITH_HAMMER = 162,
+ TC_MINING_PICK = 165,
+ TC_SKINNING_KNIFE = 166,
+ TC_HAMMER_PICK = 167,
+ TC_BLADED_PICKAXE = 168,
+ TC_FLINT_AND_TINDER = 169,
+ TC_RUNED_COBALT_ROD = 189,
+ TC_RUNED_TITANIUM_ROD = 190
};
enum UnitDynFlags
@@ -1913,7 +1979,8 @@ enum UnitDynFlags
UNIT_DYNFLAG_OTHER_TAGGER = 0x0004,
UNIT_DYNFLAG_ROOTED = 0x0008,
UNIT_DYNFLAG_SPECIALINFO = 0x0010,
- UNIT_DYNFLAG_DEAD = 0x0020
+ UNIT_DYNFLAG_DEAD = 0x0020,
+ UNIT_DYNFLAG_REFER_A_FRIEND = 0x0040
};
enum CorpseDynFlags
@@ -1922,11 +1989,14 @@ enum CorpseDynFlags
};
// Passive Spell codes explicit used in code
-#define SPELL_ID_GENERIC_LEARN 483
-#define SPELL_ID_PASSIVE_BATTLE_STANCE 2457
-#define SPELL_ID_PASSIVE_RESURRECTION_SICKNESS 15007
-#define SPELL_ID_WEAPON_SWITCH_COOLDOWN_1_5s 6119
-#define SPELL_ID_WEAPON_SWITCH_COOLDOWN_1_0s 6123
+#define SPELL_ID_GENERIC_LEARN 483
+#define SPELL_ID_GENERIC_LEARN_PET 55884 // used for learning mounts and companions
+#define SPELL_ID_PASSIVE_BATTLE_STANCE 2457
+#define SPELL_ID_PASSIVE_RESURRECTION_SICKNESS 15007
+#define SPELL_ID_WEAPON_SWITCH_COOLDOWN_1_5s 6119
+#define SPELL_ID_WEAPON_SWITCH_COOLDOWN_1_0s 6123
+#define SPELL_ID_AUTOSHOT 75 // used for checks in other spells interruption
+#define SPELL_ID_SHADOWMELD 58984 // used for check ignore stealth stance state
enum WeatherType
{
@@ -1990,9 +2060,12 @@ enum ChatMsg
CHAT_MSG_BATTLEGROUND = 0x2C,
CHAT_MSG_BATTLEGROUND_LEADER = 0x2D,
CHAT_MSG_RESTRICTED = 0x2E,
+ CHAT_MSG_BN = 0x2F,
+ CHAT_MSG_ACHIEVEMENT = 0x30,
+ CHAT_MSG_GUILD_ACHIEVEMENT = 0x31
};
-#define MAX_CHAT_MSG_TYPE 0x2F
+#define MAX_CHAT_MSG_TYPE 0x32
// Values from ItemPetFood (power of (value-1) used for compare with CreatureFamilyEntry.petDietMask
enum PetDiet
@@ -2092,7 +2165,9 @@ enum SummonType
SUMMON_TYPE_CRITTER3 = 307,
SUMMON_TYPE_UNKNOWN5 = 409,
SUMMON_TYPE_POSESSED3 = 427,
- SUMMON_TYPE_POSESSED2 = 428
+ SUMMON_TYPE_POSESSED2 = 428,
+ SUMMON_TYPE_FORCE_OF_NATURE = 669,
+ SUMMON_TYPE_GUARDIAN2 = 1161
};
enum ResponseCodes
@@ -2161,42 +2236,45 @@ enum ResponseCodes
CHAR_CREATE_SERVER_QUEUE = 0x37,
CHAR_CREATE_ONLY_EXISTING = 0x38,
CHAR_CREATE_EXPANSION = 0x39,
-
- CHAR_DELETE_IN_PROGRESS = 0x3A,
- CHAR_DELETE_SUCCESS = 0x3B,
- CHAR_DELETE_FAILED = 0x3C,
- CHAR_DELETE_FAILED_LOCKED_FOR_TRANSFER = 0x3D,
- CHAR_DELETE_FAILED_GUILD_LEADER = 0x3E,
- CHAR_DELETE_FAILED_ARENA_CAPTAIN = 0x3F,
-
- CHAR_LOGIN_IN_PROGRESS = 0x40,
- CHAR_LOGIN_SUCCESS = 0x41,
- CHAR_LOGIN_NO_WORLD = 0x42,
- CHAR_LOGIN_DUPLICATE_CHARACTER = 0x43,
- CHAR_LOGIN_NO_INSTANCES = 0x44,
- CHAR_LOGIN_FAILED = 0x45,
- CHAR_LOGIN_DISABLED = 0x46,
- CHAR_LOGIN_NO_CHARACTER = 0x47,
- CHAR_LOGIN_LOCKED_FOR_TRANSFER = 0x48,
- CHAR_LOGIN_LOCKED_BY_BILLING = 0x49,
-
- CHAR_NAME_SUCCESS = 0x4A,
- CHAR_NAME_FAILURE = 0x4B,
- CHAR_NAME_NO_NAME = 0x4C,
- CHAR_NAME_TOO_SHORT = 0x4D,
- CHAR_NAME_TOO_LONG = 0x4E,
- CHAR_NAME_INVALID_CHARACTER = 0x4F,
- CHAR_NAME_MIXED_LANGUAGES = 0x50,
- CHAR_NAME_PROFANE = 0x51,
- CHAR_NAME_RESERVED = 0x52,
- CHAR_NAME_INVALID_APOSTROPHE = 0x53,
- CHAR_NAME_MULTIPLE_APOSTROPHES = 0x54,
- CHAR_NAME_THREE_CONSECUTIVE = 0x55,
- CHAR_NAME_INVALID_SPACE = 0x56,
- CHAR_NAME_CONSECUTIVE_SPACES = 0x57,
- CHAR_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS = 0x58,
- CHAR_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END = 0x59,
- CHAR_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 0x5A,
+ CHAR_CREATE_EXPANSION_CLASS = 0x3A,
+ CHAR_CREATE_LEVEL_REQUIREMENT = 0x3B,
+ CHAR_CREATE_UNIQUE_CLASS_LIMIT = 0x3C,
+
+ CHAR_DELETE_IN_PROGRESS = 0x3D,
+ CHAR_DELETE_SUCCESS = 0x3E,
+ CHAR_DELETE_FAILED = 0x3F,
+ CHAR_DELETE_FAILED_LOCKED_FOR_TRANSFER = 0x40,
+ CHAR_DELETE_FAILED_GUILD_LEADER = 0x41,
+ CHAR_DELETE_FAILED_ARENA_CAPTAIN = 0x42,
+
+ CHAR_LOGIN_IN_PROGRESS = 0x43,
+ CHAR_LOGIN_SUCCESS = 0x44,
+ CHAR_LOGIN_NO_WORLD = 0x45,
+ CHAR_LOGIN_DUPLICATE_CHARACTER = 0x46,
+ CHAR_LOGIN_NO_INSTANCES = 0x47,
+ CHAR_LOGIN_FAILED = 0x48,
+ CHAR_LOGIN_DISABLED = 0x49,
+ CHAR_LOGIN_NO_CHARACTER = 0x4A,
+ CHAR_LOGIN_LOCKED_FOR_TRANSFER = 0x4B,
+ CHAR_LOGIN_LOCKED_BY_BILLING = 0x4C,
+
+ CHAR_NAME_SUCCESS = 0x4D,
+ CHAR_NAME_FAILURE = 0x4E,
+ CHAR_NAME_NO_NAME = 0x4F,
+ CHAR_NAME_TOO_SHORT = 0x50,
+ CHAR_NAME_TOO_LONG = 0x51,
+ CHAR_NAME_INVALID_CHARACTER = 0x52,
+ CHAR_NAME_MIXED_LANGUAGES = 0x53,
+ CHAR_NAME_PROFANE = 0x54,
+ CHAR_NAME_RESERVED = 0x55,
+ CHAR_NAME_INVALID_APOSTROPHE = 0x56,
+ CHAR_NAME_MULTIPLE_APOSTROPHES = 0x57,
+ CHAR_NAME_THREE_CONSECUTIVE = 0x58,
+ CHAR_NAME_INVALID_SPACE = 0x59,
+ CHAR_NAME_CONSECUTIVE_SPACES = 0x5A,
+ CHAR_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS = 0x5B,
+ CHAR_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END = 0x5C,
+ CHAR_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 0x5D
};
/// Ban function modes
@@ -2214,4 +2292,22 @@ enum BanReturn
BAN_SYNTAX_ERROR,
BAN_NOTFOUND
};
+
+// indexes of BattlemasterList.dbc
+enum BattleGroundTypeId
+{
+ BATTLEGROUND_AV = 1,
+ BATTLEGROUND_WS = 2,
+ BATTLEGROUND_AB = 3,
+ BATTLEGROUND_NA = 4,
+ BATTLEGROUND_BE = 5,
+ BATTLEGROUND_AA = 6,
+ BATTLEGROUND_EY = 7,
+ BATTLEGROUND_RL = 8,
+ BATTLEGROUND_SA = 9,
+ BATTLEGROUND_DS = 10,
+ BATTLEGROUND_RV = 11
+};
+#define MAX_BATTLEGROUND_TYPE_ID 12
+
#endif
diff --git a/src/game/SkillDiscovery.cpp b/src/game/SkillDiscovery.cpp
index 2a1c6ec9d82..f5e79bf220b 100644
--- a/src/game/SkillDiscovery.cpp
+++ b/src/game/SkillDiscovery.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -31,14 +31,15 @@
struct SkillDiscoveryEntry
{
- uint32 spellId;
- float chance;
+ uint32 spellId; // discavered spell
+ uint32 reqSkillValue; // skill level limitation
+ float chance; // chance
SkillDiscoveryEntry()
- : spellId(0), chance(0) {}
+ : spellId(0), reqSkillValue(0), chance(0) {}
- SkillDiscoveryEntry(uint16 _spellId, float _chance)
- : spellId(_spellId), chance(_chance) {}
+ SkillDiscoveryEntry(uint16 _spellId, uint32 req_skill_val, float _chance)
+ : spellId(_spellId), reqSkillValue(req_skill_val), chance(_chance) {}
};
typedef std::list<SkillDiscoveryEntry> SkillDiscoveryList;
@@ -53,8 +54,8 @@ void LoadSkillDiscoveryTable()
uint32 count = 0;
- // 0 1 2
- QueryResult *result = WorldDatabase.Query("SELECT spellId, reqSpell, chance FROM skill_discovery_template");
+ // 0 1 2 3
+ QueryResult *result = WorldDatabase.Query("SELECT spellId, reqSpell, reqSkillValue, chance FROM skill_discovery_template");
if (result)
{
@@ -69,11 +70,13 @@ void LoadSkillDiscoveryTable()
uint32 spellId = fields[0].GetUInt32();
int32 reqSkillOrSpell = fields[1].GetInt32();
- float chance = fields[2].GetFloat();
+ uint32 reqSkillValue = fields[2].GetInt32();
+ float chance = fields[3].GetFloat();
if( chance <= 0 ) // chance
{
- ssNonDiscoverableEntries << "spellId = " << spellId << " reqSkillOrSpell = " << reqSkillOrSpell << " chance = " << chance << "\n";
+ ssNonDiscoverableEntries << "spellId = " << spellId << " reqSkillOrSpell = " << reqSkillOrSpell
+ << " reqSkillValue = " << reqSkillValue << " chance = " << chance << "(chance problem)\n";
continue;
}
@@ -86,13 +89,16 @@ void LoadSkillDiscoveryTable()
continue;
}
- if( spellEntry->Mechanic != MECHANIC_DISCOVERY )
+ // mechanic discovery
+ if (spellEntry->Mechanic != MECHANIC_DISCOVERY &&
+ // explicit discovery ability
+ !IsExplicitDiscoverySpell(spellEntry))
{
- sLog.outErrorDb("Spell (ID: %u) not have have MECHANIC_DISCOVERY (28) value in Mechanic field in spell.dbc but listed in `skill_discovery_template` table",spellId);
+ sLog.outErrorDb("Spell (ID: %u) not have have MECHANIC_DISCOVERY (28) value in Mechanic field in spell.dbc and not 100% chance random discovery ability but listed in `skill_discovery_template` table",spellId);
continue;
}
- SkillDiscoveryStore[reqSkillOrSpell].push_back( SkillDiscoveryEntry(spellId, chance) );
+ SkillDiscoveryStore[reqSkillOrSpell].push_back( SkillDiscoveryEntry(spellId, reqSkillValue, chance) );
}
else if( reqSkillOrSpell == 0 ) // skill case
{
@@ -107,7 +113,7 @@ void LoadSkillDiscoveryTable()
for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
{
- SkillDiscoveryStore[-int32(_spell_idx->second->skillId)].push_back( SkillDiscoveryEntry(spellId, chance) );
+ SkillDiscoveryStore[-int32(_spell_idx->second->skillId)].push_back( SkillDiscoveryEntry(spellId, reqSkillValue, chance) );
}
}
else
@@ -115,6 +121,7 @@ void LoadSkillDiscoveryTable()
sLog.outErrorDb("Spell (ID: %u) have negative value in `reqSpell` field in `skill_discovery_template` table",spellId);
continue;
}
+
++count;
} while (result->NextRow());
@@ -132,8 +139,48 @@ void LoadSkillDiscoveryTable()
}
}
+uint32 GetExplicitDiscoverySpell(uint32 spellId, Player* player)
+{
+ // explicit discovery spell chances (always success if case exist)
+ // in this case we have both skill and spell
+ SkillDiscoveryMap::iterator tab = SkillDiscoveryStore.find(spellId);
+ if(tab == SkillDiscoveryStore.end())
+ return 0;
+
+ SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(spellId);
+ SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(spellId);
+ uint32 skillvalue = lower != upper ? player->GetSkillValue(lower->second->skillId) : 0;
+
+ float full_chance = 0;
+ for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter)
+ if(item_iter->reqSkillValue <= skillvalue)
+ if(!player->HasSpell(item_iter->spellId))
+ full_chance += item_iter->chance;
+
+ float rate = full_chance / 100.0f;
+ float roll = rand_chance() * rate; // roll now in range 0..full_chance
+
+ for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter)
+ {
+ if(item_iter->reqSkillValue > skillvalue)
+ continue;
+
+ if(player->HasSpell(item_iter->spellId))
+ continue;
+
+ if(item_iter->chance > roll)
+ return item_iter->spellId;
+
+ roll -= item_iter->chance;
+ }
+
+ return 0;
+}
+
uint32 GetSkillDiscoverySpell(uint32 skillId, uint32 spellId, Player* player)
{
+ uint32 skillvalue = skillId ? player->GetSkillValue(skillId) : 0;
+
// check spell case
SkillDiscoveryMap::iterator tab = SkillDiscoveryStore.find(spellId);
@@ -142,6 +189,7 @@ uint32 GetSkillDiscoverySpell(uint32 skillId, uint32 spellId, Player* player)
for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter)
{
if( roll_chance_f(item_iter->chance * sWorld.getRate(RATE_SKILL_DISCOVERY))
+ && item_iter->reqSkillValue <= skillvalue
&& !player->HasSpell(item_iter->spellId) )
return item_iter->spellId;
}
@@ -149,6 +197,9 @@ uint32 GetSkillDiscoverySpell(uint32 skillId, uint32 spellId, Player* player)
return 0;
}
+ if(!skillId)
+ return 0;
+
// check skill line case
tab = SkillDiscoveryStore.find(-(int32)skillId);
if(tab != SkillDiscoveryStore.end())
@@ -156,6 +207,7 @@ uint32 GetSkillDiscoverySpell(uint32 skillId, uint32 spellId, Player* player)
for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter)
{
if( roll_chance_f(item_iter->chance * sWorld.getRate(RATE_SKILL_DISCOVERY))
+ && item_iter->reqSkillValue <= skillvalue
&& !player->HasSpell(item_iter->spellId) )
return item_iter->spellId;
}
diff --git a/src/game/SkillDiscovery.h b/src/game/SkillDiscovery.h
index bdd126e0cb3..9ee29c86810 100644
--- a/src/game/SkillDiscovery.h
+++ b/src/game/SkillDiscovery.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -27,4 +27,5 @@ class Player;
void LoadSkillDiscoveryTable();
uint32 GetSkillDiscoverySpell(uint32 skillId, uint32 spellId, Player* player);
+uint32 GetExplicitDiscoverySpell(uint32 spellId, Player* player);
#endif
diff --git a/src/game/SkillExtraItems.cpp b/src/game/SkillExtraItems.cpp
index d4d46d8611d..67ec9719659 100644
--- a/src/game/SkillExtraItems.cpp
+++ b/src/game/SkillExtraItems.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/SkillExtraItems.h b/src/game/SkillExtraItems.h
index 904136cd9d3..5d71d8fd753 100644
--- a/src/game/SkillExtraItems.h
+++ b/src/game/SkillExtraItems.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/SkillHandler.cpp b/src/game/SkillHandler.cpp
index 56e48bf75c4..58c35fe463e 100644
--- a/src/game/SkillHandler.cpp
+++ b/src/game/SkillHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -82,10 +82,6 @@ void WorldSession::HandleLearnTalentOpcode( WorldPacket & recv_data )
}
}
- // Check if it requires spell
- if( talentInfo->DependsOnSpell && !player->HasSpell(talentInfo->DependsOnSpell) )
- return;
-
// Find out how many points we have in this field
uint32 spentPoints = 0;
@@ -133,7 +129,7 @@ void WorldSession::HandleLearnTalentOpcode( WorldPacket & recv_data )
return;
// learn! (other talent ranks will unlearned at learning)
- GetPlayer( )->learnSpell(spellid);
+ GetPlayer( )->learnSpell(spellid,false);
sLog.outDetail("TalentID: %u Rank: %u Spell: %u\n", talent_id, requested_rank, spellid);
// update free talent points
diff --git a/src/game/SocialMgr.cpp b/src/game/SocialMgr.cpp
index baabe9b043f..a0851264451 100644
--- a/src/game/SocialMgr.cpp
+++ b/src/game/SocialMgr.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -182,13 +182,6 @@ SocialMgr::~SocialMgr()
}
-void SocialMgr::RemovePlayerSocial(uint32 guid)
-{
- SocialMap::iterator itr = m_socialMap.find(guid);
- if(itr != m_socialMap.end())
- m_socialMap.erase(itr);
-}
-
void SocialMgr::GetFriendInfo(Player *player, uint32 friendGUID, FriendInfo &friendInfo)
{
if(!player)
diff --git a/src/game/SocialMgr.h b/src/game/SocialMgr.h
index 1cc14589e51..864cf8b2455 100644
--- a/src/game/SocialMgr.h
+++ b/src/game/SocialMgr.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -143,7 +143,8 @@ class SocialMgr
SocialMgr();
~SocialMgr();
// Misc
- void RemovePlayerSocial(uint32 guid);
+ void RemovePlayerSocial(uint32 guid) { m_socialMap.erase(guid); }
+
void GetFriendInfo(Player *player, uint32 friendGUID, FriendInfo &friendInfo);
// Packet management
void MakeFriendStatusPacket(FriendsResult result, uint32 friend_guid, WorldPacket *data);
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index d7d9446ab50..8d8f47f6379 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -43,7 +43,6 @@
#include "CellImpl.h"
#include "Policies/SingletonImp.h"
#include "SharedDefines.h"
-#include "Tools.h"
#include "LootMgr.h"
#include "VMapFactory.h"
#include "BattleGround.h"
@@ -120,6 +119,14 @@ void SpellCastTargets::setDestination(Unit *target, bool send)
m_targetMask |= TARGET_FLAG_DEST_LOCATION;
}
+void SpellCastTargets::setSource(float x, float y, float z)
+{
+ m_srcX = x;
+ m_srcY = y;
+ m_srcZ = z;
+ m_targetMask |= TARGET_FLAG_SOURCE_LOCATION;
+}
+
void SpellCastTargets::setGOTarget(GameObject *target)
{
m_GOTarget = target;
@@ -178,16 +185,20 @@ bool SpellCastTargets::read ( WorldPacket * data, Unit *caster )
return true;
// TARGET_FLAG_UNK2 is used for non-combat pets, maybe other?
- if( m_targetMask & (TARGET_FLAG_UNIT|TARGET_FLAG_UNK2) )
- if(!readGUID(*data, m_unitTargetGUID))
+ if( m_targetMask & ( TARGET_FLAG_UNIT | TARGET_FLAG_UNK2 ))
+ if(!data->readPackGUID(m_unitTargetGUID))
return false;
- if( m_targetMask & ( TARGET_FLAG_OBJECT | TARGET_FLAG_OBJECT_UNK ))
- if(!readGUID(*data, m_GOTargetGUID))
+ if( m_targetMask & ( TARGET_FLAG_OBJECT ))
+ if(!data->readPackGUID(m_GOTargetGUID))
return false;
if(( m_targetMask & ( TARGET_FLAG_ITEM | TARGET_FLAG_TRADE_ITEM )) && caster->GetTypeId() == TYPEID_PLAYER)
- if(!readGUID(*data, m_itemTargetGUID))
+ if(!data->readPackGUID(m_itemTargetGUID))
+ return false;
+
+ if( m_targetMask & (TARGET_FLAG_CORPSE | TARGET_FLAG_PVP_CORPSE ) )
+ if(!data->readPackGUID(m_CorpseTargetGUID))
return false;
/*if( m_targetMask & TARGET_FLAG_SOURCE_LOCATION )
@@ -202,7 +213,10 @@ bool SpellCastTargets::read ( WorldPacket * data, Unit *caster )
if( m_targetMask & (TARGET_FLAG_SOURCE_LOCATION | TARGET_FLAG_DEST_LOCATION) )
{
- if(data->rpos()+4+4+4 > data->size())
+ if(data->rpos()+1+4+4+4 > data->size())
+ return false;
+
+ if(!data->readPackGUID(m_unitTargetGUID))
return false;
*data >> m_destX >> m_destY >> m_destZ;
@@ -219,10 +233,6 @@ bool SpellCastTargets::read ( WorldPacket * data, Unit *caster )
*data >> m_strTarget;
}
- if( m_targetMask & (TARGET_FLAG_CORPSE | TARGET_FLAG_PVP_CORPSE ) )
- if(!readGUID(*data, m_CorpseTargetGUID))
- return false;
-
// find real units/GOs
Update(caster);
return true;
@@ -242,7 +252,7 @@ void SpellCastTargets::write ( WorldPacket * data )
else
*data << uint8(0);
}
- else if( m_targetMask & ( TARGET_FLAG_OBJECT | TARGET_FLAG_OBJECT_UNK ) )
+ else if( m_targetMask & TARGET_FLAG_OBJECT )
{
if(m_GOTarget)
data->append(m_GOTarget->GetPackGUID());
@@ -267,7 +277,14 @@ void SpellCastTargets::write ( WorldPacket * data )
*data << m_srcX << m_srcY << m_srcZ;
if( m_targetMask & TARGET_FLAG_DEST_LOCATION )
+ {
+ if(m_unitTarget)
+ data->append(m_unitTarget->GetPackGUID());
+ else
+ *data << uint8(0);
+
*data << m_destX << m_destY << m_destZ;
+ }
if( m_targetMask & TARGET_FLAG_STRING )
*data << m_strTarget;
@@ -305,7 +322,7 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
break;
default:
// Wands
- if (m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_REQ_WAND)
+ if (m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_AUTOREPEAT_FLAG)
m_attackType = RANGED_ATTACK;
else
m_attackType = BASE_ATTACK;
@@ -355,14 +372,14 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
gameObjTarget = NULL;
focusObject = NULL;
m_cast_count = 0;
+ m_glyphIndex = 0;
+ m_preCastSpell = 0;
m_triggeredByAuraSpell = NULL;
- //Auto Shot & Shoot
- if( m_spellInfo->AttributesEx2 == 0x000020 && !triggered )
- m_autoRepeat = true;
- else
- m_autoRepeat = false;
+ //Auto Shot & Shoot (wand)
+ m_autoRepeat = IsAutoRepeatRangedSpell(m_spellInfo);
+ m_runesState = 0;
m_powerCost = 0; // setup to correct value in Spell::prepare, don't must be used before.
m_casttime = 0; // setup to correct value in Spell::prepare, don't must be used before.
m_timer = 0; // will set to castime in prepare
@@ -372,7 +389,7 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
// determine reflection
m_canReflect = false;
- if(m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC && (m_spellInfo->AttributesEx2 & 0x4)==0)
+ if(m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC && !(m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_CANT_REFLECTED))
{
for(int j=0;j<3;j++)
{
@@ -461,7 +478,7 @@ void Spell::FillTargetMap()
WorldObject* result = NULL;
Trinity::CannibalizeObjectCheck u_check(m_caster, max_range);
- Trinity::WorldObjectSearcher<Trinity::CannibalizeObjectCheck > searcher(result, u_check);
+ Trinity::WorldObjectSearcher<Trinity::CannibalizeObjectCheck > searcher(m_caster, result, u_check);
m_caster->VisitNearbyGridObject(max_range, searcher);
if(!result)
m_caster->VisitNearbyWorldObject(max_range, searcher);
@@ -511,6 +528,8 @@ void Spell::FillTargetMap()
case SPELL_EFFECT_CREATE_ITEM:
case SPELL_EFFECT_TRIGGER_SPELL:
case SPELL_EFFECT_SKILL_STEP:
+ case SPELL_EFFECT_PROFICIENCY:
+ case SPELL_EFFECT_SUMMON_OBJECT_WILD:
case SPELL_EFFECT_SELF_RESURRECT:
case SPELL_EFFECT_REPUTATION:
case SPELL_EFFECT_LEARN_SPELL:
@@ -543,7 +562,9 @@ void Spell::FillTargetMap()
break;
case SPELL_EFFECT_SUMMON_CHANGE_ITEM:
case SPELL_EFFECT_ADD_FARSIGHT:
+ case SPELL_EFFECT_APPLY_GLYPH:
case SPELL_EFFECT_STUCK:
+ case SPELL_EFFECT_FEED_PET:
case SPELL_EFFECT_DESTROY_ALL_TOTEMS:
tmpUnitMap.push_back(m_caster);
break;
@@ -553,9 +574,10 @@ void Spell::FillTargetMap()
break;
/*case SPELL_EFFECT_ENCHANT_ITEM:
case SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY:
+ case SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC:
case SPELL_EFFECT_DISENCHANT:
- case SPELL_EFFECT_FEED_PET:
case SPELL_EFFECT_PROSPECTING:
+ case SPELL_EFFECT_MILLING:
if(m_targets.getItemTarget())
AddItemTarget(m_targets.getItemTarget(), i);
break;*/
@@ -596,7 +618,6 @@ void Spell::FillTargetMap()
}
}
-
if(IsChanneledSpell(m_spellInfo) && !tmpUnitMap.empty())
m_needAliveTargetMask |= (1<<i);
@@ -633,34 +654,43 @@ void Spell::prepareDataForTriggerSystem()
// Ñan spell trigger another or not ( m_canTrigger )
// Create base triggers flags for Attacker and Victim ( m_procAttacker and m_procVictim)
//==========================================================================================
-
// Fill flag can spell trigger or not
- if (!m_IsTriggeredSpell)
+ // TODO: possible exist spell attribute for this
+ m_canTrigger = false;
+
+ if (m_CastItem)
+ m_canTrigger = false; // Do not trigger from item cast spell
+ else if (!m_IsTriggeredSpell)
m_canTrigger = true; // Normal cast - can trigger
else if (!m_triggeredByAuraSpell)
m_canTrigger = true; // Triggered from SPELL_EFFECT_TRIGGER_SPELL - can trigger
- else // Exceptions (some periodic triggers)
+
+ if (!m_canTrigger) // Exceptions (some periodic triggers)
{
- m_canTrigger = false; // Triggered spells can`t trigger another
switch (m_spellInfo->SpellFamilyName)
{
case SPELLFAMILY_MAGE: // Arcane Missles / Blizzard triggers need do it
- if (m_spellInfo->SpellFamilyFlags & 0x0000000000200080LL) m_canTrigger = true;
+ if (m_spellInfo->SpellFamilyFlags[0] & 0x200080) m_canTrigger = true;
break;
case SPELLFAMILY_WARLOCK: // For Hellfire Effect / Rain of Fire / Seed of Corruption triggers need do it
- if (m_spellInfo->SpellFamilyFlags & 0x0000800000000060LL) m_canTrigger = true;
+ if (m_spellInfo->SpellFamilyFlags[1] & 0x00008000 || m_spellInfo->SpellFamilyFlags[0] & 0x00000060) m_canTrigger = true;
break;
- case SPELLFAMILY_HUNTER: // Hunter Explosive Trap Effect/Immolation Trap Effect/Frost Trap Aura/Snake Trap Effect
- if (m_spellInfo->SpellFamilyFlags & 0x0000200000000014LL) m_canTrigger = true;
+ case SPELLFAMILY_PRIEST: // For Penance heal/damage triggers need do it
+ if (m_spellInfo->SpellFamilyFlags[1] & 0x00018000) m_canTrigger = true;
break;
- case SPELLFAMILY_PALADIN: // For Holy Shock triggers need do it
- if (m_spellInfo->SpellFamilyFlags & 0x0001000000200000LL) m_canTrigger = true;
+ case SPELLFAMILY_ROGUE: // For poisons need do it
+ if (m_spellInfo->SpellFamilyFlags[1] & 0x00000010 || m_spellInfo->SpellFamilyFlags[0] & 0x1001E000) m_canTrigger = true;
+ break;
+ case SPELLFAMILY_HUNTER: // Hunter Rapid Killing/Explosive Trap Effect/Immolation Trap Effect/Frost Trap Aura/Snake Trap Effect/Explosive Shot
+ if (m_spellInfo->SpellFamilyFlags[1] & 0x01002000
+ || m_spellInfo->SpellFamilyFlags[0] & 0x00000214 ||
+ m_spellInfo->SpellFamilyFlags[2] & 0x200) m_canTrigger = true;
+ break;
+ case SPELLFAMILY_PALADIN: // For Judgements (all) / Holy Shock triggers need do it
+ if (m_spellInfo->SpellFamilyFlags[1] & 0x00010009 || m_spellInfo->SpellFamilyFlags[0] & 0x00B80400) m_canTrigger = true;
break;
}
}
- // Do not trigger from item cast spell
- if (m_CastItem)
- m_canTrigger = false;
// Get data for type of attack and fill base info for trigger
switch (m_spellInfo->DmgClass)
@@ -670,21 +700,30 @@ void Spell::prepareDataForTriggerSystem()
m_procVictim = PROC_FLAG_TAKEN_MELEE_SPELL_HIT;
break;
case SPELL_DAMAGE_CLASS_RANGED:
- m_procAttacker = PROC_FLAG_SUCCESSFUL_RANGED_SPELL_HIT;
- m_procVictim = PROC_FLAG_TAKEN_RANGED_SPELL_HIT;
+ // Auto attack
+ if (m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_AUTOREPEAT_FLAG)
+ {
+ m_procAttacker = PROC_FLAG_SUCCESSFUL_RANGED_HIT;
+ m_procVictim = PROC_FLAG_TAKEN_RANGED_HIT;
+ }
+ else // Ranged spell attack
+ {
+ m_procAttacker = PROC_FLAG_SUCCESSFUL_RANGED_SPELL_HIT;
+ m_procVictim = PROC_FLAG_TAKEN_RANGED_SPELL_HIT;
+ }
break;
default:
- if (IsPositiveSpell(m_spellInfo->Id)) // Check for positive spell
+ if (IsPositiveSpell(m_spellInfo->Id)) // Check for positive spell
{
m_procAttacker = PROC_FLAG_SUCCESSFUL_POSITIVE_SPELL;
m_procVictim = PROC_FLAG_TAKEN_POSITIVE_SPELL;
}
- else if (m_spellInfo->Id == 5019) // Wands
+ else if (m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_AUTOREPEAT_FLAG) // Wands auto attack
{
- m_procAttacker = PROC_FLAG_SUCCESSFUL_RANGED_SPELL_HIT;
- m_procVictim = PROC_FLAG_TAKEN_RANGED_SPELL_HIT;
+ m_procAttacker = PROC_FLAG_SUCCESSFUL_RANGED_HIT;
+ m_procVictim = PROC_FLAG_TAKEN_RANGED_HIT;
}
- else
+ else // Negative spell
{
m_procAttacker = PROC_FLAG_SUCCESSFUL_NEGATIVE_SPELL_HIT;
m_procVictim = PROC_FLAG_TAKEN_NEGATIVE_SPELL_HIT;
@@ -693,7 +732,7 @@ void Spell::prepareDataForTriggerSystem()
}
// Hunter traps spells (for Entrapment trigger)
// Gives your Immolation Trap, Frost Trap, Explosive Trap, and Snake Trap ....
- if (m_spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && m_spellInfo->SpellFamilyFlags & 0x0000200000000014LL)
+ if (m_spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && (m_spellInfo->SpellFamilyFlags[1] & 0x00002000 || m_spellInfo->SpellFamilyFlags[0] & 0x1C))
m_procAttacker |= PROC_FLAG_ON_TRAP_ACTIVATION;
}
@@ -702,8 +741,6 @@ void Spell::CleanupTargetList()
m_UniqueTargetInfo.clear();
m_UniqueGOTargetInfo.clear();
m_UniqueItemInfo.clear();
- m_countOfHit = 0;
- m_countOfMiss = 0;
m_delayMoment = 0;
}
@@ -712,6 +749,9 @@ void Spell::AddUnitTarget(Unit* pVictim, uint32 effIndex)
if( m_spellInfo->Effect[effIndex]==0 )
return;
+ // Check for effect immune skip if immuned
+ bool immuned = pVictim->IsImmunedToSpellEffect(m_spellInfo, effIndex);
+
uint64 targetGUID = pVictim->GetGUID();
// Lookup target in already in list
@@ -719,7 +759,8 @@ void Spell::AddUnitTarget(Unit* pVictim, uint32 effIndex)
{
if (targetGUID == ihit->targetGUID) // Found in list
{
- ihit->effectMask |= 1<<effIndex; // Add only effect mask
+ if (!immuned)
+ ihit->effectMask |= 1<<effIndex; // Add only effect mask if not immuned
return;
}
}
@@ -729,7 +770,7 @@ void Spell::AddUnitTarget(Unit* pVictim, uint32 effIndex)
// Get spell hit result on target
TargetInfo target;
target.targetGUID = targetGUID; // Store target GUID
- target.effectMask = 1<<effIndex; // Store index of effect
+ target.effectMask = immuned ? 0 : 1<<effIndex; // Store index of effect if not immuned
target.processed = false; // Effects not apply on target
target.damage = 0;
@@ -743,11 +784,6 @@ void Spell::AddUnitTarget(Unit* pVictim, uint32 effIndex)
else
target.missCondition = SPELL_MISS_EVADE; //SPELL_MISS_NONE;
- if (target.missCondition == SPELL_MISS_NONE)
- ++m_countOfHit;
- else
- ++m_countOfMiss;
-
// Spell have speed - need calculate incoming time
if (m_spellInfo->speed > 0.0f)
{
@@ -828,8 +864,6 @@ void Spell::AddGOTarget(GameObject* pVictim, uint32 effIndex)
else
target.timeDelay = 0LL;
- ++m_countOfHit;
-
// Add target to list
m_UniqueGOTargetInfo.push_back(target);
}
@@ -863,83 +897,6 @@ void Spell::AddItemTarget(Item* pitem, uint32 effIndex)
target.effectMask = 1<<effIndex;
m_UniqueItemInfo.push_back(target);
}
-/*
-void Spell::doTriggers(SpellMissInfo missInfo, uint32 damage, SpellSchoolMask damageSchoolMask, uint32 block, uint32 absorb, bool crit)
-{
- // Do triggers depends from hit result (triggers on hit do in effects)
- // Set aura states depends from hit result
- if (missInfo!=SPELL_MISS_NONE)
- {
- // Miss/dodge/parry/block only for melee based spells
- // Resist only for magic based spells
- switch (missInfo)
- {
- case SPELL_MISS_MISS:
- if(m_caster->GetTypeId()== TYPEID_PLAYER)
- ((Player*)m_caster)->UpdateWeaponSkill(BASE_ATTACK);
-
- m_caster->CastMeleeProcDamageAndSpell(unitTarget, 0, damageSchoolMask, m_attackType, MELEE_HIT_MISS, m_spellInfo, m_IsTriggeredSpell);
- break;
- case SPELL_MISS_RESIST:
- m_caster->ProcDamageAndSpell(unitTarget, PROC_FLAG_TARGET_RESISTS, PROC_FLAG_RESIST_SPELL, 0, damageSchoolMask, m_spellInfo, m_IsTriggeredSpell);
- break;
- case SPELL_MISS_DODGE:
- if(unitTarget->GetTypeId() == TYPEID_PLAYER)
- ((Player*)unitTarget)->UpdateDefense();
-
- // Overpower
- if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->getClass() == CLASS_WARRIOR)
- {
- ((Player*) m_caster)->AddComboPoints(unitTarget, 1);
- m_caster->StartReactiveTimer( REACTIVE_OVERPOWER );
- }
-
- // Riposte
- if (unitTarget->getClass() != CLASS_ROGUE)
- {
- unitTarget->ModifyAuraState(AURA_STATE_DEFENSE, true);
- unitTarget->StartReactiveTimer( REACTIVE_DEFENSE );
- }
-
- m_caster->CastMeleeProcDamageAndSpell(unitTarget, 0, damageSchoolMask, m_attackType, MELEE_HIT_DODGE, m_spellInfo, m_IsTriggeredSpell);
- break;
- case SPELL_MISS_PARRY:
- // Update victim defense ?
- if(unitTarget->GetTypeId() == TYPEID_PLAYER)
- ((Player*)unitTarget)->UpdateDefense();
- // Mongoose bite - set only Counterattack here
- if (unitTarget->getClass() == CLASS_HUNTER)
- {
- unitTarget->ModifyAuraState(AURA_STATE_HUNTER_PARRY,true);
- unitTarget->StartReactiveTimer( REACTIVE_HUNTER_PARRY );
- }
- else
- {
- unitTarget->ModifyAuraState(AURA_STATE_DEFENSE, true);
- unitTarget->StartReactiveTimer( REACTIVE_DEFENSE );
- }
- m_caster->CastMeleeProcDamageAndSpell(unitTarget, 0, damageSchoolMask, m_attackType, MELEE_HIT_PARRY, m_spellInfo, m_IsTriggeredSpell);
- break;
- case SPELL_MISS_BLOCK:
- unitTarget->ModifyAuraState(AURA_STATE_DEFENSE, true);
- unitTarget->StartReactiveTimer( REACTIVE_DEFENSE );
-
- m_caster->CastMeleeProcDamageAndSpell(unitTarget, 0, damageSchoolMask, m_attackType, MELEE_HIT_BLOCK, m_spellInfo, m_IsTriggeredSpell);
- break;
- // Trigger from this events not supported
- case SPELL_MISS_EVADE:
- case SPELL_MISS_IMMUNE:
- case SPELL_MISS_IMMUNE2:
- case SPELL_MISS_DEFLECT:
- case SPELL_MISS_ABSORB:
- // Trigger from reflects need do after get reflect result
- case SPELL_MISS_REFLECT:
- break;
- default:
- break;
- }
- }
-}*/
void Spell::DoAllEffectOnTarget(TargetInfo *target)
{
@@ -949,15 +906,13 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
// Get mask of effects for target
uint32 mask = target->effectMask;
- if (mask == 0) // No effects
- return;
Unit* unit = m_caster->GetGUID()==target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster,target->targetGUID);
if (!unit)
return;
// Get original caster (if exist) and calculate damage/healing from him data
- Unit *caster = m_originalCasterGUID ? m_originalCaster : m_caster;
+ Unit *caster = m_originalCaster ? m_originalCaster : m_caster;
// Skip if m_originalCaster not avaiable
if (!caster)
@@ -1005,7 +960,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
if (crit)
{
procEx |= PROC_EX_CRITICAL_HIT;
- addhealth = caster->SpellCriticalBonus(m_spellInfo, addhealth, NULL);
+ addhealth = caster->SpellCriticalHealingBonus(m_spellInfo, addhealth, NULL);
}
else
procEx |= PROC_EX_NORMAL_HIT;
@@ -1044,44 +999,12 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
caster->DealSpellDamage(&damageInfo, true);
- // Shadow Word: Death - deals damage equal to damage done to caster if victim is not killed
- if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && m_spellInfo->SpellFamilyFlags&0x0000000200000000LL &&
- caster != unitTarget && unitTarget->isAlive())
- {
- // Redirect damage to caster if victim Alive
- damageInfo.target = caster;
- damageInfo.absorb = 0;
- damageInfo.resist = 0;
- damageInfo.blocked = 0;
- // Send log damage message to client
- caster->SendSpellNonMeleeDamageLog(&damageInfo);
- caster->DealSpellDamage(&damageInfo, true);
- }
// Judgement of Blood
- else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && m_spellInfo->SpellFamilyFlags & 0x0000000800000000LL && m_spellInfo->SpellIconID==153)
+ if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && m_spellInfo->SpellFamilyFlags[1] & 0x00000008 && m_spellInfo->SpellIconID==153)
{
int32 damagePoint = damageInfo.damage * 33 / 100;
m_caster->CastCustomSpell(m_caster, 32220, &damagePoint, NULL, NULL, true);
}
- // Bloodthirst
- else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR && m_spellInfo->SpellFamilyFlags & 0x40000000000LL)
- {
- uint32 BTAura = 0;
- switch(m_spellInfo->Id)
- {
- case 23881: BTAura = 23885; break;
- case 23892: BTAura = 23886; break;
- case 23893: BTAura = 23887; break;
- case 23894: BTAura = 23888; break;
- case 25251: BTAura = 25252; break;
- case 30335: BTAura = 30339; break;
- default:
- sLog.outError("Spell::EffectSchoolDMG: Spell %u not handled in BTAura",m_spellInfo->Id);
- break;
- }
- if (BTAura)
- m_caster->CastSpell(m_caster,BTAura,true);
- }
}
// Passive spell hits/misses or active spells only misses (only triggers)
else
@@ -1105,14 +1028,14 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
if( !m_caster->IsFriendlyTo(unit) && !IsPositiveSpell(m_spellInfo->Id))
{
- if( !(m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_NO_INITIAL_AGGRO) )
+ if( !(m_spellInfo->AttributesEx & SPELL_ATTR_EX_NO_INITIAL_AGGRO) )
{
m_caster->CombatStart(unit);
}
else if(m_customAttr & SPELL_ATTR_CU_AURA_CC)
{
if(!unit->IsStandState())
- unit->SetStandState(PLAYER_STATE_NONE);
+ unit->SetStandState(UNIT_STAND_STATE_STAND);
}
}
}
@@ -1125,25 +1048,37 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
// Recheck immune (only for delayed spells)
if( m_spellInfo->speed &&
!(m_spellInfo->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY)
- && (unit->IsImmunedToDamage(GetSpellSchoolMask(m_spellInfo),true) ||
- unit->IsImmunedToSpell(m_spellInfo,true) ))
+ && (unit->IsImmunedToDamage(GetSpellSchoolMask(m_spellInfo)) ||
+ unit->IsImmunedToSpell(m_spellInfo)))
{
m_caster->SendSpellMiss(unit, m_spellInfo->Id, SPELL_MISS_IMMUNE);
m_damage = 0;
return;
}
+ if (unit->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)unit)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, m_spellInfo->Id);
+ ((Player*)unit)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, m_spellInfo->Id);
+ }
+
+ if(m_caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)m_caster)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, m_spellInfo->Id, 0, unit);
+ }
+
if( m_caster != unit )
{
- if (unit->GetCharmerOrOwnerGUID() != m_caster->GetGUID())
+ // Recheck UNIT_FLAG_NON_ATTACKABLE for delayed spells
+ if (m_spellInfo->speed > 0.0f &&
+ unit->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE) &&
+ unit->GetCharmerOrOwnerGUID() != m_caster->GetGUID())
{
- if (unit->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
- {
- m_caster->SendSpellMiss(unit, m_spellInfo->Id, SPELL_MISS_EVADE);
+ m_caster->SendSpellMiss(unit, m_spellInfo->Id, SPELL_MISS_EVADE);
m_damage = 0;
- return;
- }
+ return;
}
+
if( !m_caster->IsFriendlyTo(unit) )
{
// for delayed spells ignore not visible explicit target
@@ -1172,7 +1107,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
// assisting case, healing and resurrection
if(unit->hasUnitState(UNIT_STAT_ATTACK_PLAYER))
m_caster->SetContestedPvP();
- if( unit->isInCombat() && !(m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_NO_INITIAL_AGGRO) )
+ if( unit->isInCombat() && !(m_spellInfo->AttributesEx & SPELL_ATTR_EX_NO_INITIAL_AGGRO) )
{
m_caster->SetInCombatState(unit->GetCombatTimer() > 0);
unit->getHostilRefManager().threatAssist(m_caster, 0.0f);
@@ -1190,6 +1125,10 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
unit->IncrDiminishing(m_diminishGroup);
}
+ // Apply additional spell effects to target
+ if (m_preCastSpell)
+ m_caster->CastSpell(unit,m_preCastSpell, true, m_CastItem);
+
for(uint32 effectNumber=0;effectNumber<3;effectNumber++)
{
if (effectMask & (1<<effectNumber))
@@ -1349,6 +1288,16 @@ void Spell::SearchChainTarget(std::list<Unit*> &TagUnitMap, float max_range, uin
if(!cur)
return;
+ // Get spell max affected targets
+ /*uint32 unMaxTargets = m_spellInfo->MaxAffectedTargets;
+ Unit::AuraList const& mod = m_caster->GetAurasByType(SPELL_AURA_MOD_MAX_AFFECTED_TARGETS);
+ for(Unit::AuraList::const_iterator m = mod.begin(); m != mod.end(); ++m)
+ {
+ if (!(*m)->isAffectedOnSpell(m_spellInfo))
+ continue;
+ unMaxTargets+=(*m)->GetModifier()->m_amount;
+ }*/
+
//FIXME: This very like horrible hack and wrong for most spells
if(m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MELEE)
max_range += num * CHAIN_SPELL_JUMP_RADIUS;
@@ -1460,7 +1409,7 @@ Unit* Spell::SearchNearbyTarget(float radius, SpellTargets TargetType, uint32 en
{
Creature* target = NULL;
Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*m_caster, entry, true, radius);
- Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(target, u_check);
+ Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(m_caster, target, u_check);
m_caster->VisitNearbyObject(radius, searcher);
return target;
}
@@ -1474,13 +1423,13 @@ Unit* Spell::SearchNearbyTarget(float radius, SpellTargets TargetType, uint32 en
case SPELL_TARGETS_ENEMY:
{
Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, radius);
- Trinity::UnitLastSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(target, u_check);
+ Trinity::UnitLastSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(m_caster, target, u_check);
m_caster->VisitNearbyObject(radius, searcher);
}break;
case SPELL_TARGETS_ALLY:
{
Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, radius);
- Trinity::UnitLastSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(target, u_check);
+ Trinity::UnitLastSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(m_caster, target, u_check);
m_caster->VisitNearbyObject(radius, searcher);
}break;
}
@@ -1499,6 +1448,13 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
uint32 EffectChainTarget = m_spellInfo->EffectChainTarget[i];
uint32 unMaxTargets = m_spellInfo->MaxAffectedTargets;
+ Unit::AuraList const& Auras = m_caster->GetAurasByType(SPELL_AURA_MOD_ABILITY_AFFECTED_TARGETS);
+ for(Unit::AuraList::const_iterator j = Auras.begin();j != Auras.end(); ++j)
+ {
+ if((*j)->isAffectedOnSpell(m_spellInfo))
+ unMaxTargets+=(*j)->GetModifier()->m_amount;
+ }
+
if(m_originalCaster)
{
if(Player* modOwner = m_originalCaster->GetSpellModOwner())
@@ -1537,10 +1493,11 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
m_caster->GetPartyMember(TagUnitMap, radius);
break;
case TARGET_UNIT_RAID:
- if(Unit *target = m_targets.getUnitTarget())
- TagUnitMap.push_back(target);
- else
- m_caster->GetRaidMember(TagUnitMap, radius);
+ //if(Unit *target = m_targets.getUnitTarget())
+ // TagUnitMap.push_back(target);
+ //else
+ m_caster->GetRaidMember(TagUnitMap, radius);
+ TagUnitMap.push_back(m_caster);
break;
}
}break;
@@ -1564,7 +1521,6 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
case TARGET_UNIT_TARGET_RAID:
case TARGET_UNIT_TARGET_ANY: // SelectMagnetTarget()?
case TARGET_UNIT_TARGET_PARTY:
- case TARGET_UNIT_SINGLE_UNKNOWN:
TagUnitMap.push_back(target);
break;
case TARGET_UNIT_PARTY_TARGET:
@@ -1703,7 +1659,6 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
m_targets.setDestination(((Player*)m_caster)->m_homebindX,((Player*)m_caster)->m_homebindY,((Player*)m_caster)->m_homebindZ, true, ((Player*)m_caster)->m_homebindMapId);
break;
-
case TARGET_IN_FRONT_OF_CASTER:
case TARGET_UNIT_CONE_ENEMY_UNKNOWN:
if(m_customAttr & SPELL_ATTR_CU_CONE_BACK)
@@ -1719,6 +1674,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
// nearby target
case TARGET_UNIT_NEARBY_ALLY:
+ case TARGET_UNIT_NEARBY_ALLY_UNK:
if(!m_targets.getUnitTarget())
m_targets.setUnitTarget(SearchNearbyTarget(radius, SPELL_TARGETS_ALLY));
if(m_targets.getUnitTarget())
@@ -1729,7 +1685,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
SearchChainTarget(TagUnitMap, radius, EffectChainTarget, SPELL_TARGETS_ALLY);
}
break;
- case TARGET_RANDOM_ENEMY_CHAIN_IN_AREA:
+ case TARGET_UNIT_NEARBY_ENEMY:
if(!m_targets.getUnitTarget())
m_targets.setUnitTarget(SearchNearbyTarget(radius, SPELL_TARGETS_ENEMY));
if(m_targets.getUnitTarget())
@@ -1770,7 +1726,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
if(i_spellST->second.targetEntry)
{
Trinity::NearestGameObjectEntryInObjectRangeCheck go_check(*m_caster,i_spellST->second.targetEntry,range);
- Trinity::GameObjectLastSearcher<Trinity::NearestGameObjectEntryInObjectRangeCheck> checker(p_GameObject,go_check);
+ Trinity::GameObjectLastSearcher<Trinity::NearestGameObjectEntryInObjectRangeCheck> checker(m_caster, p_GameObject,go_check);
m_caster->VisitNearbyGridObject(range, checker);
if(p_GameObject)
@@ -1800,7 +1756,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
Creature *p_Creature = NULL;
Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*m_caster,i_spellST->second.targetEntry,i_spellST->second.type!=SPELL_TARGET_TYPE_DEAD,range);
- Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(p_Creature, u_check);
+ Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(m_caster, p_Creature, u_check);
m_caster->VisitNearbyObject(range, searcher);
if(p_Creature )
@@ -2016,7 +1972,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
}
}
-void Spell::prepare(SpellCastTargets * targets, Aura* triggeredByAura)
+void Spell::prepare(SpellCastTargets const* targets, Aura* triggeredByAura)
{
if(m_CastItem)
m_castItemGUID = m_CastItem->GetGUID();
@@ -2038,7 +1994,7 @@ void Spell::prepare(SpellCastTargets * targets, Aura* triggeredByAura)
m_caster->m_Events.AddEvent(Event, m_caster->m_Events.CalculateTime(1));
//Prevent casting at cast another spell (ServerSide check)
- if(m_caster->IsNonMeleeSpellCasted(false, true) && m_cast_count)
+ if(m_caster->IsNonMeleeSpellCasted(false, true, true) && m_cast_count)
{
SendCastResult(SPELL_FAILED_SPELL_IN_PROGRESS);
finish(false);
@@ -2131,11 +2087,11 @@ void Spell::cancel(bool report)
{
Unit* unit = m_caster->GetGUID()==(*ihit).targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
if( unit && unit->isAlive() )
- unit->RemoveAurasDueToCasterSpell(m_spellInfo->Id, m_caster->GetGUID());
+ unit->RemoveAurasByCasterSpell(m_spellInfo->Id, m_caster->GetGUID());
}
}
- m_caster->RemoveAurasDueToCasterSpell(m_spellInfo->Id, m_caster->GetGUID());
+ m_caster->RemoveAurasByCasterSpell(m_spellInfo->Id, m_caster->GetGUID());
SendChannelUpdate(0);
SendInterrupted(0);
SendCastResult(report ? SPELL_FAILED_INTERRUPTED : SPELL_FAILED_DONT_REPORT);
@@ -2212,16 +2168,43 @@ void Spell::cast(bool skipCheck)
FillTargetMap();
- if(m_spellState == SPELL_STATE_FINISHED) // stop cast if spell marked as finish somewhere in Take*/FillTargetMap
+ if(m_spellInfo->SpellFamilyName)
{
- SetExecutedCurrently(false);
- return;
+ if (m_spellInfo->excludeCasterAuraSpell)
+ m_preCastSpell = m_spellInfo->excludeCasterAuraSpell;
+ else if (m_spellInfo->excludeTargetAuraSpell)
+ m_preCastSpell = m_spellInfo->excludeTargetAuraSpell;
}
+ switch (m_spellInfo->SpellFamilyName)
+ {
+ case SPELLFAMILY_GENERIC:
+ {
+ if (m_spellInfo->Mechanic == MECHANIC_BANDAGE) // Bandages
+ m_preCastSpell = 11196; // Recently Bandaged
+ else if(m_spellInfo->SpellIconID == 1662 && m_spellInfo->AttributesEx & 0x20)
+ m_preCastSpell = 23230; // Blood Fury - Healing Reduction
+ break;
+ }
+ case SPELLFAMILY_PRIEST:
+ {
+ if (m_spellInfo->Id == 47585) // Dispersion (transform)
+ m_preCastSpell = 60069; // Dispersion (mana regen)
+ break;
+ }
+ }
// traded items have trade slot instead of guid in m_itemTargetGUID
// set to real guid to be sent later to the client
m_targets.updateTradeSlotItem();
+ if (m_caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ if (m_CastItem)
+ ((Player*)m_caster)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, m_CastItem->GetEntry());
+
+ ((Player*)m_caster)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, m_spellInfo->Id);
+ }
+
if(!m_IsTriggeredSpell)
{
//TakePower();
@@ -2236,6 +2219,23 @@ void Spell::cast(bool skipCheck)
if(m_customAttr & SPELL_ATTR_CU_DIRECT_DAMAGE)
CalculateDamageDoneForAllTargets();
+ //are there any spells need to be triggered after hit?
+ // handle SPELL_AURA_ADD_TARGET_TRIGGER auras
+ Unit::AuraList const& targetTriggers = m_caster->GetAurasByType(SPELL_AURA_ADD_TARGET_TRIGGER);
+ for(Unit::AuraList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)
+ {
+ if (!(*i)->isAffectedOnSpell(m_spellInfo))
+ continue;
+ SpellEntry const *auraSpellInfo = (*i)->GetSpellProto();
+ uint32 auraSpellIdx = (*i)->GetEffIndex();
+ if(SpellEntry const *spellInfo = sSpellStore.LookupEntry(auraSpellInfo->EffectTriggerSpell[auraSpellIdx]))
+ {
+ // Calculate chance at that moment (can be depend for example from combo points)
+ int32 chance = m_caster->CalculateSpellDamage(auraSpellInfo, auraSpellIdx, (*i)->GetBasePoints(), NULL);
+ m_ChanceTriggerSpells.push_back(std::make_pair(spellInfo, chance * (*i)->GetStackAmount()));
+ }
+ }
+
if(m_customAttr & SPELL_ATTR_CU_CHARGE)
EffectCharge(0);
@@ -2257,24 +2257,6 @@ void Spell::cast(bool skipCheck)
handle_immediate();
}
- //handle SPELL_AURA_ADD_TARGET_TRIGGER auras
- //are there any spells need to be triggered after hit?
- Unit::AuraList const& targetTriggers = m_caster->GetAurasByType(SPELL_AURA_ADD_TARGET_TRIGGER);
- for(Unit::AuraList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)
- {
- SpellEntry const *auraSpellInfo = (*i)->GetSpellProto();
- uint32 auraSpellIdx = (*i)->GetEffIndex();
- if (IsAffectedBy(auraSpellInfo, auraSpellIdx))
- {
- if(SpellEntry const *spellInfo = sSpellStore.LookupEntry(auraSpellInfo->EffectTriggerSpell[auraSpellIdx]))
- {
- // Calculate chance at that moment (can be depend for example from combo points)
- int32 chance = m_caster->CalculateSpellDamage(auraSpellInfo, auraSpellIdx, (*i)->GetBasePoints(), NULL);
- m_ChanceTriggerSpells.push_back(std::make_pair(spellInfo, chance * (*i)->GetStackAmount()));
- }
- }
- }
-
// combo points should not be taken before SPELL_AURA_ADD_TARGET_TRIGGER auras are handled
if(!m_IsTriggeredSpell)
{
@@ -2299,9 +2281,18 @@ void Spell::handle_immediate()
// start channeling if applicable
if(IsChanneledSpell(m_spellInfo))
{
- m_spellState = SPELL_STATE_CASTING;
- m_caster->AddInterruptMask(m_spellInfo->ChannelInterruptFlags);
- SendChannelStart(GetSpellDuration(m_spellInfo));
+ int32 duration = GetSpellDuration(m_spellInfo);
+ if (duration)
+ {
+ //apply haste mods
+ m_caster->ModSpellCastTime(m_spellInfo, duration);
+ // Apply duration mod
+ if(Player* modOwner = m_caster->GetSpellModOwner())
+ modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
+ m_spellState = SPELL_STATE_CASTING;
+ m_caster->AddInterruptMask(m_spellInfo->ChannelInterruptFlags);
+ SendChannelStart(duration);
+ }
}
// process immediate effects (items, ground, etc.) also initialize some variables
@@ -2482,7 +2473,7 @@ void Spell::SendSpellCooldown()
// shoot spells used equipped item cooldown values already assigned in GetAttackTime(RANGED_ATTACK)
// prevent 0 cooldowns set by another way
- if (rec <= 0 && catrec <= 0 && (cat == 76 || cat == 351))
+ if (rec <= 0 && catrec <= 0 && (cat == 76 || IsAutoRepeatRangedSpell(m_spellInfo) && m_spellInfo->Id != SPELL_ID_AUTOSHOT))
rec = _player->GetAttackTime(RANGED_ATTACK);
// Now we have cooldown data (if found any), time to apply mods
@@ -2520,7 +2511,7 @@ void Spell::SendSpellCooldown()
if(*i_scset == m_spellInfo->Id) // skip main spell, already handled above
continue;
- _player->AddSpellCooldown(m_spellInfo->Id, m_CastItem ? m_CastItem->GetEntry() : 0, catrecTime);
+ _player->AddSpellCooldown(*i_scset, m_CastItem ? m_CastItem->GetEntry() : 0, catrecTime);
}
}
}
@@ -2698,9 +2689,9 @@ void Spell::SendCastResult(uint8 result)
if(result != 0)
{
WorldPacket data(SMSG_CAST_FAILED, (4+1+1));
+ data << uint8(m_cast_count); // single cast or multi 2.3 (0/1)
data << uint32(m_spellInfo->Id);
data << uint8(result); // problem
- data << uint8(m_cast_count); // single cast or multi 2.3 (0/1)
switch (result)
{
case SPELL_FAILED_REQUIRES_SPELL_FOCUS:
@@ -2721,8 +2712,8 @@ void Spell::SendCastResult(uint8 result)
case 45373: // Bloodberry Elixir
data << uint32(4075);
break;
- default: // default case
- data << uint32(m_spellInfo->AreaId);
+ default: // default case (don't must be)
+ data << uint32(0);
break;
}
break;
@@ -2741,18 +2732,11 @@ void Spell::SendCastResult(uint8 result)
case SPELL_FAILED_EQUIPPED_ITEM_CLASS:
data << uint32(m_spellInfo->EquippedItemClass);
data << uint32(m_spellInfo->EquippedItemSubClassMask);
- data << uint32(m_spellInfo->EquippedItemInventoryTypeMask);
+ //data << uint32(m_spellInfo->EquippedItemInventoryTypeMask);
break;
}
((Player*)m_caster)->GetSession()->SendPacket(&data);
}
- else
- {
- WorldPacket data(SMSG_CLEAR_EXTRA_AURA_INFO, (8+4));
- data.append(m_caster->GetPackGUID());
- data << uint32(m_spellInfo->Id);
- ((Player*)m_caster)->GetSession()->SendPacket(&data);
- }
}
void Spell::SendSpellStart()
@@ -2766,6 +2750,9 @@ void Spell::SendSpellStart()
if(IsRangedSpell())
castFlags |= CAST_FLAG_AMMO;
+ if(m_spellInfo->runeCostID)
+ castFlags |= CAST_FLAG_UNKNOWN10;
+
Unit *target = m_targets.getUnitTarget() ? m_targets.getUnitTarget() : m_caster;
WorldPacket data(SMSG_SPELL_START, (8+8+4+4+2));
@@ -2775,14 +2762,32 @@ void Spell::SendSpellStart()
data.append(m_caster->GetPackGUID());
data.append(m_caster->GetPackGUID());
- data << uint32(m_spellInfo->Id);
- data << uint8(m_cast_count); // single cast or multi 2.3 (0/1)
- data << uint16(castFlags);
- data << uint32(m_timer);
+ data << uint8(m_cast_count); // pending spell cast?
+ data << uint32(m_spellInfo->Id); // spellId
+ data << uint32(castFlags); // cast flags
+ data << uint32(m_timer); // delay?
m_targets.write(&data);
- if( castFlags & CAST_FLAG_AMMO )
+ if ( castFlags & CAST_FLAG_UNKNOWN6 ) // predicted power?
+ data << uint32(0);
+
+ if ( castFlags & CAST_FLAG_UNKNOWN7 ) // rune cooldowns list
+ {
+ uint8 v1 = 0;//m_runesState;
+ uint8 v2 = 0;//((Player*)m_caster)->GetRunesState();
+ data << uint8(v1); // runes state before
+ data << uint8(v2); // runes state after
+ for(uint8 i = 0; i < MAX_RUNES; ++i)
+ {
+ uint8 m = (1 << i);
+ if(m & v1) // usable before...
+ if(!(m & v2)) // ...but on cooldown now...
+ data << uint8(0); // some unknown byte (time?)
+ }
+ }
+
+ if ( castFlags & CAST_FLAG_AMMO )
WriteAmmoToPacket(&data);
m_caster->SendMessageToSet(&data, true);
@@ -2802,24 +2807,68 @@ void Spell::SendSpellGo()
if(IsRangedSpell())
castFlags |= CAST_FLAG_AMMO; // arrows/bullets visual
+ if((m_caster->GetTypeId() == TYPEID_PLAYER) && (m_caster->getClass() == CLASS_DEATH_KNIGHT) && m_spellInfo->runeCostID)
+ {
+ castFlags |= CAST_FLAG_UNKNOWN10; // same as in SMSG_SPELL_START
+ castFlags |= CAST_FLAG_UNKNOWN6; // makes cooldowns visible
+ castFlags |= CAST_FLAG_UNKNOWN7; // rune cooldowns list
+ }
+
WorldPacket data(SMSG_SPELL_GO, 50); // guess size
+
if(m_CastItem)
data.append(m_CastItem->GetPackGUID());
else
data.append(m_caster->GetPackGUID());
data.append(m_caster->GetPackGUID());
- data << uint32(m_spellInfo->Id);
- data << uint16(castFlags);
+ data << uint8(m_cast_count); // pending spell cast?
+ data << uint32(m_spellInfo->Id); // spellId
+ data << uint32(castFlags); // cast flags
data << uint32(getMSTime()); // timestamp
WriteSpellGoTargets(&data);
m_targets.write(&data);
- if( castFlags & CAST_FLAG_AMMO )
+ if ( castFlags & CAST_FLAG_UNKNOWN6 ) // unknown wotlk, predicted power?
+ data << uint32(0);
+
+ if ( castFlags & CAST_FLAG_UNKNOWN7 ) // rune cooldowns list
+ {
+ uint8 v1 = m_runesState;
+ uint8 v2 = ((Player*)m_caster)->GetRunesState();
+ data << uint8(v1); // runes state before
+ data << uint8(v2); // runes state after
+ for(uint8 i = 0; i < MAX_RUNES; ++i)
+ {
+ uint8 m = (1 << i);
+ if(m & v1) // usable before...
+ if(!(m & v2)) // ...but on cooldown now...
+ data << uint8(0); // some unknown byte (time?)
+ }
+ }
+
+ if ( castFlags & CAST_FLAG_UNKNOWN4 ) // unknown wotlk
+ {
+ data << float(0);
+ data << uint32(0);
+ }
+
+ if ( castFlags & CAST_FLAG_AMMO )
WriteAmmoToPacket(&data);
+ if ( castFlags & CAST_FLAG_UNKNOWN5 ) // unknown wotlk
+ {
+ data << uint32(0);
+ data << uint32(0);
+ }
+
+ if ( m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION )
+ {
+ data << uint8(0);
+ }
+
m_caster->SendMessageToSet(&data, true);
}
@@ -2864,15 +2913,36 @@ void Spell::WriteAmmoToPacket( WorldPacket * data )
void Spell::WriteSpellGoTargets( WorldPacket * data )
{
- *data << (uint8)m_countOfHit;
+ // This function also fill data for channeled spells:
+ // m_needAliveTargetMask req for stop channelig if one target die
+ uint32 hit = m_UniqueGOTargetInfo.size(); // Always hits on GO
+ uint32 miss = 0;
+ for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
+ {
+ if ((*ihit).effectMask == 0) // No effect apply - all immuned add state
+ {
+ // possibly SPELL_MISS_IMMUNE2 for this??
+ ihit->missCondition = SPELL_MISS_IMMUNE2;
+ miss++;
+ }
+ else if ((*ihit).missCondition == SPELL_MISS_NONE)
+ hit++;
+ else
+ miss++;
+ }
+
+ *data << (uint8)hit;
for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits
+ {
*data << uint64(ihit->targetGUID);
+ m_needAliveTargetMask |=ihit->effectMask;
+ }
for(std::list<GOTargetInfo>::iterator ighit= m_UniqueGOTargetInfo.begin();ighit != m_UniqueGOTargetInfo.end();++ighit)
*data << uint64(ighit->targetGUID); // Always hits
- *data << (uint8)m_countOfMiss;
+ *data << (uint8)miss;
for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
{
if( ihit->missCondition != SPELL_MISS_NONE ) // Add only miss
@@ -2883,6 +2953,9 @@ void Spell::WriteSpellGoTargets( WorldPacket * data )
*data << uint8(ihit->reflectResult);
}
}
+ // Reset m_needAliveTargetMask for non channeled spell
+ if(!IsChanneledSpell(m_spellInfo))
+ m_needAliveTargetMask = 0;
}
void Spell::SendLogExecute()
@@ -2947,30 +3020,19 @@ void Spell::SendLogExecute()
data << uint8(0);
break;
case SPELL_EFFECT_CREATE_ITEM:
+ case SPELL_EFFECT_CREATE_ITEM_2:
data << uint32(m_spellInfo->EffectItemType[0]);
break;
case SPELL_EFFECT_SUMMON:
- case SPELL_EFFECT_SUMMON_WILD:
- case SPELL_EFFECT_SUMMON_GUARDIAN:
case SPELL_EFFECT_TRANS_DOOR:
case SPELL_EFFECT_SUMMON_PET:
- case SPELL_EFFECT_SUMMON_POSSESSED:
- case SPELL_EFFECT_SUMMON_TOTEM:
case SPELL_EFFECT_SUMMON_OBJECT_WILD:
case SPELL_EFFECT_CREATE_HOUSE:
case SPELL_EFFECT_DUEL:
- case SPELL_EFFECT_SUMMON_TOTEM_SLOT1:
- case SPELL_EFFECT_SUMMON_TOTEM_SLOT2:
- case SPELL_EFFECT_SUMMON_TOTEM_SLOT3:
- case SPELL_EFFECT_SUMMON_TOTEM_SLOT4:
- case SPELL_EFFECT_SUMMON_PHANTASM:
- case SPELL_EFFECT_SUMMON_CRITTER:
case SPELL_EFFECT_SUMMON_OBJECT_SLOT1:
case SPELL_EFFECT_SUMMON_OBJECT_SLOT2:
case SPELL_EFFECT_SUMMON_OBJECT_SLOT3:
case SPELL_EFFECT_SUMMON_OBJECT_SLOT4:
- case SPELL_EFFECT_SUMMON_DEMON:
- case SPELL_EFFECT_150:
if(Unit *unit = m_targets.getUnitTarget())
data.append(unit->GetPackGUID());
else if(m_targets.getItemTargetGUID())
@@ -2989,6 +3051,13 @@ void Spell::SendLogExecute()
else
data << uint8(0);
break;
+ case SPELL_EFFECT_RESURRECT:
+ case SPELL_EFFECT_RESURRECT_NEW:
+ if(Unit *unit = m_targets.getUnitTarget())
+ data.append(unit->GetPackGUID());
+ else
+ data << uint8(0);
+ break;
default:
return;
}
@@ -3002,13 +3071,16 @@ void Spell::SendInterrupted(uint8 result)
{
WorldPacket data(SMSG_SPELL_FAILURE, (8+4+1));
data.append(m_caster->GetPackGUID());
- data << m_spellInfo->Id;
- data << result;
+ data << uint8(m_cast_count);
+ data << uint32(m_spellInfo->Id);
+ data << uint8(result);
m_caster->SendMessageToSet(&data, true);
data.Initialize(SMSG_SPELL_FAILED_OTHER, (8+4));
data.append(m_caster->GetPackGUID());
- data << m_spellInfo->Id;
+ data << uint8(m_cast_count);
+ data << uint32(m_spellInfo->Id);
+ data << uint8(result);
m_caster->SendMessageToSet(&data, true);
}
@@ -3076,10 +3148,19 @@ void Spell::SendChannelStart(uint32 duration)
void Spell::SendResurrectRequest(Player* target)
{
- WorldPacket data(SMSG_RESURRECT_REQUEST, (8+4+2+4));
- data << m_caster->GetGUID();
- data << uint32(1) << uint16(0) << uint32(1);
+ // Both players and NPCs can resurrect using spells - have a look at creature 28487 for example
+ // However, the packet structure differs slightly
+
+ const char* sentName = m_caster->GetTypeId()==TYPEID_PLAYER ?"":m_caster->GetNameForLocaleIdx(target->GetSession()->GetSessionDbLocaleIndex());
+
+ WorldPacket data(SMSG_RESURRECT_REQUEST, (8+4+strlen(sentName)+1+1+1));
+ data << uint64(m_caster->GetGUID());
+ data << uint32(strlen(sentName)+1);
+
+ data << sentName;
+ data << uint8(0);
+ data << uint8(m_caster->GetTypeId()==TYPEID_PLAYER ?0:1);
target->GetSession()->SendPacket(&data);
}
@@ -3132,7 +3213,7 @@ void Spell::TakeCastItem()
if (charges)
{
(charges > 0) ? --charges : ++charges; // abs(charges) less at 1 after use
- if (proto->Stackable < 2)
+ if (proto->Stackable == 1)
m_CastItem->SetSpellCharges(i, charges);
m_CastItem->SetState(ITEM_CHANGED, (Player*)m_caster);
}
@@ -3171,6 +3252,12 @@ void Spell::TakePower()
{
if(ihit->missCondition != SPELL_MISS_NONE && ihit->missCondition != SPELL_MISS_MISS/* && ihit->targetGUID!=m_caster->GetGUID()*/)
hit = false;
+ if (ihit->missCondition != SPELL_MISS_NONE)
+ {
+ //lower spell cost on fail (by talent aura)
+ if(Player *modOwner = ((Player*)m_caster)->GetSpellModOwner())
+ modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, m_powerCost);
+ }
break;
}
if(hit && NeedsComboPoints(m_spellInfo))
@@ -3192,6 +3279,12 @@ void Spell::TakePower()
Powers powerType = Powers(m_spellInfo->powerType);
+ if(powerType == POWER_RUNE)
+ {
+ TakeRunePower();
+ return;
+ }
+
if(hit)
m_caster->ModifyPower(powerType, -m_powerCost);
else
@@ -3202,6 +3295,145 @@ void Spell::TakePower()
m_caster->SetLastManaUse(getMSTime());
}
+void Spell::TakeAmmo()
+{
+ if(m_attackType == RANGED_ATTACK && m_caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ Item *pItem = ((Player*)m_caster)->GetWeaponForAttack( RANGED_ATTACK );
+
+ // wands don't have ammo
+ if(!pItem || pItem->IsBroken() || pItem->GetProto()->SubClass==ITEM_SUBCLASS_WEAPON_WAND)
+ return;
+
+ if( pItem->GetProto()->InventoryType == INVTYPE_THROWN )
+ {
+ if(pItem->GetMaxStackCount()==1)
+ {
+ // decrease durability for non-stackable throw weapon
+ ((Player*)m_caster)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_RANGED);
+ }
+ else
+ {
+ // decrease items amount for stackable throw weapon
+ uint32 count = 1;
+ ((Player*)m_caster)->DestroyItemCount( pItem, count, true);
+ }
+ }
+ else if(uint32 ammo = ((Player*)m_caster)->GetUInt32Value(PLAYER_AMMO_ID))
+ ((Player*)m_caster)->DestroyItemCount(ammo, 1, true);
+ }
+}
+
+uint8 Spell::CheckRuneCost(uint32 runeCostID)
+{
+ if(m_caster->GetTypeId() != TYPEID_PLAYER)
+ return 0;
+
+ Player *plr = (Player*)m_caster;
+
+ if(plr->getClass() != CLASS_DEATH_KNIGHT)
+ return 0;
+
+ SpellRuneCostEntry const *src = sSpellRuneCostStore.LookupEntry(runeCostID);
+
+ if(!src)
+ return 0;
+
+ if(src->NoRuneCost())
+ return 0;
+
+ int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
+
+ for(uint32 i = 0; i < RUNE_DEATH; ++i)
+ {
+ runeCost[i] = src->RuneCost[i];
+ }
+
+ runeCost[RUNE_DEATH] = 0; // calculated later
+
+ for(uint32 i = 0; i < MAX_RUNES; ++i)
+ {
+ uint8 rune = plr->GetCurrentRune(i);
+ if((plr->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0))
+ {
+ runeCost[rune]--;
+ }
+ }
+
+ for(uint32 i = 0; i < RUNE_DEATH; ++i)
+ {
+ if(runeCost[i] > 0)
+ {
+ runeCost[RUNE_DEATH] += runeCost[i];
+ }
+ }
+
+ if(runeCost[RUNE_DEATH] > 0)
+ return SPELL_FAILED_NO_POWER; // not sure if result code is correct
+
+ return 0;
+}
+
+void Spell::TakeRunePower()
+{
+ if(m_caster->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ Player *plr = (Player*)m_caster;
+
+ if(plr->getClass() != CLASS_DEATH_KNIGHT)
+ return;
+
+ SpellRuneCostEntry const *src = sSpellRuneCostStore.LookupEntry(m_spellInfo->runeCostID);
+
+ if(!src || (src->NoRuneCost() && src->NoRunicPowerGain()))
+ return;
+
+ m_runesState = plr->GetRunesState(); // store previous state
+
+ int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
+
+ for(uint32 i = 0; i < RUNE_DEATH; ++i)
+ {
+ runeCost[i] = src->RuneCost[i];
+ }
+
+ runeCost[RUNE_DEATH] = 0; // calculated later
+
+ for(uint32 i = 0; i < MAX_RUNES; ++i)
+ {
+ uint8 rune = plr->GetCurrentRune(i);
+ if((plr->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0))
+ {
+ plr->SetRuneCooldown(i, RUNE_COOLDOWN); // 5*2=10 sec
+ runeCost[rune]--;
+ }
+ }
+
+ runeCost[RUNE_DEATH] = runeCost[RUNE_BLOOD] + runeCost[RUNE_UNHOLY] + runeCost[RUNE_FROST];
+
+ if(runeCost[RUNE_DEATH] > 0)
+ {
+ for(uint32 i = 0; i < MAX_RUNES; ++i)
+ {
+ uint8 rune = plr->GetCurrentRune(i);
+ if((plr->GetRuneCooldown(i) == 0) && (rune == RUNE_DEATH))
+ {
+ plr->SetRuneCooldown(i, RUNE_COOLDOWN); // 5*2=10 sec
+ runeCost[rune]--;
+ plr->ConvertRune(i, plr->GetBaseRune(i));
+ if(runeCost[RUNE_DEATH] == 0)
+ break;
+ }
+ }
+ }
+
+ // you can gain some runic power when use runes
+ float rp = src->runePowerGain;;
+ rp *= sWorld.getRate(RATE_POWER_RUNICPOWER_INCOME);
+ plr->ModifyPower(POWER_RUNIC_POWER, (int32)rp);
+}
+
void Spell::TakeReagents()
{
if(m_IsTriggeredSpell) // reagents used in triggered spell removed by original spell or don't must be removed.
@@ -3210,11 +3442,9 @@ void Spell::TakeReagents()
if (m_caster->GetTypeId() != TYPEID_PLAYER)
return;
- if (m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP &&
- m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION))
- return;
-
Player* p_caster = (Player*)m_caster;
+ if (p_caster->CanNoReagentCast(m_spellInfo))
+ return;
for(uint32 x=0;x<8;x++)
{
@@ -3277,14 +3507,9 @@ void Spell::HandleEffects(Unit *pUnitTarget,Item *pItemTarget,GameObject *pGOTar
gameObjTarget = pGOTarget;
uint8 eff = m_spellInfo->Effect[i];
- uint32 mechanic = m_spellInfo->EffectMechanic[i];
sLog.outDebug( "Spell: Effect : %u", eff);
- //Simply return. Do not display "immune" in red text on client
- if(unitTarget && unitTarget->IsImmunedToSpellEffect(eff, mechanic))
- return;
-
//we do not need DamageMultiplier here.
damage = CalculateDamage(i, NULL);
@@ -3322,6 +3547,9 @@ uint8 Spell::CanCast(bool strict)
// check cooldowns to prevent cheating
if(m_caster->GetTypeId()==TYPEID_PLAYER && ((Player*)m_caster)->HasSpellCooldown(m_spellInfo->Id))
{
+ //can cast triggered (by aura only?) spells while have this flag
+ if (!m_IsTriggeredSpell && ((Player*)m_caster)->HasFlag(PLAYER_FLAGS, PLAYER_ALLOW_ONLY_ABILITY))
+ return SPELL_FAILED_SPELL_IN_PROGRESS;
if(m_triggeredByAuraSpell)
return SPELL_FAILED_DONT_REPORT;
else
@@ -3338,19 +3566,55 @@ uint8 Spell::CanCast(bool strict)
// for now, ignore triggered spells
if( strict && !m_IsTriggeredSpell)
{
- // Cannot be used in this stance/form
- if(uint8 shapeError = GetErrorAtShapeshiftedCast(m_spellInfo, m_caster->m_form))
- return shapeError;
+ bool checkForm = true;
+ // Ignore form req aura
+ Unit::AuraList const& ignore = m_caster->GetAurasByType(SPELL_AURA_MOD_IGNORE_SHAPESHIFT);
+ for(Unit::AuraList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
+ {
+ if (!(*i)->isAffectedOnSpell(m_spellInfo))
+ continue;
+ checkForm = false;
+ break;
+ }
+ if (checkForm)
+ {
+ // Cannot be used in this stance/form
+ if(uint8 shapeError = GetErrorAtShapeshiftedCast(m_spellInfo, m_caster->m_form))
+ return shapeError;
+
+ if ((m_spellInfo->Attributes & SPELL_ATTR_ONLY_STEALTHED) && !(m_caster->HasStealthAura()))
+ return SPELL_FAILED_ONLY_STEALTHED;
+ }
+ }
+
+ bool reqAuraState=true;
+ Unit::AuraList const& stateAuras = m_caster->GetAurasByType(SPELL_AURA_ABILITY_IGNORE_AURASTATE);
+ for(Unit::AuraList::const_iterator j = stateAuras.begin();j != stateAuras.end(); ++j)
+ {
+ if((*j)->isAffectedOnSpell(m_spellInfo))
+ {
+ reqAuraState=false;
+ break;
+ }
+ }
+
+ if (reqAuraState)
+ {
+ // caster state requirements
+ if(m_spellInfo->CasterAuraState && !m_caster->HasAuraState(AuraState(m_spellInfo->CasterAuraState)))
+ return SPELL_FAILED_CASTER_AURASTATE;
+ if(m_spellInfo->CasterAuraStateNot && m_caster->HasAuraState(AuraState(m_spellInfo->CasterAuraStateNot)))
+ return SPELL_FAILED_CASTER_AURASTATE;
- if ((m_spellInfo->Attributes & SPELL_ATTR_ONLY_STEALTHED) && !(m_caster->HasStealthAura()))
- return SPELL_FAILED_ONLY_STEALTHED;
+ if(m_spellInfo->casterAuraSpell && !m_caster->HasAura(m_spellInfo->casterAuraSpell))
+ return SPELL_FAILED_CASTER_AURASTATE;
+ if(m_spellInfo->excludeCasterAuraSpell && m_caster->HasAura(m_spellInfo->excludeCasterAuraSpell))
+ return SPELL_FAILED_CASTER_AURASTATE;
+
+ if(m_caster->isInCombat() && IsNonCombatSpell(m_spellInfo))
+ return SPELL_FAILED_AFFECTING_COMBAT;
}
- // caster state requirements
- if(m_spellInfo->CasterAuraState && !m_caster->HasAuraState(AuraState(m_spellInfo->CasterAuraState)))
- return SPELL_FAILED_CASTER_AURASTATE;
- if(m_spellInfo->CasterAuraStateNot && m_caster->HasAuraState(AuraState(m_spellInfo->CasterAuraStateNot)))
- return SPELL_FAILED_CASTER_AURASTATE;
// cancel autorepeat spells if cast start when moving
// (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
@@ -3366,14 +3630,23 @@ uint8 Spell::CanCast(bool strict)
if(target)
{
- // target state requirements (not allowed state), apply to self also
- if(m_spellInfo->TargetAuraStateNot && target->HasAuraState(AuraState(m_spellInfo->TargetAuraStateNot)))
- return SPELL_FAILED_TARGET_AURASTATE;
+ if (reqAuraState)
+ {
+ // target state requirements (not allowed state), apply to self also
+ if(m_spellInfo->TargetAuraStateNot && target->HasAuraState(AuraState(m_spellInfo->TargetAuraStateNot)))
+ return SPELL_FAILED_TARGET_AURASTATE;
+
+ if(m_spellInfo->targetAuraSpell && !target->HasAura(m_spellInfo->targetAuraSpell))
+ return SPELL_FAILED_TARGET_AURASTATE;
+
+ if(m_spellInfo->excludeTargetAuraSpell && target->HasAura(m_spellInfo->excludeTargetAuraSpell))
+ return SPELL_FAILED_TARGET_AURASTATE;
+ }
if(target != m_caster)
{
// target state requirements (apply to non-self only), to allow cast affects to self like Dirty Deeds
- if(m_spellInfo->TargetAuraState && !target->HasAuraState(AuraState(m_spellInfo->TargetAuraState)))
+ if(reqAuraState && m_spellInfo->TargetAuraState && !target->HasAuraState(AuraState(m_spellInfo->TargetAuraState)))
return SPELL_FAILED_TARGET_AURASTATE;
// Not allow casting on flying player
@@ -3395,6 +3668,20 @@ uint8 Spell::CanCast(bool strict)
}
}
}
+ else if (m_caster->GetTypeId()==TYPEID_PLAYER) // Target - is player caster
+ {
+ // Additional check for some spells
+ // If 0 spell effect empty - client not send target data (need use selection)
+ // TODO: check it on next client version
+ if (m_targets.m_targetMask == TARGET_FLAG_SELF &&
+ m_spellInfo->EffectImplicitTargetA[1] == TARGET_CHAIN_DAMAGE)
+ {
+ if (target = m_caster->GetUnit(*m_caster, ((Player *)m_caster)->GetSelection()))
+ m_targets.setUnitTarget(target);
+ else
+ return SPELL_FAILED_BAD_TARGETS;
+ }
+ }
// check pet presents
for(int j=0;j<3;j++)
@@ -3446,13 +3733,16 @@ uint8 Spell::CanCast(bool strict)
if(IsPositiveSpell(m_spellInfo->Id))
{
- if(target->IsImmunedToSpell(m_spellInfo,false))
+ if(target->IsImmunedToSpell(m_spellInfo))
return SPELL_FAILED_TARGET_AURASTATE;
}
//Must be behind the target.
if( m_spellInfo->AttributesEx2 == 0x100000 && (m_spellInfo->AttributesEx & 0x200) == 0x200 && target->HasInArc(M_PI, m_caster)
- && (m_spellInfo->SpellFamilyName != SPELLFAMILY_DRUID || m_spellInfo->SpellFamilyFlags != 0x0000000000020000LL))
+ //Exclusion for Pounce: Facing Limitation was removed in 2.0.1, but it still uses the same, old Ex-Flags
+ && (!(m_spellInfo->SpellFamilyName == SPELLFAMILY_DRUID && m_spellInfo->SpellFamilyFlags.IsEqual(0x20000,0,0)))
+ //Multilate - same reason
+ && (!(m_spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && m_spellInfo->SpellFamilyFlags[1] & 200000)))
{
SendInterrupted(2);
return SPELL_FAILED_NOT_BEHIND;
@@ -3486,8 +3776,9 @@ uint8 Spell::CanCast(bool strict)
return SPELL_FAILED_NOT_IN_ARENA;
// zone check
- if(!IsSpellAllowedInLocation(m_spellInfo,m_caster->GetMapId(),m_caster->GetZoneId(),m_caster->GetAreaId()))
- return SPELL_FAILED_REQUIRES_AREA;
+ if (uint8 res= GetSpellAllowedInLocationError(m_spellInfo,m_caster->GetMapId(),m_caster->GetZoneId(),m_caster->GetAreaId(),
+ m_caster->GetTypeId()==TYPEID_PLAYER ? ((Player*)m_caster)->GetBattleGroundId() : 0))
+ return res;
// not let players cast spells at mount (and let do it to creatures)
if( m_caster->IsMounted() && m_caster->GetTypeId()==TYPEID_PLAYER && !m_IsTriggeredSpell &&
@@ -3540,7 +3831,7 @@ uint8 Spell::CanCast(bool strict)
cell.data.Part.reserved = ALL_DISTRICT;
MaNGOS::NearestGameObjectEntryInObjectRangeCheck go_check(*m_caster,i_spellST->second.targetEntry,range);
- MaNGOS::GameObjectLastSearcher<MaNGOS::NearestGameObjectEntryInObjectRangeCheck> checker(p_GameObject,go_check);
+ MaNGOS::GameObjectLastSearcher<MaNGOS::NearestGameObjectEntryInObjectRangeCheck> checker(m_caster, p_GameObject,go_check);
TypeContainerVisitor<MaNGOS::GameObjectLastSearcher<MaNGOS::NearestGameObjectEntryInObjectRangeCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
@@ -3578,7 +3869,7 @@ uint8 Spell::CanCast(bool strict)
cell.SetNoCreate(); // Really don't know what is that???
MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*m_caster,i_spellST->second.targetEntry,i_spellST->second.type!=SPELL_TARGET_TYPE_DEAD,range);
- MaNGOS::CreatureLastSearcher<MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(p_Creature, u_check);
+ MaNGOS::CreatureLastSearcher<MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(m_caster, p_Creature, u_check);
TypeContainerVisitor<MaNGOS::CreatureLastSearcher<MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck>, GridTypeMapContainer > grid_creature_searcher(searcher);
@@ -3686,7 +3977,7 @@ uint8 Spell::CanCast(bool strict)
case SPELL_EFFECT_SCHOOL_DAMAGE:
{
// Hammer of Wrath
- if(m_spellInfo->SpellVisual == 7250)
+ if(m_spellInfo->SpellVisual[0] == 7250)
{
if (!m_targets.getUnitTarget())
return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
@@ -3711,15 +4002,9 @@ uint8 Spell::CanCast(bool strict)
if(!learn_spellproto)
return SPELL_FAILED_NOT_KNOWN;
- if(!pet->CanTakeMoreActiveSpells(learn_spellproto->Id))
- return SPELL_FAILED_TOO_MANY_SKILLS;
-
if(m_spellInfo->spellLevel > pet->getLevel())
return SPELL_FAILED_LOWLEVEL;
- if(!pet->HasTPForSpell(learn_spellproto->Id))
- return SPELL_FAILED_TRAINING_POINTS;
-
break;
}
case SPELL_EFFECT_LEARN_PET_SPELL:
@@ -3734,20 +4019,18 @@ uint8 Spell::CanCast(bool strict)
if(!learn_spellproto)
return SPELL_FAILED_NOT_KNOWN;
- if(!pet->CanTakeMoreActiveSpells(learn_spellproto->Id))
- return SPELL_FAILED_TOO_MANY_SKILLS;
-
if(m_spellInfo->spellLevel > pet->getLevel())
return SPELL_FAILED_LOWLEVEL;
- if(!pet->HasTPForSpell(learn_spellproto->Id))
- return SPELL_FAILED_TRAINING_POINTS;
-
break;
}
case SPELL_EFFECT_FEED_PET:
{
- if (m_caster->GetTypeId() != TYPEID_PLAYER || !m_targets.getItemTarget() )
+ if (m_caster->GetTypeId() != TYPEID_PLAYER)
+ return SPELL_FAILED_BAD_TARGETS;
+
+ Item* foodItem = m_targets.getItemTarget();
+ if(!foodItem)
return SPELL_FAILED_BAD_TARGETS;
Pet* pet = m_caster->GetPet();
@@ -3755,10 +4038,10 @@ uint8 Spell::CanCast(bool strict)
if(!pet)
return SPELL_FAILED_NO_PET;
- if(!pet->HaveInDiet(m_targets.getItemTarget()->GetProto()))
+ if(!pet->HaveInDiet(foodItem->GetProto()))
return SPELL_FAILED_WRONG_PET_FOOD;
- if(!pet->GetCurrentFoodBenefitLevel(m_targets.getItemTarget()->GetProto()->ItemLevel))
+ if(!pet->GetCurrentFoodBenefitLevel(foodItem->GetProto()->ItemLevel))
return SPELL_FAILED_FOOD_LOWLEVEL;
if(m_caster->isInCombat() || pet->isInCombat())
@@ -3845,27 +4128,27 @@ uint8 Spell::CanCast(bool strict)
{
// check for lock - key pair (checked by client also, just prevent cheating
bool ok_key = false;
- for(int it = 0; it < 5; ++it)
+ for(int it = 0; it < 8; ++it)
{
- switch(lockInfo->keytype[it])
+ switch(lockInfo->Type[it])
{
case LOCK_KEY_NONE:
break;
case LOCK_KEY_ITEM:
{
- if(lockInfo->key[it])
+ if(lockInfo->Index[it])
{
- if(m_CastItem && m_CastItem->GetEntry()==lockInfo->key[it])
+ if(m_CastItem && m_CastItem->GetEntry()==lockInfo->Index[it])
ok_key =true;
break;
}
}
case LOCK_KEY_SKILL:
{
- if(uint32(m_spellInfo->EffectMiscValue[i])!=lockInfo->key[it])
+ if(uint32(m_spellInfo->EffectMiscValue[i])!=lockInfo->Index[it])
break;
- switch(lockInfo->key[it])
+ switch(lockInfo->Index[it])
{
case LOCKTYPE_HERBALISM:
if(((Player*)m_caster)->HasSkill(SKILL_HERBALISM))
@@ -3923,9 +4206,9 @@ uint8 Spell::CanCast(bool strict)
{
// check for lock - key pair
bool ok = false;
- for(int it = 0; it < 5; ++it)
+ for(int it = 0; it < 8; ++it)
{
- if(lockInfo->keytype[it]==LOCK_KEY_ITEM && lockInfo->key[it] && m_CastItem && m_CastItem->GetEntry()==lockInfo->key[it])
+ if(lockInfo->Type[it]==LOCK_KEY_ITEM && lockInfo->Index[it] && m_CastItem && m_CastItem->GetEntry()==lockInfo->Index[it])
{
// if so, we're good to go
ok = true;
@@ -3936,9 +4219,9 @@ uint8 Spell::CanCast(bool strict)
break;
if (m_spellInfo->EffectMiscValue[i] == LOCKTYPE_PICKLOCK)
- ReqValue = lockInfo->requiredlockskill;
+ ReqValue = lockInfo->Skill[1];
else
- ReqValue = lockInfo->requiredminingskill;
+ ReqValue = lockInfo->Skill[0];
}
// skill doesn't meet the required value
@@ -3962,9 +4245,7 @@ uint8 Spell::CanCast(bool strict)
break;
}
- // This is generic summon effect now and don't make this check for summon types similar
- // SPELL_EFFECT_SUMMON_CRITTER, SPELL_EFFECT_SUMMON_WILD or SPELL_EFFECT_SUMMON_GUARDIAN.
- // These won't show up in m_caster->GetPetGUID()
+ // This is generic summon effect
case SPELL_EFFECT_SUMMON:
{
switch(m_spellInfo->EffectMiscValueB[i])
@@ -3985,11 +4266,8 @@ uint8 Spell::CanCast(bool strict)
}
break;
}
- // Don't make this check for SPELL_EFFECT_SUMMON_CRITTER, SPELL_EFFECT_SUMMON_WILD or SPELL_EFFECT_SUMMON_GUARDIAN.
- // These won't show up in m_caster->GetPetGUID()
- case SPELL_EFFECT_SUMMON_POSSESSED:
+ // Not used for summon?
case SPELL_EFFECT_SUMMON_PHANTASM:
- case SPELL_EFFECT_SUMMON_DEMON:
{
if(m_caster->GetPetGUID())
return SPELL_FAILED_ALREADY_HAVE_SUMMON;
@@ -4134,17 +4412,14 @@ uint8 Spell::CanCast(bool strict)
return SPELL_FAILED_NO_MOUNTS_ALLOWED;
// Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells
- if (m_caster->GetTypeId()==TYPEID_PLAYER && !sMapStore.LookupEntry(m_caster->GetMapId())->IsMountAllowed() && !m_IsTriggeredSpell && !m_spellInfo->AreaId)
- return SPELL_FAILED_NO_MOUNTS_ALLOWED;
-
- if (m_caster->GetAreaId()==35)
+ if (m_caster->GetTypeId()==TYPEID_PLAYER && !sMapStore.LookupEntry(m_caster->GetMapId())->IsMountAllowed() && !m_IsTriggeredSpell && !m_spellInfo->AreaGroupId)
return SPELL_FAILED_NO_MOUNTS_ALLOWED;
ShapeshiftForm form = m_caster->m_form;
if( form == FORM_CAT || form == FORM_TREE || form == FORM_TRAVEL ||
form == FORM_AQUA || form == FORM_BEAR || form == FORM_DIREBEAR ||
form == FORM_CREATUREBEAR || form == FORM_GHOSTWOLF || form == FORM_FLIGHT ||
- form == FORM_FLIGHT_EPIC || form == FORM_MOONKIN )
+ form == FORM_FLIGHT_EPIC || form == FORM_MOONKIN || form == FORM_METAMORPHOSIS )
return SPELL_FAILED_NOT_SHAPESHIFT;
break;
@@ -4163,11 +4438,10 @@ uint8 Spell::CanCast(bool strict)
case SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED:
case SPELL_AURA_FLY:
{
- // not allow cast fly spells at old maps by players (all spells is self target)
+ // not allow cast fly spells at old maps by players (all spells is self target)
if(m_caster->GetTypeId()==TYPEID_PLAYER)
{
- if( !((Player*)m_caster)->isGameMaster() &&
- GetVirtualMapForMapAndZone(m_caster->GetMapId(),m_caster->GetZoneId()) != 530)
+ if( !((Player*)m_caster)->IsAllowUseFlyMountsHere() )
return SPELL_FAILED_NOT_HERE;
}
break;
@@ -4282,15 +4556,16 @@ uint8 Spell::CheckCasterAuras() const
//Check whether the cast should be prevented by any state you might have.
uint8 prevented_reason = 0;
// Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out
- if(!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_STUNNED) && m_caster->HasAuraType(SPELL_AURA_MOD_STUN))
+ uint32 unitflag = m_caster->GetUInt32Value(UNIT_FIELD_FLAGS); // Get unit state
+ if(unitflag & UNIT_FLAG_STUNNED && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_STUNNED))
prevented_reason = SPELL_FAILED_STUNNED;
- else if(m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED) && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_CONFUSED))
+ else if(unitflag & UNIT_FLAG_CONFUSED && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_CONFUSED))
prevented_reason = SPELL_FAILED_CONFUSED;
- else if(m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING) && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_FEARED))
+ else if(unitflag & UNIT_FLAG_FLEEING && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_FEARED))
prevented_reason = SPELL_FAILED_FLEEING;
- else if(m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED) && m_spellInfo->PreventionType==SPELL_PREVENTION_TYPE_SILENCE)
+ else if(unitflag & UNIT_FLAG_SILENCED && m_spellInfo->PreventionType==SPELL_PREVENTION_TYPE_SILENCE)
prevented_reason = SPELL_FAILED_SILENCED;
- else if(m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED) && m_spellInfo->PreventionType==SPELL_PREVENTION_TYPE_PACIFY)
+ else if(unitflag & UNIT_FLAG_PACIFIED && m_spellInfo->PreventionType==SPELL_PREVENTION_TYPE_PACIFY)
prevented_reason = SPELL_FAILED_PACIFIED;
// Attr must make flag drop spell totally immune from all effects
@@ -4481,9 +4756,12 @@ int32 Spell::CalculatePowerCost()
case POWER_FOCUS:
case POWER_ENERGY:
case POWER_HAPPINESS:
- // case POWER_RUNES:
powerCost += m_spellInfo->ManaCostPercentage * m_caster->GetMaxPower(Powers(m_spellInfo->powerType)) / 100;
break;
+ case POWER_RUNE:
+ case POWER_RUNIC_POWER:
+ sLog.outDebug("Spell::CalculateManaCost: Not implemented yet!");
+ break;
default:
sLog.outError("Spell::CalculateManaCost: Unknown power type '%d' in spell %d", m_spellInfo->powerType, m_spellInfo->Id);
return 0;
@@ -4528,6 +4806,11 @@ uint8 Spell::CheckPower()
sLog.outError("Spell::CheckMana: Unknown power type '%d'", m_spellInfo->powerType);
return SPELL_FAILED_UNKNOWN;
}
+
+ uint8 failReason = CheckRuneCost(m_spellInfo->runeCostID);
+ if(failReason)
+ return failReason;
+
// Check power amount
Powers powerType = Powers(m_spellInfo->powerType);
if(m_caster->GetPower(powerType) < m_powerCost)
@@ -4647,8 +4930,8 @@ uint8 Spell::CheckItems()
cell.data.Part.reserved = ALL_DISTRICT;
GameObject* ok = NULL;
- Trinity::GameObjectFocusCheck go_check(m_caster,m_spellInfo->RequiresSpellFocus);
- Trinity::GameObjectSearcher<Trinity::GameObjectFocusCheck> checker(ok,go_check);
+ MaNGOS::GameObjectFocusCheck go_check(m_caster,m_spellInfo->RequiresSpellFocus);
+ MaNGOS::GameObjectSearcher<MaNGOS::GameObjectFocusCheck> checker(m_caster,ok,go_check);
TypeContainerVisitor<Trinity::GameObjectSearcher<Trinity::GameObjectFocusCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
@@ -4660,8 +4943,7 @@ uint8 Spell::CheckItems()
focusObject = ok; // game object found in range
}
- if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP &&
- m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION)))
+ if (!p_caster->CanNoReagentCast(m_spellInfo))
{
for(uint32 i=0;i<8;i++)
{
@@ -4746,6 +5028,7 @@ uint8 Spell::CheckItems()
break;
}
case SPELL_EFFECT_ENCHANT_ITEM:
+ case SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC:
{
Item* targetItem = m_targets.getItemTarget();
if(!targetItem)
@@ -4829,13 +5112,36 @@ uint8 Spell::CheckItems()
return SPELL_FAILED_LOW_CASTLEVEL;
//make sure the player has the required ores in inventory
if(m_targets.getItemTarget()->GetCount() < 5)
- return SPELL_FAILED_PROSPECT_NEED_MORE;
+ return SPELL_FAILED_NEED_MORE_ITEMS;
if(!LootTemplates_Prospecting.HaveLootFor(m_targets.getItemTargetEntry()))
return SPELL_FAILED_CANT_BE_PROSPECTED;
break;
}
+ case SPELL_EFFECT_MILLING:
+ {
+ if(!m_targets.getItemTarget())
+ return SPELL_FAILED_CANT_BE_MILLED;
+ //ensure item is a millable herb
+ if(!(m_targets.getItemTarget()->GetProto()->BagFamily & BAG_FAMILY_MASK_HERBS) || m_targets.getItemTarget()->GetProto()->Class != ITEM_CLASS_TRADE_GOODS)
+ return SPELL_FAILED_CANT_BE_MILLED;
+ //prevent milling in trade slot
+ if( m_targets.getItemTarget()->GetOwnerGUID() != m_caster->GetGUID() )
+ return SPELL_FAILED_CANT_BE_MILLED;
+ //Check for enough skill in inscription
+ uint32 item_millingskilllevel = m_targets.getItemTarget()->GetProto()->RequiredSkillRank;
+ if(item_millingskilllevel >p_caster->GetSkillValue(SKILL_INSCRIPTION))
+ return SPELL_FAILED_LOW_CASTLEVEL;
+ //make sure the player has the required herbs in inventory
+ if(m_targets.getItemTarget()->GetCount() < 5)
+ return SPELL_FAILED_NEED_MORE_ITEMS;
+
+ if(!LootTemplates_Milling.HaveLootFor(m_targets.getItemTargetEntry()))
+ return SPELL_FAILED_CANT_BE_MILLED;
+
+ break;
+ }
case SPELL_EFFECT_WEAPON_DAMAGE:
case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
{
@@ -4915,18 +5221,22 @@ void Spell::Delayed() // only called in DealDamage()
//if (m_spellState == SPELL_STATE_DELAYED)
// return; // spell is active and can't be time-backed
+ if(isDelayableNoMore()) // Spells may only be delayed twice
+ return;
+
// spells not loosing casting time ( slam, dynamites, bombs.. )
//if(!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE))
// return;
- //check resist chance
- int32 resistChance = 100; //must be initialized to 100 for percent modifiers
- ((Player*)m_caster)->ApplySpellMod(m_spellInfo->Id,SPELLMOD_NOT_LOSE_CASTING_TIME,resistChance, this);
- resistChance += m_caster->GetTotalAuraModifier(SPELL_AURA_RESIST_PUSHBACK) - 100;
- if (roll_chance_i(resistChance))
+ //check pushback reduce
+ int32 delaytime = 500; // spellcasting delay is normally 500ms
+ int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
+ ((Player*)m_caster)->ApplySpellMod(m_spellInfo->Id,SPELLMOD_NOT_LOSE_CASTING_TIME, delayReduce, this);
+ delayReduce += m_caster->GetTotalAuraModifier(SPELL_AURA_REDUCE_PUSHBACK) - 100;
+ if(delayReduce >= 100)
return;
- int32 delaytime = GetNextDelayAtDamageMsTime();
+ delaytime = delaytime * (100 - delayReduce) / 100;
if(int32(m_timer) + delaytime > m_casttime)
{
@@ -4950,14 +5260,18 @@ void Spell::DelayedChannel()
if(!m_caster || m_caster->GetTypeId() != TYPEID_PLAYER || getState() != SPELL_STATE_CASTING)
return;
- //check resist chance
- int32 resistChance = 100; //must be initialized to 100 for percent modifiers
- ((Player*)m_caster)->ApplySpellMod(m_spellInfo->Id,SPELLMOD_NOT_LOSE_CASTING_TIME,resistChance, this);
- resistChance += m_caster->GetTotalAuraModifier(SPELL_AURA_RESIST_PUSHBACK) - 100;
- if (roll_chance_i(resistChance))
+ if(isDelayableNoMore()) // Spells may only be delayed twice
+ return;
+
+ //check pushback reduce
+ int32 delaytime = GetSpellDuration(m_spellInfo) * 25 / 100; // channeling delay is normally 25% of its time per hit
+ int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
+ ((Player*)m_caster)->ApplySpellMod(m_spellInfo->Id,SPELLMOD_NOT_LOSE_CASTING_TIME,delayReduce, this);
+ delayReduce += m_caster->GetTotalAuraModifier(SPELL_AURA_REDUCE_PUSHBACK) - 100;
+ if(delayReduce >= 100)
return;
- int32 delaytime = GetNextDelayAtDamageMsTime();
+ delaytime = delaytime * (100 - delayReduce) / 100;
if(int32(m_timer) < delaytime)
{
@@ -5011,9 +5325,9 @@ void Spell::UpdatePointers()
m_targets.Update(m_caster);
}
-bool Spell::IsAffectedBy(SpellEntry const *spellInfo, uint32 effectId)
+bool Spell::IsAffectedByAura(Aura *aura)
{
- return spellmgr.IsAffectedBySpell(m_spellInfo,spellInfo->Id,effectId,spellInfo->EffectItemType[effectId]);
+ return spellmgr.IsAffectedByMod(m_spellInfo, aura->getAuraSpellMod());
}
bool Spell::CheckTargetCreatureType(Unit* target) const
@@ -5021,7 +5335,7 @@ bool Spell::CheckTargetCreatureType(Unit* target) const
uint32 spellCreatureTargetMask = m_spellInfo->TargetCreatureType;
// Curse of Doom : not find another way to fix spell target check :/
- if(m_spellInfo->SpellFamilyName==SPELLFAMILY_WARLOCK && m_spellInfo->SpellFamilyFlags == 0x0200000000LL)
+ if(m_spellInfo->SpellFamilyName==SPELLFAMILY_WARLOCK && m_spellInfo->SpellFamilyFlags.IsEqual(0,0x02,0))
{
// not allow cast at player
if(target->GetTypeId()==TYPEID_PLAYER)
@@ -5064,6 +5378,12 @@ bool Spell::CheckTarget( Unit* target, uint32 eff, bool hitPhase )
return false;
}
+ // Check Aura spell req (need for AoE spells)
+ if(m_spellInfo->targetAuraSpell && !target->HasAura(m_spellInfo->targetAuraSpell))
+ return false;
+ if (m_spellInfo->excludeTargetAuraSpell && target->HasAura(m_spellInfo->excludeTargetAuraSpell))
+ return false;
+
// Check targets for not_selectable unit flag and remove
// A player can cast spells on his pet (or other controlled unit) though in any state
if (target != m_caster && target->GetCharmerOrOwnerGUID() != m_caster->GetGUID())
@@ -5124,7 +5444,13 @@ bool Spell::CheckTarget( Unit* target, uint32 eff, bool hitPhase )
// all ok by some way or another, skip normal check
break;
default: // normal case
- if(target!=m_caster && !target->IsWithinLOSInMap(m_caster))
+ // Get GO cast coordinates if original caster -> GO
+ WorldObject *caster = NULL;
+ if (m_originalCasterGUID)
+ caster = ObjectAccessor::GetGameObject(*m_caster, m_originalCasterGUID);
+ if (!caster)
+ caster = m_caster;
+ if(target!=m_caster && !target->IsWithinLOSInMap(caster))
return false;
break;
}
@@ -5143,9 +5469,8 @@ Unit* Spell::SelectMagnetTarget()
{
if(Unit* magnet = (*itr)->GetCaster())
{
- if((*itr)->m_procCharges>0)
+ if((*itr)->DropAuraCharge())
{
- (*itr)->SetAuraProcCharges((*itr)->m_procCharges-1);
target = magnet;
m_targets.setUnitTarget(target);
AddUnitTarget(target, 0);
@@ -5169,7 +5494,7 @@ Unit* Spell::SelectMagnetTarget()
bool Spell::IsNeedSendToClient() const
{
- return m_spellInfo->SpellVisual!=0 || IsChanneledSpell(m_spellInfo) ||
+ return m_spellInfo->SpellVisual[0] || m_spellInfo->SpellVisual[1] || IsChanneledSpell(m_spellInfo) ||
m_spellInfo->speed > 0.0f || !m_triggeredByAuraSpell && !m_IsTriggeredSpell;
}
@@ -5350,6 +5675,14 @@ void Spell::CalculateDamageDoneForAllTargets()
}
}
+ bool usesAmmo=true;
+ Unit::AuraList const& Auras = m_caster->GetAurasByType(SPELL_AURA_ABILITY_CONSUME_NO_AMMO);
+ for(Unit::AuraList::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)
{
TargetInfo &target = *ihit;
@@ -5362,6 +5695,28 @@ void Spell::CalculateDamageDoneForAllTargets()
if (!unit)
continue;
+ if (usesAmmo)
+ {
+ bool ammoTaken=false;
+ for (uint8 i=0;i<3;i++)
+ {
+ if (!(mask & 1<<i))
+ continue;
+ switch (m_spellInfo->Effect[i])
+ {
+ case SPELL_EFFECT_SCHOOL_DAMAGE:
+ case SPELL_EFFECT_WEAPON_DAMAGE:
+ case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
+ case SPELL_EFFECT_NORMALIZED_WEAPON_DMG:
+ case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE:
+ ammoTaken=true;
+ TakeAmmo();
+ }
+ if (ammoTaken)
+ break;
+ }
+ }
+
if (target.missCondition==SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
target.damage += CalculateDamageDone(unit, mask, multiplier);
else if (target.missCondition == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit)
diff --git a/src/game/Spell.h b/src/game/Spell.h
index 42725aa11c7..9f29d3bf8d7 100644
--- a/src/game/Spell.h
+++ b/src/game/Spell.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -47,26 +47,51 @@ enum SpellCastTargetFlags
TARGET_FLAG_RESURRECTABLE = 0x8000*/
TARGET_FLAG_SELF = 0x00000000,
+ TARGET_FLAG_UNUSED1 = 0x00000001, // not used in any spells as of 3.0.3 (can be set dynamically)
TARGET_FLAG_UNIT = 0x00000002, // pguid
+ TARGET_FLAG_UNUSED2 = 0x00000004, // not used in any spells as of 3.0.3 (can be set dynamically)
+ TARGET_FLAG_UNUSED3 = 0x00000008, // not used in any spells as of 3.0.3 (can be set dynamically)
TARGET_FLAG_ITEM = 0x00000010, // pguid
TARGET_FLAG_SOURCE_LOCATION = 0x00000020, // 3 float
TARGET_FLAG_DEST_LOCATION = 0x00000040, // 3 float
- TARGET_FLAG_OBJECT_UNK = 0x00000080, // ?
+ TARGET_FLAG_OBJECT_UNK = 0x00000080, // used in 7 spells only
+ TARGET_FLAG_UNIT_UNK = 0x00000100, // looks like self target (480 spells)
TARGET_FLAG_PVP_CORPSE = 0x00000200, // pguid
- TARGET_FLAG_OBJECT = 0x00000800, // pguid
- TARGET_FLAG_TRADE_ITEM = 0x00001000, // pguid
- TARGET_FLAG_STRING = 0x00002000, // string
- TARGET_FLAG_UNK1 = 0x00004000, // ?
- TARGET_FLAG_CORPSE = 0x00008000, // pguid
- TARGET_FLAG_UNK2 = 0x00010000 // pguid
+ TARGET_FLAG_UNIT_CORPSE = 0x00000400, // 10 spells (gathering professions)
+ TARGET_FLAG_OBJECT = 0x00000800, // pguid, 2 spells
+ TARGET_FLAG_TRADE_ITEM = 0x00001000, // pguid, 0 spells
+ TARGET_FLAG_STRING = 0x00002000, // string, 0 spells
+ TARGET_FLAG_UNK1 = 0x00004000, // 199 spells, opening object/lock
+ TARGET_FLAG_CORPSE = 0x00008000, // pguid, resurrection spells
+ TARGET_FLAG_UNK2 = 0x00010000, // pguid, not used in any spells as of 3.0.3 (can be set dynamically)
+ TARGET_FLAG_GLYPH = 0x00020000 // used in glyph spells
};
enum SpellCastFlags
{
+ CAST_FLAG_NONE = 0x00000000,
+ CAST_FLAG_UNKNOWN0 = 0x00000001, // may be pending spell cast
CAST_FLAG_UNKNOWN1 = 0x00000002,
+ CAST_FLAG_UNKNOWN11 = 0x00000004,
+ CAST_FLAG_UNKNOWN12 = 0x00000008,
CAST_FLAG_UNKNOWN2 = 0x00000010,
- CAST_FLAG_AMMO = 0x00000020,
- CAST_FLAG_UNKNOWN3 = 0x00000100
+ CAST_FLAG_AMMO = 0x00000020, // Projectiles visual
+ CAST_FLAG_UNKNOWN8 = 0x00000040,
+ CAST_FLAG_UNKNOWN9 = 0x00000080,
+ CAST_FLAG_UNKNOWN3 = 0x00000100,
+ CAST_FLAG_UNKNOWN13 = 0x00000200,
+ CAST_FLAG_UNKNOWN14 = 0x00000400,
+ CAST_FLAG_UNKNOWN6 = 0x00000800, // wotlk, trigger rune cooldown
+ CAST_FLAG_UNKNOWN15 = 0x00001000,
+ CAST_FLAG_UNKNOWN16 = 0x00002000,
+ CAST_FLAG_UNKNOWN17 = 0x00004000,
+ CAST_FLAG_UNKNOWN18 = 0x00008000,
+ CAST_FLAG_UNKNOWN19 = 0x00010000,
+ CAST_FLAG_UNKNOWN4 = 0x00020000, // wotlk
+ CAST_FLAG_UNKNOWN10 = 0x00040000,
+ CAST_FLAG_UNKNOWN5 = 0x00080000, // wotlk
+ CAST_FLAG_UNKNOWN20 = 0x00100000,
+ CAST_FLAG_UNKNOWN7 = 0x00200000 // wotlk, rune cooldown list
};
enum SpellRangeFlag
@@ -136,6 +161,7 @@ class SpellCastTargets
void setUnitTarget(Unit *target);
void setDestination(float x, float y, float z, bool send = true, int32 mapId = -1);
void setDestination(Unit *target, bool send = true);
+ void setSource(float x, float y, float z);
uint64 getGOTargetGUID() const { return m_GOTargetGUID; }
GameObject *getGOTarget() const { return m_GOTarget; }
@@ -234,6 +260,7 @@ class Spell
void EffectHealthLeech(uint32 i);
void EffectQuestComplete(uint32 i);
void EffectCreateItem(uint32 i);
+ void EffectCreateItem2(uint32 i);
void EffectPersistentAA(uint32 i);
void EffectEnergize(uint32 i);
void EffectOpenLock(uint32 i);
@@ -276,6 +303,7 @@ class Spell
void EffectStuck(uint32 i);
void EffectSummonPlayer(uint32 i);
void EffectActivateObject(uint32 i);
+ void EffectApplyGlyph(uint32 i);
void EffectSummonTotem(uint32 i);
void EffectEnchantHeldItem(uint32 i);
void EffectSummonObject(uint32 i);
@@ -293,6 +321,8 @@ class Spell
void EffectSkinning(uint32 i);
void EffectCharge(uint32 i);
void EffectProspecting(uint32 i);
+ void EffectMilling(uint32 i);
+ void EffectRenamePet(uint32 i);
void EffectSendTaxi(uint32 i);
void EffectSummonCritter(uint32 i);
void EffectKnockBack(uint32 i);
@@ -319,16 +349,22 @@ class Spell
void EffectKillCredit(uint32 i);
void EffectQuestFail(uint32 i);
void EffectRedirectThreat(uint32 i);
+ void EffectActivateRune(uint32 i);
+ void EffectTitanGrip(uint32 i);
+ void EffectEnchantItemPrismatic(uint32 i);
Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 originalCasterGUID = 0, Spell** triggeringContainer = NULL, bool skipCheck = false );
~Spell();
- void prepare(SpellCastTargets * targets, Aura* triggeredByAura = NULL);
+ void prepare(SpellCastTargets const* targets, Aura* triggeredByAura = NULL);
void cancel(bool report = true);
void update(uint32 difftime);
void cast(bool skipCheck = false);
void finish(bool ok = true);
void TakePower();
+ void TakeAmmo();
+ uint8 CheckRuneCost(uint32 runeCostID);
+ void TakeRunePower();
void TakeReagents();
void TakeCastItem();
void TriggerSpell();
@@ -354,11 +390,10 @@ class Spell
bool HaveTargetsForEffect(uint8 effect) const;
void Delayed();
void DelayedChannel();
- inline uint32 getState() const { return m_spellState; }
+ uint32 getState() const { return m_spellState; }
void setState(uint32 state) { m_spellState = state; }
void DoCreateItem(uint32 i, uint32 itemtype);
-
void WriteSpellGoTargets( WorldPacket * data );
void WriteAmmoToPacket( WorldPacket * data );
void FillTargetMap();
@@ -388,6 +423,8 @@ class Spell
Item* m_CastItem;
uint64 m_castItemGUID;
uint8 m_cast_count;
+ uint32 m_glyphIndex;
+ uint32 m_preCastSpell;
SpellCastTargets m_targets;
int32 GetCastTime() const { return m_casttime; }
@@ -424,7 +461,7 @@ class Spell
void UpdatePointers(); // must be used at call Spell code after time delay (non triggered spell cast/update spell call/etc)
- bool IsAffectedBy(SpellEntry const *spellInfo, uint32 effectId);
+ bool IsAffectedByAura(Aura *aura);
bool CheckTargetCreatureType(Unit* target) const;
@@ -451,9 +488,17 @@ class Spell
int32 m_casttime; // Calculated spell cast time initialized only in Spell::prepare
bool m_canReflect; // can reflect this spell?
bool m_autoRepeat;
+ uint8 m_runesState;
uint8 m_delayAtDamageCount;
- int32 GetNextDelayAtDamageMsTime() { return m_delayAtDamageCount < 5 ? 1000 - (m_delayAtDamageCount++)* 200 : 200; }
+ bool isDelayableNoMore()
+ {
+ if(m_delayAtDamageCount >= 2)
+ return true;
+
+ m_delayAtDamageCount++;
+ return false;
+ }
// Delayed spells system
uint64 m_delayStart; // time of spell delay start, filled by event handler, zero = just started
@@ -497,8 +542,6 @@ class Spell
// Spell target subsystem
//*****************************************
// Targets store structures and data
- uint32 m_countOfHit;
- uint32 m_countOfMiss;
struct TargetInfo
{
uint64 targetGUID;
diff --git a/src/game/SpellAuraDefines.h b/src/game/SpellAuraDefines.h
index cf628515925..b5a33052341 100644
--- a/src/game/SpellAuraDefines.h
+++ b/src/game/SpellAuraDefines.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -20,14 +20,19 @@
#ifndef TRINITY_SPELLAURADEFINES_H
#define TRINITY_SPELLAURADEFINES_H
-#define MAX_AURAS 56
-#define MAX_POSITIVE_AURAS 40
+#define MAX_AURAS 64 // client support up to 255, but it will cause problems with group auras updating
enum AURA_FLAGS
{
- AFLAG_NEGATIVE = 0x09,
- AFLAG_POSITIVE = 0x1F,
- AFLAG_MASK = 0xFF
+ AFLAG_NONE = 0x00,
+ AFLAG_EFF_INDEX_0 = 0x01,
+ AFLAG_EFF_INDEX_1 = 0x02,
+ AFLAG_EFF_INDEX_2 = 0x04,
+ AFLAG_NOT_CASTER = 0x08,
+ AFLAG_POSITIVE = 0x10,
+ AFLAG_DURATION = 0x20,
+ AFLAG_UNK2 = 0x40,
+ AFLAG_NEGATIVE = 0x80
};
//m_schoolAbsorb
@@ -85,11 +90,11 @@ enum AuraType
SPELL_AURA_PROC_TRIGGER_DAMAGE = 43,
SPELL_AURA_TRACK_CREATURES = 44,
SPELL_AURA_TRACK_RESOURCES = 45,
- SPELL_AURA_MOD_PARRY_SKILL = 46,
+ SPELL_AURA_46 = 46, // Ignore all Gear test spells
SPELL_AURA_MOD_PARRY_PERCENT = 47,
- SPELL_AURA_MOD_DODGE_SKILL = 48,
+ SPELL_AURA_48 = 48, // One periodic spell
SPELL_AURA_MOD_DODGE_PERCENT = 49,
- SPELL_AURA_MOD_BLOCK_SKILL = 50,
+ SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT = 50,
SPELL_AURA_MOD_BLOCK_PERCENT = 51,
SPELL_AURA_MOD_CRIT_PERCENT = 52,
SPELL_AURA_PERIODIC_LEECH = 53,
@@ -104,7 +109,7 @@ enum AuraType
SPELL_AURA_PERIODIC_HEALTH_FUNNEL = 62,
SPELL_AURA_PERIODIC_MANA_FUNNEL = 63,
SPELL_AURA_PERIODIC_MANA_LEECH = 64,
- SPELL_AURA_MOD_CASTING_SPEED = 65,
+ SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK = 65,
SPELL_AURA_FEIGN_DEATH = 66,
SPELL_AURA_MOD_DISARM = 67,
SPELL_AURA_MOD_STALKED = 68,
@@ -184,11 +189,11 @@ enum AuraType
SPELL_AURA_MOD_BASE_RESISTANCE_PCT = 142,
SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE = 143,
SPELL_AURA_SAFE_FALL = 144,
- SPELL_AURA_CHARISMA = 145,
- SPELL_AURA_PERSUADED = 146,
- SPELL_AURA_ADD_CREATURE_IMMUNITY = 147,
+ SPELL_AURA_MOD_PET_TALENT_POINTS = 145,
+ SPELL_AURA_ALLOW_TAME_PET_TYPE = 146,
+ SPELL_AURA_MECHANIC_IMMUNITY_MASK = 147,
SPELL_AURA_RETAIN_COMBO_POINTS = 148,
- SPELL_AURA_RESIST_PUSHBACK = 149, // Resist Pushback
+ SPELL_AURA_REDUCE_PUSHBACK = 149, // Reduce Pushback
SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT = 150,
SPELL_AURA_TRACK_STEALTHED = 151, // Track Stealthed
SPELL_AURA_MOD_DETECTED_RANGE = 152, // Mod Detected Range
@@ -233,8 +238,8 @@ enum AuraType
SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED = 191,
SPELL_AURA_HASTE_MELEE = 192,
SPELL_AURA_MELEE_SLOW = 193,
- SPELL_AURA_MOD_DEPRICATED_1 = 194, // not used now, old SPELL_AURA_MOD_SPELL_DAMAGE_OF_INTELLECT
- SPELL_AURA_MOD_DEPRICATED_2 = 195, // not used now, old SPELL_AURA_MOD_SPELL_HEALING_OF_INTELLECT
+ SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL = 194,
+ SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL = 195,
SPELL_AURA_MOD_COOLDOWN = 196, // only 24818 Noxious Breath
SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE = 197,
SPELL_AURA_MOD_ALL_WEAPON_SKILLS = 198,
@@ -266,16 +271,16 @@ enum AuraType
SPELL_AURA_224 = 224,
SPELL_AURA_PRAYER_OF_MENDING = 225,
SPELL_AURA_PERIODIC_DUMMY = 226,
- SPELL_AURA_227 = 227,
+ 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_231 = 231,
+ SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE = 231,
SPELL_AURA_MECHANIC_DURATION_MOD = 232,
SPELL_AURA_233 = 233,
SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK = 234,
SPELL_AURA_MOD_DISPEL_RESIST = 235,
- SPELL_AURA_236 = 236,
+ SPELL_AURA_CONTROL_VEHICLE = 236,
SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER = 237,
SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER = 238,
SPELL_AURA_MOD_SCALE_2 = 239,
@@ -284,29 +289,52 @@ enum AuraType
SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING = 242,
SPELL_AURA_243 = 243,
SPELL_AURA_COMPREHEND_LANGUAGE = 244,
- SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS = 245,
- SPELL_AURA_246 = 246,
+ SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL = 245,
+ SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK = 246,
SPELL_AURA_247 = 247,
SPELL_AURA_MOD_COMBAT_RESULT_CHANCE = 248,
- SPELL_AURA_249 = 249,
+ SPELL_AURA_CONVERT_RUNE = 249,
SPELL_AURA_MOD_INCREASE_HEALTH_2 = 250,
SPELL_AURA_MOD_ENEMY_DODGE = 251,
SPELL_AURA_252 = 252,
- SPELL_AURA_253 = 253,
- SPELL_AURA_254 = 254,
- SPELL_AURA_255 = 255,
- SPELL_AURA_256 = 256,
- SPELL_AURA_257 = 257,
+ SPELL_AURA_MOD_BLOCK_CRIT_CHANCE = 253,
+ SPELL_AURA_MOD_DISARM_OFFHAND = 254,
+ SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT = 255,
+ SPELL_AURA_NO_REAGENT_USE = 256,
+ SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS = 257,
SPELL_AURA_258 = 258,
- SPELL_AURA_259 = 259,
- SPELL_AURA_260 = 260,
- SPELL_AURA_261 = 261,
- TOTAL_AURAS=262
+ SPELL_AURA_MOD_HOT_PCT = 259,
+ SPELL_AURA_SCREEN_EFFECT = 260,
+ SPELL_AURA_PHASE = 261,
+ SPELL_AURA_ABILITY_IGNORE_AURASTATE = 262,
+ SPELL_AURA_ALLOW_ONLY_ABILITY = 263,
+ SPELL_AURA_264 = 264,
+ 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_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_MOD_DAMAGE_FROM_CASTER = 271,
+ SPELL_AURA_272 = 272,
+ SPELL_AURA_273 = 273,
+ SPELL_AURA_ABILITY_CONSUME_NO_AMMO = 274,
+ SPELL_AURA_MOD_IGNORE_SHAPESHIFT = 275,
+ SPELL_AURA_276 = 276, // Only "Test Mod Damage % Mechanic" spell, possible mod damage done
+ SPELL_AURA_MOD_ABILITY_AFFECTED_TARGETS = 277,
+ SPELL_AURA_MOD_DISARM_RANGED = 278,
+ SPELL_AURA_279 = 279,
+ SPELL_AURA_MOD_WEAPONTYPE_IGNORE_TARGET_RESISTANCE = 280,
+ 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
+ TOTAL_AURAS = 284
};
enum AreaAuraType
{
AREA_AURA_PARTY,
+ AREA_AURA_RAID,
AREA_AURA_FRIEND,
AREA_AURA_ENEMY,
AREA_AURA_PET,
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index c77e84b85f5..0896ba99a59 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -100,11 +100,11 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleNoImmediateEffect, // 43 SPELL_AURA_PROC_TRIGGER_DAMAGE implemented in Unit::ProcDamageAndSpellFor
&Aura::HandleAuraTrackCreatures, // 44 SPELL_AURA_TRACK_CREATURES
&Aura::HandleAuraTrackResources, // 45 SPELL_AURA_TRACK_RESOURCES
- &Aura::HandleUnused, // 46 SPELL_AURA_MOD_PARRY_SKILL obsolete?
+ &Aura::HandleUnused, // 46 SPELL_AURA_46
&Aura::HandleAuraModParryPercent, // 47 SPELL_AURA_MOD_PARRY_PERCENT
- &Aura::HandleUnused, // 48 SPELL_AURA_MOD_DODGE_SKILL obsolete?
+ &Aura::HandleUnused, // 48 SPELL_AURA_48
&Aura::HandleAuraModDodgePercent, // 49 SPELL_AURA_MOD_DODGE_PERCENT
- &Aura::HandleUnused, // 50 SPELL_AURA_MOD_BLOCK_SKILL obsolete?
+ &Aura::HandleNoImmediateEffect, // 50 SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT implemented in Unit::SpellCriticalHealingBonus
&Aura::HandleAuraModBlockPercent, // 51 SPELL_AURA_MOD_BLOCK_PERCENT
&Aura::HandleAuraModCritPercent, // 52 SPELL_AURA_MOD_CRIT_PERCENT
&Aura::HandlePeriodicLeech, // 53 SPELL_AURA_PERIODIC_LEECH
@@ -116,10 +116,10 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleNoImmediateEffect, // 59 SPELL_AURA_MOD_DAMAGE_DONE_CREATURE implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
&Aura::HandleAuraModPacifyAndSilence, // 60 SPELL_AURA_MOD_PACIFY_SILENCE
&Aura::HandleAuraModScale, // 61 SPELL_AURA_MOD_SCALE
- &Aura::HandleNULL, // 62 SPELL_AURA_PERIODIC_HEALTH_FUNNEL
+ &Aura::HandlePeriodicHealthFunnel, // 62 SPELL_AURA_PERIODIC_HEALTH_FUNNEL
&Aura::HandleUnused, // 63 SPELL_AURA_PERIODIC_MANA_FUNNEL obsolete?
&Aura::HandlePeriodicManaLeech, // 64 SPELL_AURA_PERIODIC_MANA_LEECH
- &Aura::HandleModCastingSpeed, // 65 SPELL_AURA_MOD_CASTING_SPEED
+ &Aura::HandleModCastingSpeed, // 65 SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK
&Aura::HandleFeignDeath, // 66 SPELL_AURA_FEIGN_DEATH
&Aura::HandleAuraModDisarm, // 67 SPELL_AURA_MOD_DISARM
&Aura::HandleAuraModStalked, // 68 SPELL_AURA_MOD_STALKED
@@ -163,7 +163,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleAuraHover, //106 SPELL_AURA_HOVER
&Aura::HandleAddModifier, //107 SPELL_AURA_ADD_FLAT_MODIFIER
&Aura::HandleAddModifier, //108 SPELL_AURA_ADD_PCT_MODIFIER
- &Aura::HandleNoImmediateEffect, //109 SPELL_AURA_ADD_TARGET_TRIGGER
+ &Aura::HandleAddTargetTrigger, //109 SPELL_AURA_ADD_TARGET_TRIGGER
&Aura::HandleModPowerRegenPCT, //110 SPELL_AURA_MOD_POWER_REGEN_PERCENT
&Aura::HandleNULL, //111 SPELL_AURA_ADD_CASTER_HIT_TRIGGER
&Aura::HandleNoImmediateEffect, //112 SPELL_AURA_OVERRIDE_CLASS_SCRIPTS
@@ -199,11 +199,11 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleAuraModBaseResistancePCT, //142 SPELL_AURA_MOD_BASE_RESISTANCE_PCT
&Aura::HandleAuraModResistanceExclusive, //143 SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE
&Aura::HandleNoImmediateEffect, //144 SPELL_AURA_SAFE_FALL implemented in WorldSession::HandleMovementOpcodes
- &Aura::HandleUnused, //145 SPELL_AURA_CHARISMA obsolete?
- &Aura::HandleUnused, //146 SPELL_AURA_PERSUADED obsolete?
- &Aura::HandleNULL, //147 SPELL_AURA_ADD_CREATURE_IMMUNITY
+ &Aura::HandleAuraModPetTalentsPoints, //145 SPELL_AURA_MOD_PET_TALENT_POINTS
+ &Aura::HandleNoImmediateEffect, //146 SPELL_AURA_ALLOW_TAME_PET_TYPE
+ &Aura::HandleModMechanicImmunity, //147 SPELL_AURA_MECHANIC_IMMUNITY_MASK
&Aura::HandleAuraRetainComboPoints, //148 SPELL_AURA_RETAIN_COMBO_POINTS
- &Aura::HandleNoImmediateEffect, //149 SPELL_AURA_RESIST_PUSHBACK
+ &Aura::HandleNoImmediateEffect, //149 SPELL_AURA_REDUCE_PUSHBACK
&Aura::HandleShieldBlockValue, //150 SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT
&Aura::HandleAuraTrackStealthed, //151 SPELL_AURA_TRACK_STEALTHED
&Aura::HandleNoImmediateEffect, //152 SPELL_AURA_MOD_DETECTED_RANGE implemented in Creature::GetAttackDistance
@@ -228,7 +228,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleAuraModIncreaseSpeed, //171 SPELL_AURA_MOD_SPEED_NOT_STACK
&Aura::HandleAuraModIncreaseMountedSpeed, //172 SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK
&Aura::HandleUnused, //173 SPELL_AURA_ALLOW_CHAMPION_SPELLS only for Proclaim Champion spell
- &Aura::HandleModSpellDamagePercentFromStat, //174 SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT implemented in Unit::SpellBaseDamageBonus (by default intellect, dependent from SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT)
+ &Aura::HandleModSpellDamagePercentFromStat, //174 SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT implemented in Unit::SpellBaseDamageBonus
&Aura::HandleModSpellHealingPercentFromStat, //175 SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT implemented in Unit::SpellBaseHealingBonus
&Aura::HandleSpiritOfRedemption, //176 SPELL_AURA_SPIRIT_OF_REDEMPTION only for Spirit of Redemption spell, die at aura end
&Aura::HandleNULL, //177 SPELL_AURA_AOE_CHARM
@@ -248,8 +248,8 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleAuraModUseNormalSpeed, //191 SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED
&Aura::HandleModMeleeRangedSpeedPct, //192 SPELL_AURA_HASTE_MELEE
&Aura::HandleModCombatSpeedPct, //193 SPELL_AURA_MELEE_SLOW (in fact combat (any type attack) speed pct)
- &Aura::HandleUnused, //194 SPELL_AURA_MOD_DEPRICATED_1 not used now (old SPELL_AURA_MOD_SPELL_DAMAGE_OF_INTELLECT)
- &Aura::HandleUnused, //195 SPELL_AURA_MOD_DEPRICATED_2 not used now (old SPELL_AURA_MOD_SPELL_HEALING_OF_INTELLECT)
+ &Aura::HandleNoImmediateEffect, //194 SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL implemented in Unit::CalcAbsorbResist
+ &Aura::HandleNoImmediateEffect, //195 SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL implemented in Unit::CalcAbsorbResist
&Aura::HandleNULL, //196 SPELL_AURA_MOD_COOLDOWN
&Aura::HandleNoImmediateEffect, //197 SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE implemented in Unit::SpellCriticalBonus Unit::GetUnitCriticalChance
&Aura::HandleUnused, //198 SPELL_AURA_MOD_ALL_WEAPON_SKILLS
@@ -274,23 +274,23 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleUnused, //217 unused
&Aura::HandleAuraModRangedHaste, //218 SPELL_AURA_HASTE_RANGED
&Aura::HandleModManaRegen, //219 SPELL_AURA_MOD_MANA_REGEN_FROM_STAT
- &Aura::HandleNULL, //220 SPELL_AURA_MOD_RATING_FROM_STAT
+ &Aura::HandleModRatingFromStat, //220 SPELL_AURA_MOD_RATING_FROM_STAT
&Aura::HandleNULL, //221 ignored
- &Aura::HandleUnused, //222 unused
+ &Aura::HandleNULL, //222 unused
&Aura::HandleNULL, //223 Cold Stare
&Aura::HandleUnused, //224 unused
&Aura::HandleNoImmediateEffect, //225 SPELL_AURA_PRAYER_OF_MENDING
&Aura::HandleAuraPeriodicDummy, //226 SPELL_AURA_PERIODIC_DUMMY
- &Aura::HandleNULL, //227 periodic trigger spell
+ &Aura::HandlePeriodicTriggerSpellWithValue, //227 SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE
&Aura::HandleNoImmediateEffect, //228 stealth detection
&Aura::HandleNULL, //229 SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE
- &Aura::HandleAuraModIncreaseMaxHealth, //230 Commanding Shout
- &Aura::HandleNULL, //231
+ &Aura::HandleAuraModIncreaseHealth, //230 SPELL_AURA_MOD_INCREASE_HEALTH_2
+ &Aura::HandleNoImmediateEffect, //231 SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE
&Aura::HandleNoImmediateEffect, //232 SPELL_AURA_MECHANIC_DURATION_MOD implement in Unit::CalculateSpellDuration
&Aura::HandleNULL, //233 set model id to the one of the creature with id m_modifier.m_miscvalue
&Aura::HandleNoImmediateEffect, //234 SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK implement in Unit::CalculateSpellDuration
&Aura::HandleAuraModDispelResist, //235 SPELL_AURA_MOD_DISPEL_RESIST implement in Unit::MagicSpellHitResult
- &Aura::HandleUnused, //236 unused
+ &Aura::HandleAuraControlVehicle, //236 SPELL_AURA_CONTROL_VEHICLE
&Aura::HandleModSpellDamagePercentFromAttackPower, //237 SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER implemented in Unit::SpellBaseDamageBonus
&Aura::HandleModSpellHealingPercentFromAttackPower, //238 SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER implemented in Unit::SpellBaseHealingBonus
&Aura::HandleAuraModScale, //239 SPELL_AURA_MOD_SCALE_2 only in Noggenfogger Elixir (16595) before 2.3.0 aura 61
@@ -299,31 +299,53 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleUnused, //242 SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING
&Aura::HandleUnused, //243 used by two test spells
&Aura::HandleComprehendLanguage, //244 Comprehend language
- &Aura::HandleUnused, //245 SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS
- &Aura::HandleUnused, //246 unused
+ &Aura::HandleNoImmediateEffect, //245 SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL
+ &Aura::HandleNoImmediateEffect, //246 SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK implemented in Spell::EffectApplyAura
&Aura::HandleUnused, //247 unused
&Aura::HandleNoImmediateEffect, //248 SPELL_AURA_MOD_COMBAT_RESULT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
- &Aura::HandleNULL, //249
+ &Aura::HandleAuraConvertRune, //249 SPELL_AURA_CONVERT_RUNE
&Aura::HandleAuraModIncreaseHealth, //250 SPELL_AURA_MOD_INCREASE_HEALTH_2
- &Aura::HandleNULL, //251 SPELL_AURA_MOD_ENEMY_DODGE
- &Aura::HandleUnused, //252 unused
- &Aura::HandleUnused, //253 unused
- &Aura::HandleUnused, //254 unused
- &Aura::HandleUnused, //255 unused
- &Aura::HandleUnused, //256 unused
- &Aura::HandleUnused, //257 unused
- &Aura::HandleUnused, //258 unused
- &Aura::HandleUnused, //259 unused
- &Aura::HandleUnused, //260 unused
- &Aura::HandleNULL //261 SPELL_AURA_261 some phased state (44856 spell)
+ &Aura::HandleNoImmediateEffect, //251 SPELL_AURA_MOD_ENEMY_DODGE
+ &Aura::HandleNULL, //252 haste all?
+ &Aura::HandleNoImmediateEffect, //253 SPELL_AURA_MOD_BLOCK_CRIT_CHANCE implemented in Unit::isBlockCritical
+ &Aura::HandleAuraModDisarm, //254 SPELL_AURA_MOD_DISARM_OFFHAND
+ &Aura::HandleNoImmediateEffect, //255 SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT implemented in Unit::SpellDamageBonus
+ &Aura::HandleNoReagentUseAura, //256 SPELL_AURA_NO_REAGENT_USE Use SpellClassMask for spell select
+ &Aura::HandleNULL, //257 SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS Use SpellClassMask for spell select
+ &Aura::HandleNULL, //258 SPELL_AURA_MOD_SPELL_VISUAL
+ &Aura::HandleNoImmediateEffect, //259 SPELL_AURA_MOD_HOT_PCT implemented in Unit::SpellHealingBonus
+ &Aura::HandleNoImmediateEffect, //260 SPELL_AURA_SCREEN_EFFECT (miscvalue = id in ScreenEffect.dbc) not required any code
+ &Aura::HandlePhase, //261 SPELL_AURA_PHASE undetactable invisibility? implemented in Unit::isVisibleForOrDetect
+ &Aura::HandleNoImmediateEffect, //262 SPELL_AURA_ABILITY_IGNORE_AURASTATE implemented in spell::cancast
+ &Aura::HandleAuraAllowOnlyAbility, //263 SPELL_AURA_ALLOW_ONLY_ABILITY player can use only abilities set in SpellClassMask
+ &Aura::HandleNULL, //264 unused
+ &Aura::HandleNULL, //265 unused
+ &Aura::HandleNULL, //266 unused
+ &Aura::HandleNoImmediateEffect, //267 SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL implemented in Unit::IsImmunedToSpellEffect
+ &Aura::HandleAuraModAttackPowerOfStatPercent, //268 SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT
+ &Aura::HandleNoImmediateEffect, //269 SPELL_AURA_MOD_IGNORE_TARGET_RESIST implemented in Unit::CalcAbsorbResist and CalcArmorReducedDamage
+ &Aura::HandleNoImmediateEffect, //270 SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST implemented in Unit::CalcAbsorbResist and CalcArmorReducedDamage
+ &Aura::HandleNoImmediateEffect, //271 SPELL_AURA_MOD_DAMAGE_FROM_CASTER implemented in Unit::SpellDamageBonus
+ &Aura::HandleNULL, //272 reduce spell cast time?
+ &Aura::HandleUnused, //273 clientside
+ &Aura::HandleNoImmediateEffect, //274 SPELL_AURA_CONSUME_NO_AMMO implemented in spell::CalculateDamageDoneForAllTargets
+ &Aura::HandleNoImmediateEffect, //275 SPELL_AURA_MOD_IGNORE_SHAPESHIFT Use SpellClassMask for spell select
+ &Aura::HandleNULL, //276 mod damage % mechanic?
+ &Aura::HandleNoImmediateEffect, //277 SPELL_AURA_MOD_ABILITY_AFFECTED_TARGETS implemented in spell::settargetmap
+ &Aura::HandleAuraModDisarm, //278 SPELL_AURA_MOD_DISARM_RANGED disarm ranged weapon
+ &Aura::HandleNULL, //279
+ &Aura::HandleNoImmediateEffect, //280 SPELL_AURA_MOD_WEAPONTYPE_IGNORE_TARGET_RESISTANCE
+ &Aura::HandleNoImmediateEffect, //281 SPELL_AURA_MOD_HONOR_GAIN_PCT implemented in Player::RewardHonor
+ &Aura::HandleAuraIncreaseBaseHealthPercent, //282 SPELL_AURA_INCREASE_BASE_HEALTH_PERCENT
+ &Aura::HandleNoImmediateEffect //283 SPELL_AURA_MOD_HEALING_RECEIVED implemented in Unit::SpellHealingBonus
};
Aura::Aura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem) :
-m_procCharges(0), m_stackAmount(1), m_spellmod(NULL), m_effIndex(eff), m_caster_guid(0), m_target(target),
-m_timeCla(1000), m_castItemGuid(castItem?castItem->GetGUID():0), m_auraSlot(MAX_AURAS),
-m_positive(false), m_permanent(false), m_isPeriodic(false), m_isTrigger(false), m_isAreaAura(false),
-m_isPersistent(false), m_updated(false), m_removeMode(AURA_REMOVE_BY_DEFAULT), m_isRemovedOnShapeLost(true), m_in_use(false),
-m_periodicTimer(0), m_PeriodicEventId(0), m_AuraDRGroup(DIMINISHING_NONE)
+m_spellmod(NULL), m_caster_guid(0), m_castItemGuid(castItem?castItem->GetGUID():0), m_target(target),
+m_timeCla(1000), m_periodicTimer(0), m_removeMode(AURA_REMOVE_BY_DEFAULT), m_AuraDRGroup(DIMINISHING_NONE),
+m_effIndex(eff), m_auraSlot(MAX_AURAS), m_auraFlags(AFLAG_NONE), m_auraLevel(1), m_procCharges(0), m_stackAmount(1),
+m_positive(false), m_permanent(false), m_isPeriodic(false), m_isAreaAura(false), m_isPersistent(false),
+m_updated(false), m_isRemovedOnShapeLost(true), m_in_use(false)
{
assert(target);
@@ -355,14 +377,14 @@ m_periodicTimer(0), m_PeriodicEventId(0), m_AuraDRGroup(DIMINISHING_NONE)
{
m_caster_guid = target->GetGUID();
//damage = m_currentBasePoints+1; // stored value-1
- m_maxduration = target->CalculateSpellDuration(m_spellProto, m_effIndex, target);
+ m_maxduration = target->CalcSpellDuration(m_spellProto);
}
else
{
m_caster_guid = caster->GetGUID();
//damage = caster->CalculateSpellDamage(m_spellProto,m_effIndex,m_currentBasePoints,target);
- m_maxduration = caster->CalculateSpellDuration(m_spellProto, m_effIndex, target);
+ m_maxduration = caster->CalcSpellDuration(m_spellProto);
if (!damage && castItem && castItem->GetItemSuffixFactor())
{
@@ -399,32 +421,39 @@ m_periodicTimer(0), m_PeriodicEventId(0), m_AuraDRGroup(DIMINISHING_NONE)
m_duration = m_maxduration;
- if(modOwner)
- modOwner->ApplySpellMod(GetId(), SPELLMOD_ACTIVATION_TIME, m_periodicTimer);
-
sLog.outDebug("Aura: construct Spellid : %u, Aura : %u Duration : %d Target : %d Damage : %d", m_spellProto->Id, m_spellProto->EffectApplyAuraName[eff], m_maxduration, m_spellProto->EffectImplicitTargetA[eff],damage);
m_effIndex = eff;
SetModifier(AuraType(m_spellProto->EffectApplyAuraName[eff]), damage, m_spellProto->EffectAmplitude[eff], m_spellProto->EffectMiscValue[eff]);
- m_isDeathPersist = IsDeathPersistentSpell(m_spellProto);
+ // Apply periodic time mod
+ if(modOwner && m_modifier.periodictime)
+ modOwner->ApplySpellMod(GetId(), SPELLMOD_ACTIVATION_TIME, m_modifier.periodictime);
- if(m_spellProto->procCharges)
- {
- m_procCharges = m_spellProto->procCharges;
+ // Start periodic on next tick or at aura apply
+ if (!(m_spellProto->AttributesEx5 & SPELL_ATTR_EX5_START_PERIODIC_AT_APPLY))
+ m_periodicTimer += m_modifier.periodictime;
- if(modOwner)
- modOwner->ApplySpellMod(GetId(), SPELLMOD_CHARGES, m_procCharges);
- }
- else
- m_procCharges = -1;
+ m_isDeathPersist = IsDeathPersistentSpell(m_spellProto);
+
+ m_procCharges = m_spellProto->procCharges;
+ if(modOwner)
+ modOwner->ApplySpellMod(GetId(), SPELLMOD_CHARGES, m_procCharges);
- m_isRemovedOnShapeLost = (m_caster_guid==m_target->GetGUID() && m_spellProto->Stances &&
- !(m_spellProto->AttributesEx2 & 0x80000) && !(m_spellProto->Attributes & 0x10000));
+ m_isRemovedOnShapeLost = (m_caster_guid==m_target->GetGUID() &&
+ m_spellProto->Stances &&
+ !(m_spellProto->AttributesEx2 & SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT) &&
+ !(m_spellProto->Attributes & SPELL_ATTR_NOT_SHAPESHIFT));
}
Aura::~Aura()
{
+ //Delete references to aura
+ if(GetAuraSlot() < MAX_AURAS && m_target && m_target->GetVisibleAura(GetAuraSlot()))
+ {
+ AuraSlotEntry * entry = m_target->GetVisibleAura(GetAuraSlot());
+ entry->m_slotAuras[GetEffIndex()]=NULL;
+ }
}
AreaAura::AreaAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target,
@@ -446,6 +475,11 @@ Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target,
if(target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isTotem())
m_modifier.m_auraname = SPELL_AURA_NONE;
break;
+ case SPELL_EFFECT_APPLY_AREA_AURA_RAID:
+ m_areaAuraType = AREA_AURA_RAID;
+ if(target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isTotem())
+ m_modifier.m_auraname = SPELL_AURA_NONE;
+ break;
case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:
m_areaAuraType = AREA_AURA_FRIEND;
break;
@@ -576,28 +610,13 @@ void Aura::Update(uint32 diff)
if(m_isPeriodic && (m_duration >= 0 || m_isPassive || m_permanent))
{
m_periodicTimer -= diff;
- if(m_periodicTimer <= 0) // tick also at m_periodicTimer==0 to prevent lost last tick in case max m_duration == (max m_periodicTimer)*N
+ if(m_periodicTimer <= 0) // tick also at m_periodicTimer==0 to prevent lost last tick in case max m_duration == (max m_periodicTimer)*N
{
- if( m_modifier.m_auraname == SPELL_AURA_MOD_REGEN ||
- m_modifier.m_auraname == SPELL_AURA_MOD_POWER_REGEN ||
- // Cannibalize, eating items and other spells
- m_modifier.m_auraname == SPELL_AURA_OBS_MOD_HEALTH ||
- // Eating items and other spells
- m_modifier.m_auraname == SPELL_AURA_OBS_MOD_MANA )
- {
- ApplyModifier(true);
- return;
- }
// update before applying (aura can be removed in TriggerSpell or PeriodicTick calls)
m_periodicTimer += m_modifier.periodictime;
if(!m_target->hasUnitState(UNIT_STAT_ISOLATED))
- {
- if(m_isTrigger)
- TriggerSpell();
- else
- PeriodicTick();
- }
+ PeriodicTick();
}
}
}
@@ -618,17 +637,20 @@ void AreaAura::Update(uint32 diff)
case AREA_AURA_PARTY:
caster->GetPartyMember(targets, m_radius);
break;
+ case AREA_AURA_RAID:
+ caster->GetRaidMember(targets, m_radius);
+ break;
case AREA_AURA_FRIEND:
{
Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(caster, caster, m_radius);
- Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(targets, u_check);
+ Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(caster, targets, u_check);
caster->VisitNearbyObject(m_radius, searcher);
break;
}
case AREA_AURA_ENEMY:
{
Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(caster, caster, m_radius); // No GetCharmer in searcher
- Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(targets, u_check);
+ Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(caster, targets, u_check);
caster->VisitNearbyObject(m_radius, searcher);
break;
}
@@ -657,6 +679,7 @@ void AreaAura::Update(uint32 diff)
aur = new AreaAura(actualSpellInfo, m_effIndex, &m_modifier.m_amount, (*tIter), caster, NULL);
else
aur = new AreaAura(actualSpellInfo, m_effIndex, NULL, (*tIter), caster, NULL);
+ aur->SetAuraDuration(GetAuraDuration());
(*tIter)->AddAura(aur);
}
}
@@ -690,6 +713,11 @@ void AreaAura::Update(uint32 diff)
if(!tmp_target->IsInPartyWith(caster))
tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);
}
+ else if( m_areaAuraType == AREA_AURA_RAID) // TODO: fix me!
+ {
+ if(!tmp_target->IsInRaidWith(caster))
+ tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);
+ }
else if( m_areaAuraType == AREA_AURA_PET || m_areaAuraType == AREA_AURA_OWNER )
{
if( tmp_target->GetGUID() != caster->GetCharmerOrOwnerGUID() )
@@ -740,58 +768,27 @@ void Aura::ApplyModifier(bool apply, bool Real)
m_in_use = false;
}
-void Aura::UpdateAuraDuration()
+void Aura::_AddAura()
{
- if(m_auraSlot >= MAX_AURAS || m_isPassive)
+ if (!GetId())
return;
-
- if( m_target->GetTypeId() == TYPEID_PLAYER)
- {
- WorldPacket data(SMSG_UPDATE_AURA_DURATION, 5);
- data << (uint8)m_auraSlot << (uint32)m_duration;
- ((Player*)m_target)->SendDirectMessage(&data);
-
- data.Initialize(SMSG_SET_EXTRA_AURA_INFO, (8+1+4+4+4));
- data.append(m_target->GetPackGUID());
- data << uint8(m_auraSlot);
- data << uint32(GetId());
- data << uint32(GetAuraMaxDuration());
- data << uint32(GetAuraDuration());
- ((Player*)m_target)->SendDirectMessage(&data);
- }
-
- // not send in case player loading (will not work anyway until player not added to map), sent in visibility change code
- if(m_target->GetTypeId() == TYPEID_PLAYER && ((Player*)m_target)->GetSession()->PlayerLoading())
+ if(!m_target)
return;
Unit* caster = GetCaster();
- if(caster && caster->GetTypeId() == TYPEID_PLAYER && caster != m_target)
- SendAuraDurationForCaster((Player*)caster);
-}
-
-void Aura::SendAuraDurationForCaster(Player* caster)
-{
- WorldPacket data(SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE, (8+1+4+4+4));
- data.append(m_target->GetPackGUID());
- data << uint8(m_auraSlot);
- data << uint32(GetId());
- data << uint32(GetAuraMaxDuration()); // full
- data << uint32(GetAuraDuration()); // remain
- caster->GetSession()->SendPacket(&data);
-}
-
-void Aura::_AddAura()
-{
- if (!GetId())
- return;
- if(!m_target)
+ // passive auras (except totem auras) do not get placed in the slots
+ // area auras with SPELL_AURA_NONE are not shown on target
+ // all further code applies only to active spells
+ if(!((m_spellProto->Attributes & 0x80 || !m_isPassive || (caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem())) &&
+ (m_spellProto->Effect[GetEffIndex()] != SPELL_EFFECT_APPLY_AREA_AURA_ENEMY || m_target != caster)))
return;
- // we can found aura in NULL_AURA_SLOT and then need store state instead check slot != NULL_AURA_SLOT
+ // Second aura if some spell
bool secondaura = false;
+ // Try find slot for aura
uint8 slot = NULL_AURA_SLOT;
-
+ // Lookup for auras already applied from spell
for(uint8 i = 0; i < 3; i++)
{
Unit::spellEffectPair spair = Unit::spellEffectPair(GetId(), i);
@@ -800,109 +797,97 @@ void Aura::_AddAura()
// allow use single slot only by auras from same caster
if(itr->second->GetCasterGUID()==GetCasterGUID())
{
- secondaura = true;
slot = itr->second->GetAuraSlot();
+ secondaura = true;
break;
}
}
-
- if(secondaura)
+ if (secondaura)
break;
}
+ // Lookup free slot
+ if (!secondaura && m_target->GetVisibleAurasCount() < MAX_AURAS )
+ {
+ Unit::VisibleAuraMap const *visibleAuras = m_target->GetVisibleAuras();
+ for(uint8 i = 0; i < MAX_AURAS; ++i)
+ {
+ Unit::VisibleAuraMap::const_iterator itr = visibleAuras->find(i);
+ if(itr == visibleAuras->end())
+ {
+ slot = i;
+ break;
+ }
+ }
+ }
- Unit* caster = GetCaster();
-
- // not call total regen auras at adding
- switch (m_modifier.m_auraname)
+ if (!secondaura)
{
- /*case SPELL_AURA_PERIODIC_DAMAGE:
- case SPELL_AURA_PERIODIC_LEECH:
- if(caster)
- m_modifier.m_amount = caster->SpellDamageBonus(m_target, m_spellProto, m_modifier.m_amount, DOT);
- break;
- case SPELL_AURA_PERIODIC_HEAL:
- if(caster)
- m_modifier.m_amount = caster->SpellHealingBonus(m_spellProto, m_modifier.m_amount, DOT, m_target);
- break;*/
- case SPELL_AURA_OBS_MOD_HEALTH:
- case SPELL_AURA_OBS_MOD_MANA:
- m_periodicTimer = m_modifier.periodictime;
- break;
- case SPELL_AURA_MOD_REGEN:
- case SPELL_AURA_MOD_POWER_REGEN:
- case SPELL_AURA_MOD_MANA_REGEN_FROM_STAT:
- m_periodicTimer = 5000;
- break;
+ AuraSlotEntry t_entry;
+ t_entry.m_Flags=(IsPositive() ? AFLAG_POSITIVE : AFLAG_NEGATIVE) | AFLAG_NOT_CASTER | ((GetAuraMaxDuration() > 0) ? AFLAG_DURATION : AFLAG_NONE);
+ t_entry.m_Level=(caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
+
+ //init pointers-prevent unexpected behaviour
+ for(uint8 i = 0; i < 3; i++)
+ t_entry.m_slotAuras[i]=NULL;
+
+ t_entry.m_Level=(caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
+ m_target->SetVisibleAura(slot, t_entry);
}
- // register aura
- if (getDiminishGroup() != DIMINISHING_NONE )
- m_target->ApplyDiminishingAura(getDiminishGroup(),true);
+ AuraSlotEntry * entry;
+ entry=m_target->GetVisibleAura(slot);
+ if(!entry)
+ return;
- // passive auras (except totem auras) do not get placed in the slots
- // area auras with SPELL_AURA_NONE are not shown on target
- if((!m_isPassive || (caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem())) &&
- (m_spellProto->Effect[GetEffIndex()] != SPELL_EFFECT_APPLY_AREA_AURA_ENEMY || m_target != caster))
- {
- if(!secondaura) // new slot need
- {
- if (IsPositive()) // empty positive slot
- {
- for (uint8 i = 0; i < MAX_POSITIVE_AURAS; i++)
- {
- if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + i)) == 0)
- {
- slot = i;
- break;
- }
- }
- }
- else // empty negative slot
- {
- for (uint8 i = MAX_POSITIVE_AURAS; i < MAX_AURAS; i++)
- {
- if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + i)) == 0)
- {
- slot = i;
- break;
- }
- }
- }
+ entry->m_Flags |= (1 << GetEffIndex());
+ entry->m_slotAuras[GetEffIndex()]=this;
- SetAuraSlot( slot );
+ SetAuraSlot( slot );
- // Not update fields for not first spell's aura, all data already in fields
- if(slot < MAX_AURAS) // slot found
- {
- SetAura(slot, false);
- SetAuraFlag(slot, true);
- SetAuraLevel(slot,caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
- UpdateAuraCharges();
+ // update for out of range group members (on 1 slot use)
+ m_target->UpdateAuraForGroup(slot);
- // update for out of range group members
- m_target->UpdateAuraForGroup(slot);
- }
- }
- else // use found slot
- {
- SetAuraSlot( slot );
- }
+ //*****************************************************
+ // Update target aura state flag (at 1 aura apply)
+ // TODO: Make it easer
+ //*****************************************************
+ if (!secondaura)
+ {
+ // Sitdown on apply aura req seated
+ if (m_spellProto->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED && !m_target->IsSitState())
+ m_target->SetStandState(UNIT_STAND_STATE_SIT);
- UpdateSlotCounterAndDuration();
+ // register aura diminishing on apply
+ if (getDiminishGroup() != DIMINISHING_NONE )
+ m_target->ApplyDiminishingAura(getDiminishGroup(),true);
// Update Seals information
- if( IsSealSpell(GetSpellProto()) )
+ if (IsSealSpell(m_spellProto))
m_target->ModifyAuraState(AURA_STATE_JUDGEMENT, true);
- // Conflagrate aura state
- if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 4))
+ // Conflagrate aura state on Immolate
+ if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellProto->SpellFamilyFlags[0] & 4)
m_target->ModifyAuraState(AURA_STATE_IMMOLATE, true);
- if(GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID
- && (GetSpellProto()->SpellFamilyFlags == 0x40 || GetSpellProto()->SpellFamilyFlags == 0x10))
- {
+ // Faerie Fire (druid versions)
+ if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags[0] & 0x400)
+ m_target->ModifyAuraState(AURA_STATE_FAERIE_FIRE, true);
+
+ // Victorious
+ if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARRIOR && m_spellProto->SpellFamilyFlags[1] & 0x00040000)
+ m_target->ModifyAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH, true);
+
+ // Swiftmend state on Regrowth & Rejuvenation
+ if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags[0] & 0x50 )
m_target->ModifyAuraState(AURA_STATE_SWIFTMEND, true);
- }
+
+ // Deadly poison aura state
+ if(m_spellProto->SpellFamilyName == SPELLFAMILY_ROGUE && m_spellProto->SpellFamilyFlags[0] & 0x10000)
+ m_target->ModifyAuraState(AURA_STATE_DEADLY_POISON, true);
+
+ // Enrage aura state
+ if(m_spellProto->Dispel == DISPEL_ENRAGE)
+ m_target->ModifyAuraState(AURA_STATE_ENRAGE, true);
}
}
@@ -922,10 +907,6 @@ void Aura::_RemoveAura()
dynObj->RemoveAffected(m_target);
}
- // unregister aura
- if (getDiminishGroup() != DIMINISHING_NONE )
- m_target->ApplyDiminishingAura(getDiminishGroup(),false);
-
//passive auras do not get put in slots
// Note: but totem can be not accessible for aura target in time remove (to far for find in grid)
//if(m_isPassive && !(caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem()))
@@ -936,63 +917,89 @@ void Aura::_RemoveAura()
if(slot >= MAX_AURAS) // slot not set
return;
- if(m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + slot)) == 0)
+ if(!m_target->GetVisibleAura(slot)) //slot already removed-shouldn't happen
return;
- bool samespell = false;
+ bool lastaura = true;
- // find other aura in same slot (current already removed from list)
- for(uint8 i = 0; i < 3; i++)
+ AuraSlotEntry * entry=m_target->GetVisibleAura(slot);
+
+ entry->m_slotAuras[GetEffIndex()]=NULL; //unregister aura
+ Aura * ptr= NULL;
+ for (uint8 i=0 ; i<3; i++) //check slot for more auras of the spell
{
- Unit::spellEffectPair spair = Unit::spellEffectPair(GetId(), i);
- for(Unit::AuraMap::const_iterator itr = m_target->GetAuras().lower_bound(spair); itr != m_target->GetAuras().upper_bound(spair); ++itr)
+ if (entry->m_slotAuras[i])
{
- if(itr->second->GetAuraSlot()==slot)
- {
- samespell = true;
-
- break;
- }
- }
- if(samespell)
+ ptr=entry->m_slotAuras[i];
break;
+ }
}
// only remove icon when the last aura of the spell is removed (current aura already removed from list)
- if (!samespell)
+ if(!ptr)
{
- SetAura(slot, true);
- SetAuraFlag(slot, false);
- SetAuraLevel(slot,caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
+ // unregister aura diminishing (and store last time)
+ if (getDiminishGroup() != DIMINISHING_NONE )
+ m_target->ApplyDiminishingAura(getDiminishGroup(),false);
- SetAuraApplication(slot, 0);
// update for out of range group members
m_target->UpdateAuraForGroup(slot);
- if( IsSealSpell(GetSpellProto()) )
- m_target->ModifyAuraState(AURA_STATE_JUDGEMENT,false);
+ //*****************************************************
+ // Update target aura state flag (at last aura remove)
+ //*****************************************************
+ // Enrage aura state
+ if(m_spellProto->Dispel == DISPEL_ENRAGE)
+ m_target->ModifyAuraState(AURA_STATE_ENRAGE, false);
- // Conflagrate aura state
- if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 4))
- m_target->ModifyAuraState(AURA_STATE_IMMOLATE, false);
+ uint32 removeState = 0;
+ switch(m_spellProto->SpellFamilyName)
+ {
+ case SPELLFAMILY_PALADIN:
+ if (IsSealSpell(m_spellProto))
+ removeState = AURA_STATE_JUDGEMENT; // Update Seals information
+ break;
+ case SPELLFAMILY_WARLOCK:
+ if(m_spellProto->SpellFamilyFlags[0] & 4)
+ removeState = AURA_STATE_IMMOLATE; // Conflagrate aura state
+ break;
+ case SPELLFAMILY_DRUID:
+ if(m_spellProto->SpellFamilyFlags[0] & 0x400)
+ removeState = AURA_STATE_FAERIE_FIRE; // Faerie Fire (druid versions)
+ else if(m_spellProto->SpellFamilyFlags[0] & 0x50)
+ removeState = AURA_STATE_SWIFTMEND; // Swiftmend aura state
+ break;
+ case SPELLFAMILY_WARRIOR:
+ if(m_spellProto->SpellFamilyFlags[1] & 0x00040000)
+ removeState = AURA_STATE_WARRIOR_VICTORY_RUSH; // Victorious
+ break;
+ case SPELLFAMILY_ROGUE:
+ if(m_spellProto->SpellFamilyFlags[0] & 0x10000)
+ removeState = AURA_STATE_DEADLY_POISON; // Deadly poison aura state
+ break;
+ case SPELLFAMILY_HUNTER:
+ if(m_spellProto->SpellFamilyFlags[1] & 0x10000000)
+ removeState = AURA_STATE_FAERIE_FIRE; // Sting (hunter versions)
- // Swiftmend aura state
- if(GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID
- && (GetSpellProto()->SpellFamilyFlags == 0x40 || GetSpellProto()->SpellFamilyFlags == 0x10))
+ }
+ // Remove state (but need check other auras for it)
+ if (removeState)
{
bool found = false;
- Unit::AuraList const& RejorRegr = m_target->GetAurasByType(SPELL_AURA_PERIODIC_HEAL);
- for(Unit::AuraList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)
+ Unit::AuraMap& Auras = m_target->GetAuras();
+ for(Unit::AuraMap::iterator i = Auras.begin(); i != Auras.end(); ++i)
{
- if((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID
- && ((*i)->GetSpellProto()->SpellFamilyFlags == 0x40 || (*i)->GetSpellProto()->SpellFamilyFlags == 0x10) )
+ SpellEntry const *auraSpellInfo = (*i).second->GetSpellProto();
+ if(auraSpellInfo->SpellFamilyName == m_spellProto->SpellFamilyName &&
+ auraSpellInfo->SpellFamilyFlags == m_spellProto->SpellFamilyFlags )
{
found = true;
break;
}
}
+ // this has been last aura
if(!found)
- m_target->ModifyAuraState(AURA_STATE_SWIFTMEND, false);
+ m_target->ModifyAuraState(AuraState(removeState), false);
}
// reset cooldown state for spells
@@ -1004,56 +1011,66 @@ void Aura::_RemoveAura()
}
}
-void Aura::SetAuraFlag(uint32 slot, bool add)
+void Aura::SetStackAmount(uint8 stackAmount)
{
- uint32 index = slot / 4;
- uint32 byte = (slot % 4) * 8;
- uint32 val = m_target->GetUInt32Value(UNIT_FIELD_AURAFLAGS + index);
- val &= ~((uint32)AFLAG_MASK << byte);
- if(add)
+ if (stackAmount != m_stackAmount)
{
- if (IsPositive())
- val |= ((uint32)AFLAG_POSITIVE << byte);
- else
- val |= ((uint32)AFLAG_NEGATIVE << byte);
+ Unit *target = GetTarget();
+ Unit *caster = GetCaster();
+ if (!target || !caster)
+ return;
+ m_stackAmount = stackAmount;
+ int32 amount = m_stackAmount * caster->CalculateSpellDamage(m_spellProto, m_effIndex, m_currentBasePoints, target);
+ // Reapply if amount change
+ if (amount!=m_modifier.m_amount)
+ {
+ ApplyModifier(false, true);
+ m_modifier.m_amount = amount;
+ ApplyModifier(true, true);
+ }
}
- m_target->SetUInt32Value(UNIT_FIELD_AURAFLAGS + index, val);
+ RefreshAura();
}
-void Aura::SetAuraLevel(uint32 slot,uint32 level)
+bool Aura::modStackAmount(int32 num)
{
- uint32 index = slot / 4;
- uint32 byte = (slot % 4) * 8;
- uint32 val = m_target->GetUInt32Value(UNIT_FIELD_AURALEVELS + index);
- val &= ~(0xFF << byte);
- val |= (level << byte);
- m_target->SetUInt32Value(UNIT_FIELD_AURALEVELS + index, val);
+ // Can`t mod
+ if (!m_spellProto->StackAmount)
+ return true;
+
+ // Modify stack but limit it
+ int32 stackAmount = m_stackAmount + num;
+ if (stackAmount > m_spellProto->StackAmount)
+ stackAmount = m_spellProto->StackAmount;
+ else if (stackAmount <=0) // Last aura from stack removed
+ {
+ m_stackAmount = 0;
+ return true; // need remove aura
+ }
+
+ // Update stack amount
+ SetStackAmount(stackAmount);
+ return false;
}
-void Aura::SetAuraApplication(uint32 slot, int8 count)
+void Aura::RefreshAura()
{
- uint32 index = slot / 4;
- uint32 byte = (slot % 4) * 8;
- uint32 val = m_target->GetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS + index);
- val &= ~(0xFF << byte);
- val |= ((uint8(count)) << byte);
- m_target->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS + index, val);
+ m_duration = m_maxduration;
+ // update for out of range group members (on 1 slot use)
+ m_target->UpdateAuraForGroup(GetAuraSlot());
}
-void Aura::UpdateSlotCounterAndDuration()
+bool Aura::isAffectedOnSpell(SpellEntry const *spell) const
{
- uint8 slot = GetAuraSlot();
- if(slot >= MAX_AURAS)
- return;
-
- // Three possibilities:
- // Charge = 0; Stack >= 0
- // Charge = 1; Stack >= 0
- // Charge > 1; Stack = 0
- if(m_procCharges < 2)
- SetAuraApplication(slot, m_stackAmount-1);
-
- UpdateAuraDuration();
+ if (!spell)
+ return false;
+ // Check family name
+ if (spell->SpellFamilyName != m_spellProto->SpellFamilyName)
+ return false;
+ // Check EffectClassMask
+ if (m_spellProto->EffectSpellClassMask[m_effIndex] & spell->SpellFamilyFlags)
+ return true;
+ return false;
}
/*********************************************************/
@@ -1064,10 +1081,6 @@ void Aura::HandleAddModifier(bool apply, bool Real)
if(m_target->GetTypeId() != TYPEID_PLAYER || !Real)
return;
- SpellEntry const *spellInfo = GetSpellProto();
- if(!spellInfo)
- return;
-
if(m_modifier.m_miscvalue >= MAX_SPELLMOD)
return;
@@ -1078,40 +1091,35 @@ void Aura::HandleAddModifier(bool apply, bool Real)
{
case 17941: // Shadow Trance
case 22008: // Netherwind Focus
+ case 31834: // Light's Grace
+ case 34754: // Clearcasting
case 34936: // Backlash
- m_procCharges = 1;
+ case 48108: // Hot Streak
+ case 54741: // Firestarter
+ case 57761: // Fireball!
+ SetAuraCharges(1);
break;
}
SpellModifier *mod = new SpellModifier;
mod->op = SpellModOp(m_modifier.m_miscvalue);
- mod->value = GetModifierValue();
+ mod->value = m_modifier.m_amount;
mod->type = SpellModType(m_modifier.m_auraname); // SpellModType value == spell aura types
mod->spellId = GetId();
- mod->effectId = m_effIndex;
- mod->lastAffected = NULL;
- uint64 spellAffectMask = spellmgr.GetSpellAffectMask(GetId(), m_effIndex);
-
- if (spellAffectMask)
- mod->mask = spellAffectMask;
- else
- mod->mask = spellInfo->EffectItemType[m_effIndex];
-
- if (m_procCharges > 0)
- mod->charges = m_procCharges;
- else
- mod->charges = 0;
+ flag96 const *spellAffect = spellmgr.GetSpellAffect(GetId(), m_effIndex);
+ if (!spellAffect)
+ spellAffect = &m_spellProto->EffectSpellClassMask[m_effIndex];
+ mod->mask = *spellAffect;
+ mod->charges = m_procCharges;
m_spellmod = mod;
}
- uint64 spellFamilyMask = m_spellmod->mask;
-
((Player*)m_target)->AddSpellMod(m_spellmod, apply);
// reapply some passive spells after add/remove related spellmods
- if(spellInfo->SpellFamilyName==SPELLFAMILY_WARRIOR && (spellFamilyMask & 0x0000100000000000LL))
+ if(m_spellProto->SpellFamilyName==SPELLFAMILY_WARRIOR && (m_spellmod->mask[1] & 0x00001000))
{
m_target->RemoveAurasDueToSpell(45471);
@@ -1119,6 +1127,29 @@ void Aura::HandleAddModifier(bool apply, bool Real)
m_target->CastSpell(m_target,45471,true);
}
}
+void Aura::HandleAddTargetTrigger(bool apply, bool Real)
+{
+ // Use SpellModifier structure for check
+ // used only fields:
+ // spellId, mask, mask2
+ if (apply)
+ {
+ SpellModifier *mod = new SpellModifier;
+ mod->spellId = GetId();
+
+ flag96 const *spellAffect = spellmgr.GetSpellAffect(GetId(), m_effIndex);
+ if (!spellAffect)
+ spellAffect = &m_spellProto->EffectSpellClassMask[m_effIndex];
+
+ mod->mask = *spellAffect;
+ m_spellmod = mod;
+ }
+ else
+ {
+ delete m_spellmod;
+ m_spellmod = NULL;
+ }
+}
void Aura::TriggerSpell()
{
@@ -1131,8 +1162,6 @@ void Aura::TriggerSpell()
// generic casting code with custom spells and target/caster customs
uint32 trigger_spell_id = GetSpellProto()->EffectTriggerSpell[m_effIndex];
- uint64 originalCasterGUID = GetCasterGUID();
-
SpellEntry const *triggeredSpellInfo = sSpellStore.LookupEntry(trigger_spell_id);
SpellEntry const *auraSpellInfo = GetSpellProto();
uint32 auraId = auraSpellInfo->Id;
@@ -1340,26 +1369,10 @@ void Aura::TriggerSpell()
Creature* creature = (Creature*)target;
// missing lootid has been reported on startup - just return
if (!creature->GetCreatureInfo()->SkinLootId)
- {
return;
- }
- Loot *loot = &creature->loot;
- loot->clear();
- loot->FillLoot(creature->GetCreatureInfo()->SkinLootId, LootTemplates_Skinning, NULL);
- for(uint8 i=0;i<loot->items.size();i++)
- {
- LootItem *item = loot->LootItemInSlot(i,player);
- ItemPosCountVec dest;
- uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, item->itemid, item->count );
- if ( msg == EQUIP_ERR_OK )
- {
- Item * newitem = player->StoreNewItem( dest, item->itemid, true, item->randomPropertyId);
-
- player->SendNewItem(newitem, uint32(item->count), false, false, true);
- }
- else
- player->SendEquipError( msg, NULL, NULL );
- }
+
+ player->AutoStoreLoot(creature->GetCreatureInfo()->SkinLootId,LootTemplates_Skinning,true);
+
creature->setDeathState(JUST_DIED);
creature->RemoveCorpse();
creature->SetHealth(0); // just for nice GM-mode view
@@ -1729,7 +1742,7 @@ void Aura::TriggerSpell()
{
SpellEntry const* spell = itr->second->GetSpellProto();
if( spell->SpellFamilyName == SPELLFAMILY_SHAMAN &&
- spell->SpellFamilyFlags & 0x0000000000000400L)
+ spell->SpellFamilyFlags[0] & 0x400)
return;
}
target->RemoveAurasDueToSpell(28820);
@@ -1799,8 +1812,8 @@ void Aura::TriggerSpell()
{
switch((*i)->GetModifier()->m_miscvalue)
{
- case STAT_INTELLECT: intellectLoss += (*i)->GetModifierValue(); break;
- case STAT_SPIRIT: spiritLoss += (*i)->GetModifierValue(); break;
+ case STAT_INTELLECT: intellectLoss += (*i)->GetModifier()->m_amount; break;
+ case STAT_SPIRIT: spiritLoss += (*i)->GetModifier()->m_amount; break;
default: break;
}
}
@@ -1810,20 +1823,19 @@ void Aura::TriggerSpell()
return;
caster = target;
- originalCasterGUID = 0;
break;
}
// Mana Tide
case 16191:
{
- caster->CastCustomSpell(target, trigger_spell_id, &m_modifier.m_amount, NULL, NULL, true, NULL, this, originalCasterGUID);
+ caster->CastCustomSpell(target, trigger_spell_id, &m_modifier.m_amount, NULL, NULL, true, NULL, this);
return;
}
}
}
if(!GetSpellMaxRange(sSpellRangeStore.LookupEntry(triggeredSpellInfo->rangeIndex)))
target = m_target; //for druid dispel poison
- m_target->CastSpell(target, triggeredSpellInfo, true, 0, this, originalCasterGUID);
+ m_target->CastSpell(target, triggeredSpellInfo, true, 0, this, GetCasterGUID());
}
Unit* Aura::GetTriggerTarget() const
@@ -1835,6 +1847,21 @@ Unit* Aura::GetTriggerTarget() const
return target ? target : m_target;
}
+void Aura::TriggerSpellWithValue()
+{
+ Unit* caster = GetCaster();
+ Unit* target = GetTriggerTarget();
+
+ if(!caster || !target)
+ return;
+
+ // generic casting code with custom spells and target/caster customs
+ uint32 trigger_spell_id = GetSpellProto()->EffectTriggerSpell[m_effIndex];
+ int32 basepoints0 = this->GetModifier()->m_amount;
+
+ caster->CastCustomSpell(target, trigger_spell_id, &basepoints0, 0, 0, true, 0, this);
+}
+
/*********************************************************/
/*** AURA EFFECTS ***/
/*********************************************************/
@@ -1868,7 +1895,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
return;
case 43873: // Headless Horseman Laugh
if(caster->GetTypeId() == TYPEID_PLAYER)
- ((Player*)caster)->SendPlaySound(11965, false);
+ ((Player*)caster)->PlaySound(11965, false);
return;
case 46354: // Blood Elf Illusion
if(caster)
@@ -1893,11 +1920,11 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
}
// Earth Shield
- if ( caster && GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && (GetSpellProto()->SpellFamilyFlags & 0x40000000000LL))
+ if ( caster && GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && (GetSpellProto()->SpellFamilyFlags[1] & 0x400))
{
// prevent double apply bonuses
if(m_target->GetTypeId()!=TYPEID_PLAYER || !((Player*)m_target)->GetSession()->PlayerLoading())
- m_modifier.m_amount = caster->SpellHealingBonus(GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE, m_target);
+ m_modifier.m_amount = caster->SpellHealingBonus(m_target, GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE);
return;
}
}
@@ -1964,6 +1991,25 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
m_target->SetReducedThreatPercent(0, 0);
return;
}
+
+ if (caster && m_removeMode == AURA_REMOVE_BY_DEATH)
+ {
+ // Stop caster Arcane Missle chanelling on death
+ if (m_spellProto->SpellFamilyName == SPELLFAMILY_MAGE &&
+ m_spellProto->SpellFamilyFlags[0] & 0x800)
+ {
+ caster->InterruptSpell(CURRENT_CHANNELED_SPELL);
+ return;
+ }
+ // Stop caster Penance chanelling on death
+ if (m_spellProto->SpellFamilyName == SPELLFAMILY_PRIEST &&
+ m_spellProto->SpellFamilyFlags[2] & 0x00000080)
+ {
+ caster->InterruptSpell(CURRENT_CHANNELED_SPELL);
+ return;
+ }
+
+ }
}
// AT APPLY & REMOVE
@@ -2004,12 +2050,6 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
m_target->RemoveAurasDueToSpell(spellId);
return;
}
- // Victorious
- if(GetId()==32216 && m_target->getClass()==CLASS_WARRIOR)
- {
- m_target->ModifyAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH, apply);
- return;
- }
//Summon Fire Elemental
if (GetId() == 40133 && caster)
{
@@ -2042,10 +2082,25 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
}
case SPELLFAMILY_MAGE:
{
- // Hypothermia
- if( GetId()==41425 )
+ break;
+ }
+ case SPELLFAMILY_PRIEST:
+ {
+ // Pain and Suffering
+ if( m_spellProto->SpellIconID == 2874 && m_target->GetTypeId()==TYPEID_PLAYER )
{
- m_target->ModifyAuraState(AURA_STATE_HYPOTHERMIA,apply);
+ if(apply)
+ {
+ // Reduce backfire damage (dot damage) from Shadow Word: Death
+ SpellModifier *mod = new SpellModifier;
+ mod->op = SPELLMOD_DOT;
+ mod->value = m_modifier.m_amount;
+ mod->type = SPELLMOD_PCT;
+ mod->spellId = GetId();
+ mod->mask[1] = 0x00000002;
+ m_spellmod = mod;
+ }
+ ((Player*)m_target)->AddSpellMod(m_spellmod, apply);
return;
}
break;
@@ -2053,24 +2108,38 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
case SPELLFAMILY_DRUID:
{
// Lifebloom
- if ( GetSpellProto()->SpellFamilyFlags & 0x1000000000LL )
+ if ( GetSpellProto()->SpellFamilyFlags[1] & 0x10 )
{
if ( apply )
{
if ( caster )
// prevent double apply bonuses
if(m_target->GetTypeId()!=TYPEID_PLAYER || !((Player*)m_target)->GetSession()->PlayerLoading())
- m_modifier.m_amount = caster->SpellHealingBonus(GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE, m_target);
+ m_modifier.m_amount = caster->SpellHealingBonus(m_target, GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE);
}
- // Do final heal for real !apply
- else if (Real)
+ else
{
- if (GetAuraDuration() <= 0 || m_removeMode==AURA_REMOVE_BY_DISPEL)
+ // Final heal only on dispelled or duration end
+ if ( !(GetAuraDuration() <= 0 || m_removeMode==AURA_REMOVE_BY_DISPEL) )
+ return;
+
+ // final heal
+ if(m_target->IsInWorld())
+ m_target->CastCustomSpell(m_target,33778,&m_modifier.m_amount,NULL,NULL,true,NULL,this,GetCasterGUID());
+
+ /*// have a look if there is still some other Lifebloom dummy aura
+ Unit::AuraList auras = m_target->GetAurasByType(SPELL_AURA_DUMMY);
+ for(Unit::AuraList::iterator itr = auras.begin(); itr!=auras.end(); ++itr)
+ if((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID &&
+ (*itr)->GetSpellProto()->SpellFamilyFlags & 0x1000000000LL)
+ return;
+
+ // final heal
+ if(m_target->IsInWorld() && m_stackAmount > 0)
{
- // final heal
- if(m_target->IsInWorld())
- m_target->CastCustomSpell(m_target,33778,&m_modifier.m_amount,NULL,NULL,true,NULL,this,GetCasterGUID());
- }
+ int32 amount = m_modifier.m_amount / m_stackAmount;
+ m_target->CastCustomSpell(m_target,33778,&amount,NULL,NULL,true,NULL,this,GetCasterGUID());
+ }*/
}
return;
}
@@ -2091,10 +2160,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
mod->value = m_modifier.m_amount/7;
mod->type = SPELLMOD_FLAT;
mod->spellId = GetId();
- mod->effectId = m_effIndex;
- mod->lastAffected = NULL;
- mod->mask = 0x001000000000LL;
- mod->charges = 0;
+ mod->mask[1] = 0x0010;
m_spellmod = mod;
}
@@ -2117,10 +2183,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
mod->value = m_modifier.m_amount;
mod->type = SPELLMOD_FLAT;
mod->spellId = GetId();
- mod->effectId = m_effIndex;
- mod->lastAffected = NULL;
- mod->mask = 0x4000000000000LL;
- mod->charges = 0;
+ mod->mask[1] = 0x40000;
m_spellmod = mod;
}
@@ -2142,18 +2205,15 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
mod->value = m_modifier.m_amount;
mod->type = SPELLMOD_PCT;
mod->spellId = GetId();
- mod->effectId = m_effIndex;
- mod->lastAffected = NULL;
switch (m_effIndex)
{
case 0:
- mod->mask = 0x00200000000LL; // Windfury Totem
+ mod->mask[1] = 0x002; // Windfury Totem
break;
case 1:
- mod->mask = 0x00400000000LL; // Flametongue Totem
+ mod->mask[1] = 0x004; // Flametongue Totem
break;
}
- mod->charges = 0;
m_spellmod = mod;
}
@@ -2194,42 +2254,6 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
}
}
-void Aura::HandleAuraPeriodicDummy(bool apply, bool Real)
-{
- // spells required only Real aura add/remove
- if(!Real)
- return;
-
- SpellEntry const*spell = GetSpellProto();
- switch( spell->SpellFamilyName)
- {
- case SPELLFAMILY_ROGUE:
- {
- // Master of Subtlety
- if (spell->Id==31666 && !apply && Real)
- {
- m_target->RemoveAurasDueToSpell(31665);
- break;
- }
- break;
- }
- case SPELLFAMILY_HUNTER:
- {
- // Aspect of the Viper
- if (spell->SpellFamilyFlags&0x0004000000000000LL)
- {
- // Update regen on remove
- if (!apply && m_target->GetTypeId() == TYPEID_PLAYER)
- ((Player*)m_target)->UpdateManaRegen();
- break;
- }
- break;
- }
- }
-
- m_isPeriodic = apply;
-}
-
void Aura::HandleAuraMounted(bool apply, bool Real)
{
// only at real add/remove aura
@@ -2312,12 +2336,8 @@ void Aura::HandleAuraHover(bool apply, bool Real)
void Aura::HandleWaterBreathing(bool apply, bool Real)
{
- if(apply)
- m_target->waterbreath = true;
- else if(m_target->GetAurasByType(SPELL_AURA_WATER_BREATHING).empty())
+ if(!apply && !m_target->HasAuraType(SPELL_AURA_WATER_BREATHING))
{
- m_target->waterbreath = false;
-
// update for enable timer in case not moving target
if(m_target->GetTypeId()==TYPEID_PLAYER && m_target->IsInWorld())
{
@@ -2395,6 +2415,9 @@ void Aura::HandleAuraModShapeshift(bool apply, bool Real)
else
modelid = 21244;
break;
+ case FORM_METAMORPHOSIS:
+ modelid = 25277;
+ break;
case FORM_AMBIENT:
case FORM_SHADOW:
case FORM_STEALTH:
@@ -2742,7 +2765,7 @@ void Aura::HandleAuraModSkill(bool apply, bool Real)
return;
uint32 prot=GetSpellProto()->EffectMiscValue[m_effIndex];
- int32 points = GetModifierValue();
+ int32 points = m_modifier.m_amount;
((Player*)m_target)->ModifySkillBonus(prot,(apply ? points: -points),m_modifier.m_auraname==SPELL_AURA_MOD_SKILL_TALENT);
if(prot == SKILL_DEFENSE)
@@ -2762,6 +2785,9 @@ void Aura::HandleChannelDeathItem(bool apply, bool Real)
//talent will remove the caster's aura->interrupt channel->remove victim aura
if(victim->GetHealth() > 0)
return;
+ // Item amount
+ if (m_modifier.m_amount <= 0)
+ return;
SpellEntry const *spellInfo = GetSpellProto();
if(spellInfo->EffectItemType[m_effIndex] == 0)
@@ -2772,16 +2798,22 @@ void Aura::HandleChannelDeathItem(bool apply, bool Real)
(victim->getLevel() <= Trinity::XP::GetGrayLevel(caster->getLevel()) ||
victim->GetTypeId()==TYPEID_UNIT && !((Player*)caster)->isAllowedToLoot((Creature*)victim)) )
return;
+ //Adding items
+ uint32 noSpaceForCount = 0;
+ uint32 count = m_modifier.m_amount;
+
ItemPosCountVec dest;
- uint8 msg = ((Player*)caster)->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, spellInfo->EffectItemType[m_effIndex], 1 );
+ uint8 msg = ((Player*)caster)->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, spellInfo->EffectItemType[m_effIndex], count, &noSpaceForCount);
if( msg != EQUIP_ERR_OK )
{
+ count-=noSpaceForCount;
((Player*)caster)->SendEquipError( msg, NULL, NULL );
- return;
+ if (count==0)
+ return;
}
Item* newitem = ((Player*)caster)->StoreNewItem(dest, spellInfo->EffectItemType[m_effIndex], true);
- ((Player*)caster)->SendNewItem(newitem, 1, true, false);
+ ((Player*)caster)->SendNewItem(newitem, count, true, false);
}
}
@@ -2791,10 +2823,7 @@ void Aura::HandleBindSight(bool apply, bool Real)
if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
return;
- if (apply)
- m_target->AddPlayerToVision((Player*)caster);
- else
- m_target->RemovePlayerFromVision((Player*)caster);
+ ((Player*)caster)->SetBindSight(apply ? m_target : NULL);
}
void Aura::HandleFarSight(bool apply, bool Real)
@@ -2803,7 +2832,7 @@ void Aura::HandleFarSight(bool apply, bool Real)
if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
return;
- ((Player*)caster)->SetFarSight(apply ? m_target->GetGUID() : NULL);
+ ((Player*)caster)->SetFarSightGUID(apply ? m_target->GetGUID() : 0);
}
void Aura::HandleAuraTrackCreatures(bool apply, bool Real)
@@ -2839,30 +2868,78 @@ void Aura::HandleAuraTrackStealthed(bool apply, bool Real)
void Aura::HandleAuraModScale(bool apply, bool Real)
{
- m_target->ApplyPercentModFloatValue(OBJECT_FIELD_SCALE_X,GetModifierValue(),apply);
+ m_target->ApplyPercentModFloatValue(OBJECT_FIELD_SCALE_X,m_modifier.m_amount,apply);
}
-void Aura::HandleModPossess(bool apply, bool Real)
+/*void Aura::HandleModPossess(bool apply, bool Real)
{
if(!Real)
return;
+ if(m_target->getLevel() > m_modifier.m_amount)
+ return;
+
+ // not possess yourself
+ if(GetCasterGUID() == m_target->GetGUID())
+ return;
+
Unit* caster = GetCaster();
- if(caster && caster->GetTypeId() == TYPEID_UNIT)
- {
- HandleModCharm(apply, Real);
+ if(!caster)
return;
- }
- if(apply)
+ if( apply )
{
- if(m_target->getLevel() > m_modifier.m_amount)
- return;
+ m_target->SetCharmerGUID(GetCasterGUID());
+ m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,caster->getFaction());
+ caster->SetCharm(m_target);
- m_target->SetCharmedOrPossessedBy(caster, true);
+ m_target->CombatStop();
+ m_target->DeleteThreatList();
+ if(m_target->GetTypeId() == TYPEID_UNIT)
+ {
+ m_target->StopMoving();
+ m_target->GetMotionMaster()->Clear();
+ m_target->GetMotionMaster()->MoveIdle();
+ CharmInfo *charmInfo = ((Creature*)m_target)->InitCharmInfo(m_target);
+ charmInfo->InitPossessCreateSpells();
+ }
+
+ if(caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)caster)->PossessSpellInitialize();
+ }
}
else
- m_target->RemoveCharmedOrPossessedBy(caster);
+ {
+ m_target->SetCharmerGUID(0);
+
+ if(m_target->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)m_target)->setFactionForRace(m_target->getRace());
+ else if(m_target->GetTypeId() == TYPEID_UNIT)
+ {
+ CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
+ m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction_A);
+ }
+
+ caster->SetCharm(0);
+
+ if(caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ WorldPacket data(SMSG_PET_SPELLS, 8);
+ data << uint64(0);
+ data << uint32(0);
+ ((Player*)caster)->GetSession()->SendPacket(&data);
+ }
+ if(m_target->GetTypeId() == TYPEID_UNIT)
+ {
+ ((Creature*)m_target)->AIM_Initialize();
+
+ if (((Creature*)m_target)->AI())
+ ((Creature*)m_target)->AI()->AttackStart(caster);
+ }
+ }
+ if(caster->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)caster)->SetFarSightGUID(apply ? m_target->GetGUID() : 0);
}
void Aura::HandleModPossessPet(bool apply, bool Real)
@@ -2873,42 +2950,151 @@ void Aura::HandleModPossessPet(bool apply, bool Real)
Unit* caster = GetCaster();
if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
return;
- if(caster->GetPet() != m_target)
+
+ Pet *pet = caster->GetPet();
+ if(!pet || pet != m_target)
return;
if(apply)
- m_target->SetCharmedOrPossessedBy(caster, true);
+ pet->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
else
- {
- m_target->RemoveCharmedOrPossessedBy(caster);
+ pet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
- // Reinitialize the pet bar and make the pet come back to the owner
- ((Player*)caster)->PetSpellInitialize();
- if(!m_target->getVictim())
- {
- m_target->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
- m_target->GetCharmInfo()->SetCommandState(COMMAND_FOLLOW);
- }
+ ((Player*)caster)->SetFarSightGUID(apply ? pet->GetGUID() : NULL);
+ ((Player*)caster)->SetCharm(apply ? pet : NULL);
+ ((Player*)caster)->SetClientControl(pet, apply ? 1 : 0);
+
+ if(apply)
+ {
+ pet->StopMoving();
+ pet->GetMotionMaster()->Clear();
+ pet->GetMotionMaster()->MoveIdle();
+ }
+ else
+ {
+ pet->AttackStop();
+ pet->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
+ pet->SetUnitMovementFlags(MOVEMENTFLAG_NONE);
}
+}*/
+
+void Aura::HandleAuraModPetTalentsPoints(bool Apply, bool Real)
+{
+ if(!Real)
+ return;
+
+ // Recalculate pet tlaent points
+ if (Pet *pet=m_target->GetPet())
+ pet->InitTalentForLevel();
}
-void Aura::HandleModCharm(bool apply, bool Real)
+/*void Aura::HandleModCharm(bool apply, bool Real)
{
if(!Real)
return;
+ // not charm yourself
+ if(GetCasterGUID() == m_target->GetGUID())
+ return;
+
Unit* caster = GetCaster();
+ if(!caster)
+ return;
- if(apply)
+ if(int32(m_target->getLevel()) <= m_modifier.m_amount)
{
- if(int32(m_target->getLevel()) > m_modifier.m_amount)
- return;
+ if( apply )
+ {
+ m_target->SetCharmerGUID(GetCasterGUID());
+ m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,caster->getFaction());
+ m_target->CastStop(m_target==caster ? GetId() : 0);
+ caster->SetCharm(m_target);
- m_target->SetCharmedOrPossessedBy(caster, false);
+ m_target->CombatStop();
+ m_target->DeleteThreatList();
+
+ if(m_target->GetTypeId() == TYPEID_UNIT)
+ {
+ ((Creature*)m_target)->AIM_Initialize();
+ CharmInfo *charmInfo = ((Creature*)m_target)->InitCharmInfo(m_target);
+ charmInfo->InitCharmCreateSpells();
+ charmInfo->SetReactState( REACT_DEFENSIVE );
+
+ if(caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK)
+ {
+ CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
+ if(cinfo && cinfo->type == CREATURE_TYPE_DEMON)
+ {
+ //to prevent client crash
+ m_target->SetFlag(UNIT_FIELD_BYTES_0, 2048);
+ //just to enable stat window
+ charmInfo->SetPetNumber(objmgr.GeneratePetNumber(), true);
+ //if charmed two demons the same session, the 2nd gets the 1st one's name
+ m_target->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL));
+ }
+ }
+ }
+
+ if(caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)caster)->CharmSpellInitialize();
+ }
+ }
+ else
+ {
+ m_target->SetCharmerGUID(0);
+
+ if(m_target->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)m_target)->setFactionForRace(m_target->getRace());
+ else
+ {
+ CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
+
+ // restore faction
+ if(((Creature*)m_target)->isPet())
+ {
+ if(Unit* owner = m_target->GetOwner())
+ m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,owner->getFaction());
+ else if(cinfo)
+ m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction_A);
+ }
+ else if(cinfo) // normal creature
+ m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction_A);
+
+ // restore UNIT_FIELD_BYTES_0
+ if(cinfo && caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK && cinfo->type == CREATURE_TYPE_DEMON)
+ {
+ CreatureDataAddon const *cainfo = ((Creature*)m_target)->GetCreatureAddon();
+ if(cainfo && cainfo->bytes0 != 0)
+ m_target->SetUInt32Value(UNIT_FIELD_BYTES_0, cainfo->bytes0);
+ else
+ m_target->RemoveFlag(UNIT_FIELD_BYTES_0, 2048);
+
+ if(m_target->GetCharmInfo())
+ m_target->GetCharmInfo()->SetPetNumber(0, true);
+ else
+ sLog.outError("Aura::HandleModCharm: target="I64FMTD" with typeid=%d has a charm aura but no charm info!", m_target->GetGUID(), m_target->GetTypeId());
+ }
+ }
+
+ caster->SetCharm(0);
+
+ if(caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ WorldPacket data(SMSG_PET_SPELLS, 8);
+ data << uint64(0);
+ data << uint32(0);
+ ((Player*)caster)->GetSession()->SendPacket(&data);
+ }
+ if(m_target->GetTypeId() == TYPEID_UNIT)
+ {
+ ((Creature*)m_target)->AIM_Initialize();
+ if (((Creature*)m_target)->AI())
+ ((Creature*)m_target)->AI()->AttackStart(caster);
+ }
+ }
}
- else
- m_target->RemoveCharmedOrPossessedBy(caster);
-}
+}*/
void Aura::HandleModConfuse(bool apply, bool Real)
{
@@ -2947,7 +3133,7 @@ void Aura::HandleFeignDeath(bool apply, bool Real)
std::list<Unit*> targets;
Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(m_target, m_target, World::GetMaxVisibleDistance());
- Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(targets, u_check);
+ Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(m_target, targets, u_check);
m_target->VisitNearbyObject(World::GetMaxVisibleDistance(), searcher);
for(std::list<Unit*>::iterator iter = targets.begin(); iter != targets.end(); ++iter)
{
@@ -2964,7 +3150,7 @@ void Aura::HandleFeignDeath(bool apply, bool Real)
}
}
// blizz like 2.0.x
- m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN6);
+ m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);
// blizz like 2.0.x
m_target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
// blizz like 2.0.x
@@ -2989,7 +3175,7 @@ void Aura::HandleFeignDeath(bool apply, bool Real)
m_target->SendMessageToSet(&data,true);
*/
// blizz like 2.0.x
- m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN6);
+ m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);
// blizz like 2.0.x
m_target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
// blizz like 2.0.x
@@ -3001,37 +3187,52 @@ void Aura::HandleFeignDeath(bool apply, bool Real)
void Aura::HandleAuraModDisarm(bool apply, bool Real)
{
- if(!Real)
+ if (!Real)
return;
+ AuraType type = GetModifier()->m_auraname;
- if(!apply && m_target->HasAuraType(SPELL_AURA_MOD_DISARM))
+ //Prevent handling aura twice
+ if(apply && m_target->GetAurasByType(type).size()>1)
return;
-
- // not sure for it's correctness
+ if(!apply && m_target->HasAuraType(type))
+ return;
+ uint32 field, flag, slot;
+ WeaponAttackType attType;
+ switch (type)
+ {
+ case SPELL_AURA_MOD_DISARM:
+ field=UNIT_FIELD_FLAGS;
+ flag=UNIT_FLAG_DISARMED;
+ slot=EQUIPMENT_SLOT_MAINHAND;
+ attType=BASE_ATTACK;
+ break;
+ case SPELL_AURA_MOD_DISARM_OFFHAND:
+ field=UNIT_FIELD_FLAGS_2;
+ flag=UNIT_FLAG2_DISARM_OFFHAND;
+ slot=EQUIPMENT_SLOT_OFFHAND;
+ attType=OFF_ATTACK;
+ break;
+ case SPELL_AURA_MOD_DISARM_RANGED:
+ field=UNIT_FIELD_FLAGS_2;
+ flag=UNIT_FLAG2_DISARM_RANGED;
+ slot=EQUIPMENT_SLOT_RANGED;
+ attType=RANGED_ATTACK;
+ break;
+ }
if(apply)
- m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED);
+ m_target->SetFlag(field, flag);
else
- m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED);
+ m_target->RemoveFlag(field, flag);
if (m_target->GetTypeId() == TYPEID_PLAYER)
{
- // main-hand attack speed already set to special value for feral form already and don't must change and reset at remove.
- if (((Player *)m_target)->IsInFeralForm())
- return;
-
- if (apply)
- m_target->SetAttackTime(BASE_ATTACK,BASE_ATTACK_TIME);
- else
- ((Player *)m_target)->SetRegularAttackTime();
- }
- else
- {
- // creature does not have equipment
- if(apply && !((Creature*)m_target)->GetCurrentEquipmentId())
+ Item *pItem = ((Player*)m_target)->GetItemByPos( INVENTORY_SLOT_BAG_0, slot );
+ if(!pItem )
return;
+ ((Player*)m_target)->_ApplyItemMods(pItem, slot, !apply);
}
-
- m_target->UpdateDamagePhysical(BASE_ATTACK);
+ else if (((Creature*)m_target)->GetCurrentEquipmentId())
+ m_target->UpdateDamagePhysical(attType);
}
void Aura::HandleAuraModStun(bool apply, bool Real)
@@ -3059,7 +3260,7 @@ void Aura::HandleModStealth(bool apply, bool Real)
// only at real aura add
if(Real)
{
- m_target->SetByteValue(UNIT_FIELD_BYTES_1, 2, 0x02);
+ m_target->SetStandFlags(UNIT_STAND_FLAGS_CREEP);
if(m_target->GetTypeId()==TYPEID_PLAYER)
m_target->SetFlag(PLAYER_FIELD_BYTES2, 0x2000);
@@ -3070,10 +3271,6 @@ void Aura::HandleModStealth(bool apply, bool Real)
//m_target->SetVisibility(VISIBILITY_OFF);
m_target->SetVisibility(VISIBILITY_GROUP_STEALTH);
}
-
- // for RACE_NIGHTELF stealth
- if(m_target->GetTypeId()==TYPEID_PLAYER && GetId()==20580)
- m_target->CastSpell(m_target, 21009, true, NULL, this);
}
}
else
@@ -3081,14 +3278,10 @@ void Aura::HandleModStealth(bool apply, bool Real)
// only at real aura remove
if(Real)
{
- // for RACE_NIGHTELF stealth
- if(m_target->GetTypeId()==TYPEID_PLAYER && GetId()==20580)
- m_target->RemoveAurasDueToSpell(21009);
-
// if last SPELL_AURA_MOD_STEALTH and no GM invisibility
if(!m_target->HasAuraType(SPELL_AURA_MOD_STEALTH) && m_target->GetVisibility()!=VISIBILITY_OFF)
{
- m_target->SetByteValue(UNIT_FIELD_BYTES_1, 2, 0x00);
+ m_target->RemoveStandFlags(UNIT_STAND_FLAGS_CREEP);
if(m_target->GetTypeId()==TYPEID_PLAYER)
m_target->RemoveFlag(PLAYER_FIELD_BYTES2, 0x2000);
@@ -3210,6 +3403,10 @@ void Aura::HandleAuraModRoot(bool apply, bool Real)
if(!Real)
return;
+ // Frost root aura -> freeze/unfreeze target
+ if (GetSpellSchoolMask(m_spellProto) & SPELL_SCHOOL_MASK_FROST)
+ m_target->ModifyAuraState(AURA_STATE_FROZEN, apply);
+
m_target->SetControlled(apply, UNIT_STAT_ROOT);
}
@@ -3249,7 +3446,7 @@ void Aura::HandleAuraModSilence(bool apply, bool Real)
return;
// Search Mana Tap auras on caster
- Aura * dummy = m_target->GetDummyAura(28734);
+ Aura * dummy = caster->GetDummyAura(28734);
if (dummy)
{
int32 bp = dummy->GetStackAmount() * 10;
@@ -3306,7 +3503,7 @@ void Aura::HandleModThreat(bool apply, bool Real)
if(m_modifier.m_miscvalue & int32(1<<x))
{
if(m_target->GetTypeId() == TYPEID_PLAYER)
- ApplyPercentModFloatVar(m_target->m_threatModifier[x], m_positive ? GetModifierValue() : -GetModifierValue(), apply);
+ ApplyPercentModFloatVar(m_target->m_threatModifier[x], m_positive ? m_modifier.m_amount : -m_modifier.m_amount, apply);
}
}
}
@@ -3327,9 +3524,9 @@ void Aura::HandleAuraModTotalThreat(bool apply, bool Real)
float threatMod = 0.0f;
if(apply)
- threatMod = float(GetModifierValue());
+ threatMod = float(m_modifier.m_amount);
else
- threatMod = float(-GetModifierValue());
+ threatMod = float(-m_modifier.m_amount);
m_target->getHostilRefManager().threatAssist(caster, threatMod);
}
@@ -3398,7 +3595,7 @@ void Aura::HandleAuraModIncreaseFlightSpeed(bool apply, bool Real)
//Players on flying mounts must be immune to polymorph
if (m_target->GetTypeId()==TYPEID_PLAYER)
- m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,MECHANIC_POLYMORPH,apply);
+ m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,1<<MECHANIC_POLYMORPH,apply);
// Dragonmaw Illusion (overwrite mount model, mounted aura already applied)
if( apply && m_target->HasAura(42016,0) && m_target->GetMountID())
@@ -3445,8 +3642,11 @@ void Aura::HandleAuraModUseNormalSpeed(bool /*apply*/, bool Real)
void Aura::HandleModMechanicImmunity(bool apply, bool Real)
{
- uint32 mechanic = 1 << m_modifier.m_miscvalue;
-
+ uint32 mechanic;
+ if (GetSpellProto()->EffectApplyAuraName[GetEffIndex()]==SPELL_AURA_MECHANIC_IMMUNITY)
+ mechanic = 1 << m_modifier.m_miscvalue;
+ else //SPELL_AURA_MECHANIC_IMMUNITY_MASK
+ mechanic = m_modifier.m_miscvalue;
//immune movement impairment and loss of control
if(GetId()==42292)
mechanic=IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK;
@@ -3459,9 +3659,8 @@ void Aura::HandleModMechanicImmunity(bool apply, bool Real)
next = iter;
++next;
SpellEntry const *spell = iter->second->GetSpellProto();
- if (!( spell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) // spells unaffected by invulnerability
- && !iter->second->IsPositive() // only remove negative spells
- && spell->Id != GetId())
+ if (!( spell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) && // spells unaffected by invulnerability
+ spell->Id != GetId())
{
//check for mechanic mask
if(GetSpellMechanicMask(spell, iter->second->GetEffIndex()) & mechanic)
@@ -3476,18 +3675,7 @@ void Aura::HandleModMechanicImmunity(bool apply, bool Real)
}
}
- m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,m_modifier.m_miscvalue,apply);
-
- // special cases
- switch(m_modifier.m_miscvalue)
- {
- case MECHANIC_INVULNERABILITY:
- m_target->ModifyAuraState(AURA_STATE_FORBEARANCE,apply);
- break;
- case MECHANIC_SHIELD:
- m_target->ModifyAuraState(AURA_STATE_WEAKENED_SOUL,apply);
- break;
- }
+ m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,mechanic,apply);
// Bestial Wrath
if ( GetSpellProto()->SpellFamilyName == SPELLFAMILY_HUNTER && GetSpellProto()->Id == 19574)
@@ -3662,8 +3850,7 @@ void Aura::HandleAuraProcTriggerSpell(bool apply, bool Real)
switch (GetId())
{
case 28200: // Ascendance (Talisman of Ascendance trinket)
- m_procCharges = 6;
- UpdateAuraCharges();
+ SetAuraCharges(6);
break;
default: break;
}
@@ -3685,75 +3872,72 @@ void Aura::HandleAuraModStalked(bool apply, bool Real)
void Aura::HandlePeriodicTriggerSpell(bool apply, bool Real)
{
- if (m_periodicTimer <= 0)
- m_periodicTimer += m_modifier.periodictime;
-
m_isPeriodic = apply;
- m_isTrigger = apply;
+}
- // Curse of the Plaguebringer
- if (!apply && m_spellProto->Id == 29213 && m_removeMode!=AURA_REMOVE_BY_DISPEL)
- {
- // Cast Wrath of the Plaguebringer if not dispelled
- m_target->CastSpell(m_target, 29214, true, 0, this);
- }
+void Aura::HandlePeriodicTriggerSpellWithValue(bool apply, bool Real)
+{
+ m_isPeriodic = apply;
}
void Aura::HandlePeriodicEnergize(bool apply, bool Real)
{
- if (m_periodicTimer <= 0)
- m_periodicTimer += m_modifier.periodictime;
+ if (!Real)
+ return;
m_isPeriodic = apply;
+
+ // Replenishment (0.25% from max)
+ // Infinite Replenishment
+ if (GetId() == 57669 ||
+ GetId() == 61782)
+ m_modifier.m_amount = m_target->GetMaxPower(POWER_MANA) * 25 / 10000;
}
-void Aura::HandlePeriodicHeal(bool apply, bool Real)
+void Aura::HandleAuraPowerBurn(bool apply, bool Real)
{
- if (m_periodicTimer <= 0)
- m_periodicTimer += m_modifier.periodictime;
-
m_isPeriodic = apply;
+}
- // only at real apply
- if (Real && apply && GetSpellProto()->Mechanic == MECHANIC_BANDAGE)
- {
- // provided m_target as original caster to prevent apply aura caster selection for this negative buff
- m_target->CastSpell(m_target,11196,true,NULL,this,m_target->GetGUID());
- }
+void Aura::HandleAuraPeriodicDummy(bool apply, bool Real)
+{
+ // spells required only Real aura add/remove
+ if(!Real)
+ return;
// For prevent double apply bonuses
bool loading = (m_target->GetTypeId() == TYPEID_PLAYER && ((Player*)m_target)->GetSession()->PlayerLoading());
- if(!loading && apply)
+ Unit* caster = GetCaster();
+
+ SpellEntry const*spell = GetSpellProto();
+ switch( spell->SpellFamilyName)
{
- switch (m_spellProto->SpellFamilyName)
+ case SPELLFAMILY_ROGUE:
{
- case SPELLFAMILY_DRUID:
+ // Master of Subtlety
+ if (spell->Id==31666 && !apply)
{
- // Rejuvenation
- if(m_spellProto->SpellFamilyFlags & 0x0000000000000010LL)
- {
- if(Unit* caster = GetCaster())
- {
- Unit::AuraList const& classScripts = caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
- for(Unit::AuraList::const_iterator k = classScripts.begin(); k != classScripts.end(); ++k)
- {
- int32 tickcount = GetSpellDuration(m_spellProto) / m_spellProto->EffectAmplitude[m_effIndex];
- switch((*k)->GetModifier()->m_miscvalue)
- {
- case 4953: // Increased Rejuvenation Healing - Harold's Rejuvenating Broach Aura
- case 4415: // Increased Rejuvenation Healing - Idol of Rejuvenation Aura
- {
- m_modifier.m_amount += (*k)->GetModifier()->m_amount / tickcount;
- break;
- }
- }
- }
- }
- }
+ m_target->RemoveAurasDueToSpell(31665);
+ break;
}
+ break;
+ }
+ case SPELLFAMILY_HUNTER:
+ {
+ // Explosive Shot
+ if (apply && !loading && caster)
+ m_modifier.m_amount +=caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 8 / 100;
+ break;
}
}
+
+ m_isPeriodic = apply;
+}
+
+void Aura::HandlePeriodicHeal(bool apply, bool Real)
+{
+ m_isPeriodic = apply;
}
void Aura::HandlePeriodicDamage(bool apply, bool Real)
@@ -3762,26 +3946,28 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)
if(!Real)
return;
- if (m_periodicTimer <= 0)
- m_periodicTimer += m_modifier.periodictime;
-
m_isPeriodic = apply;
// For prevent double apply bonuses
bool loading = (m_target->GetTypeId() == TYPEID_PLAYER && ((Player*)m_target)->GetSession()->PlayerLoading());
+ // Custom damage calculation after
+ if (!apply || loading)
+ return;
+
Unit *caster = GetCaster();
+ if (!caster)
+ return;
switch (m_spellProto->SpellFamilyName)
{
case SPELLFAMILY_GENERIC:
{
// Pounce Bleed
- if ( m_spellProto->SpellIconID == 147 && m_spellProto->SpellVisual == 0 )
+ if ( m_spellProto->SpellIconID == 147 && m_spellProto->SpellVisual[0] == 0 )
{
// $AP*0.18/6 bonus per tick
- if (apply && !loading && caster)
- m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 3 / 100);
+ m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 3 / 100);
return;
}
break;
@@ -3789,18 +3975,14 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)
case SPELLFAMILY_WARRIOR:
{
// Rend
- if (m_spellProto->SpellFamilyFlags & 0x0000000000000020LL)
+ if (m_spellProto->SpellFamilyFlags[0] & 0x20)
{
- // 0.00743*(($MWB+$mwb)/2+$AP/14*$MWS) bonus per tick
- if (apply && !loading && caster)
- {
- float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK);
- int32 mws = caster->GetAttackTime(BASE_ATTACK);
- float mwb_min = caster->GetWeaponDamageRange(BASE_ATTACK,MINDAMAGE);
- float mwb_max = caster->GetWeaponDamageRange(BASE_ATTACK,MAXDAMAGE);
- // WARNING! in 3.0 multiplier 0.00743f change to 0.6
- m_modifier.m_amount+=int32(((mwb_min+mwb_max)/2+ap*mws/14000)*0.00743f);
- }
+ // $0.2*(($MWB+$mwb)/2+$AP/14*$MWS) bonus per tick
+ float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK);
+ int32 mws = caster->GetAttackTime(BASE_ATTACK);
+ float mwb_min = caster->GetWeaponDamageRange(BASE_ATTACK,MINDAMAGE);
+ float mwb_max = caster->GetWeaponDamageRange(BASE_ATTACK,MAXDAMAGE);
+ m_modifier.m_amount+=int32(((mwb_min+mwb_max)/2+ap*mws/14000)*0.2f);
return;
}
break;
@@ -3808,92 +3990,80 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)
case SPELLFAMILY_DRUID:
{
// Rake
- if (m_spellProto->SpellFamilyFlags & 0x0000000000001000LL)
+ if (m_spellProto->SpellFamilyFlags[0] & 0x1000)
{
- // $AP*0.06/3 bonus per tick
- if (apply && !loading && caster)
- m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 2 / 100);
+ // $AP*0.06 bonus per tick
+ m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 6 / 100);
return;
}
// Lacerate
- if (m_spellProto->SpellFamilyFlags & 0x000000010000000000LL)
+ if (m_spellProto->SpellFamilyFlags[1] & 0x0000000100)
{
// $AP*0.05/5 bonus per tick
- if (apply && !loading && caster)
- m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100);
+ m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100);
return;
}
// Rip
- if (m_spellProto->SpellFamilyFlags & 0x000000000000800000LL)
+ if (m_spellProto->SpellFamilyFlags[1] & 0x800000)
{
- // $AP * min(0.06*$cp, 0.24)/6 [Yes, there is no difference, whether 4 or 5 CPs are being used]
- if (apply && !loading && caster && caster->GetTypeId() == TYPEID_PLAYER)
- {
- uint8 cp = ((Player*)caster)->GetComboPoints();
+ // 0.01*$AP*cp
+ if (caster->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ uint8 cp = ((Player*)caster)->GetComboPoints();
- // Idol of Feral Shadows. Cant be handled as SpellMod in SpellAura:Dummy due its dependency from CPs
- Unit::AuraList const& dummyAuras = caster->GetAurasByType(SPELL_AURA_DUMMY);
- for(Unit::AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr)
+ // Idol of Feral Shadows. Cant be handled as SpellMod in SpellAura:Dummy due its dependency from CPs
+ Unit::AuraList const& dummyAuras = caster->GetAurasByType(SPELL_AURA_DUMMY);
+ for(Unit::AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr)
+ {
+ if((*itr)->GetId()==34241)
{
- if((*itr)->GetId()==34241)
- {
- m_modifier.m_amount += cp * (*itr)->GetModifier()->m_amount;
- break;
- }
+ m_modifier.m_amount += cp * (*itr)->GetModifier()->m_amount;
+ break;
}
-
- if (cp > 4) cp = 4;
- m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * cp / 100);
}
+ m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * cp / 100);
+ return;
+ }
+ // Lock Jaw
+ if (m_spellProto->SpellFamilyFlags[1] & 0x10000000)
+ {
+ // 0.15*$AP
+ m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 15 / 100);
return;
}
break;
}
case SPELLFAMILY_ROGUE:
{
- // Deadly poison aura state
- if((m_spellProto->SpellFamilyFlags & 0x10000) && m_spellProto->SpellVisual==5100)
+ // Rupture
+ if (m_spellProto->SpellFamilyFlags[0] & 0x100000)
{
- if(apply)
- m_target->ModifyAuraState(AURA_STATE_DEADLY_POISON,true);
- else
- {
- // current aura already removed, search present of another
- bool found = false;
- Unit::AuraList const& auras = m_target->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
- for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
- {
- SpellEntry const* itr_spell = (*itr)->GetSpellProto();
- if(itr_spell && itr_spell->SpellFamilyName==SPELLFAMILY_ROGUE && (itr_spell->SpellFamilyFlags & 0x10000) && itr_spell->SpellVisual==5100)
- {
- found = true;
- break;
- }
- }
- // this has been last deadly poison aura
- if(!found)
- m_target->ModifyAuraState(AURA_STATE_DEADLY_POISON,false);
- }
+ if (caster->GetTypeId() != TYPEID_PLAYER)
+ return;
+ //1 point : ${($m1+$b1*1+0.015*$AP)*4} damage over 8 secs
+ //2 points: ${($m1+$b1*2+0.024*$AP)*5} damage over 10 secs
+ //3 points: ${($m1+$b1*3+0.03*$AP)*6} damage over 12 secs
+ //4 points: ${($m1+$b1*4+0.03428571*$AP)*7} damage over 14 secs
+ //5 points: ${($m1+$b1*5+0.0375*$AP)*8} damage over 16 secs
+ float AP_per_combo[] = {0, 0.015f, 0.024, 0.03, 0.03428571, 0.0375};
+ uint8 cp = ((Player*)caster)->GetComboPoints();
+ if (cp > 5) cp = 5;
+ m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * AP_per_combo[cp]);
return;
}
- // Rupture
- if (m_spellProto->SpellFamilyFlags & 0x000000000000100000LL)
+ // Garrote
+ if (m_spellProto->SpellFamilyFlags[0] & 0x100)
{
- // Dmg/tick = $AP*min(0.01*$cp, 0.03) [Like Rip: only the first three CP increase the contribution from AP]
- if (apply && !loading && caster && caster->GetTypeId() == TYPEID_PLAYER)
- {
- uint8 cp = ((Player*)caster)->GetComboPoints();
- if (cp > 3) cp = 3;
- m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * cp / 100);
- }
+ // $AP*0.07 bonus per tick
+ m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 7 / 100);
return;
}
- // Garrote
- if (m_spellProto->SpellFamilyFlags & 0x000000000000000100LL)
+ // Deadly Poison
+ if (m_spellProto->SpellFamilyFlags[0] & 0x10000)
{
- // $AP*0.18/6 bonus per tick
- if (apply && !loading && caster)
- m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 3 / 100);
+ // 0.08*$AP / 4 * amount of stack
+ m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 2 * GetStackAmount() / 100);
return;
}
break;
@@ -3901,47 +4071,17 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)
case SPELLFAMILY_HUNTER:
{
// Serpent Sting
- if (m_spellProto->SpellFamilyFlags & 0x0000000000004000LL)
+ if (m_spellProto->SpellFamilyFlags[0] & 0x4000)
{
// $RAP*0.1/5 bonus per tick
- if (apply && !loading && caster)
- m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 10 / 500);
+ m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 10 / 500);
return;
}
// Immolation Trap
- if (m_spellProto->SpellFamilyFlags & 0x0000000000000004LL && m_spellProto->SpellIconID == 678)
+ if (m_spellProto->SpellFamilyFlags[0] & 0x4 && m_spellProto->SpellIconID == 678)
{
// $RAP*0.1/5 bonus per tick
- if (apply && !loading && caster)
- m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 10 / 500);
- return;
- }
- break;
- }
- case SPELLFAMILY_PALADIN:
- {
- // Consecration
- if (m_spellProto->SpellFamilyFlags & 0x0000000000000020LL)
- {
- if (apply && !loading)
- {
- if(Unit* caster = GetCaster())
- {
- Unit::AuraList const& classScripts = caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
- for(Unit::AuraList::const_iterator k = classScripts.begin(); k != classScripts.end(); ++k)
- {
- int32 tickcount = GetSpellDuration(m_spellProto) / m_spellProto->EffectAmplitude[m_effIndex];
- switch((*k)->GetModifier()->m_miscvalue)
- {
- case 5147: // Improved Consecration - Libram of the Eternal Rest
- {
- m_modifier.m_amount += (*k)->GetModifier()->m_amount / tickcount;
- break;
- }
- }
- }
- }
- }
+ m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 10 / 500);
return;
}
break;
@@ -3953,25 +4093,21 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)
void Aura::HandlePeriodicDamagePCT(bool apply, bool Real)
{
- if (m_periodicTimer <= 0)
- m_periodicTimer += m_modifier.periodictime;
-
m_isPeriodic = apply;
}
void Aura::HandlePeriodicLeech(bool apply, bool Real)
{
- if (m_periodicTimer <= 0)
- m_periodicTimer += m_modifier.periodictime;
-
m_isPeriodic = apply;
}
void Aura::HandlePeriodicManaLeech(bool apply, bool Real)
{
- if (m_periodicTimer <= 0)
- m_periodicTimer += m_modifier.periodictime;
+ m_isPeriodic = apply;
+}
+void Aura::HandlePeriodicHealthFunnel(bool apply, bool Real)
+{
m_isPeriodic = apply;
}
@@ -3989,9 +4125,9 @@ void Aura::HandleAuraModResistanceExclusive(bool apply, bool Real)
{
if(m_modifier.m_miscvalue & int32(1<<x))
{
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_VALUE, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_VALUE, float(m_modifier.m_amount), apply);
if(m_target->GetTypeId() == TYPEID_PLAYER)
- m_target->ApplyResistanceBuffModsMod(SpellSchools(x),m_positive,GetModifierValue(), apply);
+ m_target->ApplyResistanceBuffModsMod(SpellSchools(x),m_positive,m_modifier.m_amount, apply);
}
}
}
@@ -4002,19 +4138,11 @@ void Aura::HandleAuraModResistance(bool apply, bool Real)
{
if(m_modifier.m_miscvalue & int32(1<<x))
{
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), TOTAL_VALUE, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), TOTAL_VALUE, float(m_modifier.m_amount), apply);
if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet())
- m_target->ApplyResistanceBuffModsMod(SpellSchools(x),m_positive,GetModifierValue(), apply);
+ m_target->ApplyResistanceBuffModsMod(SpellSchools(x),m_positive,m_modifier.m_amount, apply);
}
}
-
- // Faerie Fire (druid versions)
- if( m_spellProto->SpellIconID == 109 &&
- m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID &&
- m_spellProto->SpellFamilyFlags & 0x0000000000000400LL )
- {
- m_target->ModifyAuraState(AURA_STATE_FAERIE_FIRE,apply);
- }
}
void Aura::HandleAuraModBaseResistancePCT(bool apply, bool Real)
@@ -4024,14 +4152,14 @@ void Aura::HandleAuraModBaseResistancePCT(bool apply, bool Real)
{
//pets only have base armor
if(((Creature*)m_target)->isPet() && (m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL))
- m_target->HandleStatModifier(UNIT_MOD_ARMOR, BASE_PCT, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UNIT_MOD_ARMOR, BASE_PCT, float(m_modifier.m_amount), apply);
}
else
{
for(int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL;x++)
{
if(m_modifier.m_miscvalue & int32(1<<x))
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_PCT, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_PCT, float(m_modifier.m_amount), apply);
}
}
}
@@ -4042,11 +4170,11 @@ void Aura::HandleModResistancePercent(bool apply, bool Real)
{
if(m_modifier.m_miscvalue & int32(1<<i))
{
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_PCT, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_PCT, float(m_modifier.m_amount), apply);
if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet())
{
- m_target->ApplyResistanceBuffModsPercentMod(SpellSchools(i),true,GetModifierValue(), apply);
- m_target->ApplyResistanceBuffModsPercentMod(SpellSchools(i),false,GetModifierValue(), apply);
+ m_target->ApplyResistanceBuffModsPercentMod(SpellSchools(i),true,m_modifier.m_amount, apply);
+ m_target->ApplyResistanceBuffModsPercentMod(SpellSchools(i),false,m_modifier.m_amount, apply);
}
}
}
@@ -4059,13 +4187,13 @@ void Aura::HandleModBaseResistance(bool apply, bool Real)
{
//only pets have base stats
if(((Creature*)m_target)->isPet() && (m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL))
- m_target->HandleStatModifier(UNIT_MOD_ARMOR, TOTAL_VALUE, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UNIT_MOD_ARMOR, TOTAL_VALUE, float(m_modifier.m_amount), apply);
}
else
{
for(int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++)
if(m_modifier.m_miscvalue & (1<<i))
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_VALUE, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_VALUE, float(m_modifier.m_amount), apply);
}
}
@@ -4087,9 +4215,9 @@ void Aura::HandleAuraModStat(bool apply, bool Real)
if (m_modifier.m_miscvalue < 0 || m_modifier.m_miscvalue == i)
{
//m_target->ApplyStatMod(Stats(i), m_modifier.m_amount,apply);
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_VALUE, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_VALUE, float(m_modifier.m_amount), apply);
if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet())
- m_target->ApplyStatBuffMod(Stats(i),GetModifierValue(),apply);
+ m_target->ApplyStatBuffMod(Stats(i),m_modifier.m_amount,apply);
}
}
}
@@ -4109,7 +4237,7 @@ void Aura::HandleModPercentStat(bool apply, bool Real)
for (int32 i = STAT_STRENGTH; i < MAX_STATS; ++i)
{
if(m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1)
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), BASE_PCT, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), BASE_PCT, float(m_modifier.m_amount), apply);
}
}
@@ -4187,9 +4315,9 @@ void Aura::HandleModTotalPercentStat(bool apply, bool Real)
{
if(m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1)
{
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_PCT, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_PCT, float(m_modifier.m_amount), apply);
if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet())
- m_target->ApplyStatPercentBuffMod(Stats(i), GetModifierValue(), apply );
+ m_target->ApplyStatPercentBuffMod(Stats(i), m_modifier.m_amount, apply );
}
}
@@ -4224,117 +4352,47 @@ void Aura::HandleAuraModResistenceOfStatPercent(bool /*apply*/, bool Real)
/********************************/
void Aura::HandleAuraModTotalHealthPercentRegen(bool apply, bool Real)
{
- /*
- Need additional checking for auras who reduce or increase healing, magic effect like Dumpen Magic,
- so this aura not fully working.
- */
- if(apply)
- {
- if(!m_target->isAlive())
- return;
-
- if((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && !m_target->IsSitState())
- m_target->SetStandState(PLAYER_STATE_SIT);
-
- if(m_periodicTimer <= 0)
- {
- m_periodicTimer += m_modifier.periodictime;
-
- if(m_target->GetHealth() < m_target->GetMaxHealth())
- {
- // PeriodicTick can cast triggered spells with stats changes
- PeriodicTick();
- }
- }
- }
-
m_isPeriodic = apply;
}
void Aura::HandleAuraModTotalManaPercentRegen(bool apply, bool Real)
{
- if((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && apply && !m_target->IsSitState())
- m_target->SetStandState(PLAYER_STATE_SIT);
- if(apply)
- {
- if(m_modifier.periodictime == 0)
- m_modifier.periodictime = 1000;
- if(m_periodicTimer <= 0 && m_target->getPowerType() == POWER_MANA)
- {
- m_periodicTimer += m_modifier.periodictime;
-
- if(m_target->GetPower(POWER_MANA) < m_target->GetMaxPower(POWER_MANA))
- {
- // PeriodicTick can cast triggered spells with stats changes
- PeriodicTick();
- }
- }
- }
+ if(m_modifier.periodictime == 0)
+ m_modifier.periodictime = 1000;
+ m_periodicTimer = m_modifier.periodictime;
m_isPeriodic = apply;
}
void Aura::HandleModRegen(bool apply, bool Real) // eating
{
- if(apply)
- {
- if(!m_target->isAlive())
- return;
-
- if ((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && !m_target->IsSitState())
- m_target->SetStandState(PLAYER_STATE_SIT);
-
- if(m_periodicTimer <= 0)
- {
- m_periodicTimer += 5000;
- int32 gain = m_target->ModifyHealth(GetModifierValue());
- Unit *caster = GetCaster();
- if (caster)
- {
- SpellEntry const *spellProto = GetSpellProto();
- if (spellProto)
- m_target->getHostilRefManager().threatAssist(caster, float(gain) * 0.5f, spellProto);
- }
- }
- }
+ if(m_modifier.periodictime == 0)
+ m_modifier.periodictime = 5000;
+ m_periodicTimer = 5000;
m_isPeriodic = apply;
}
void Aura::HandleModPowerRegen(bool apply, bool Real) // drinking
{
- if ((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && apply && !m_target->IsSitState())
- m_target->SetStandState(PLAYER_STATE_SIT);
+ if (!Real)
+ return;
- if(apply && m_periodicTimer <= 0)
+ Powers pt = m_target->getPowerType();
+ if(m_modifier.periodictime == 0)
{
- m_periodicTimer += 2000;
+ if (pt == POWER_RAGE)
+ m_modifier.periodictime = 1000;
+ else
+ m_modifier.periodictime = 2000;
+ }
- Powers pt = m_target->getPowerType();
- if(int32(pt) != m_modifier.m_miscvalue)
- return;
+ m_periodicTimer = 5000;
- if ( GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED )
- {
- // eating anim
- m_target->HandleEmoteCommand(EMOTE_ONESHOT_EAT);
- }
- else if( GetId() == 20577 )
- {
- // cannibalize anim
- m_target->HandleEmoteCommand(398);
- }
+ if (m_target->GetTypeId() == TYPEID_PLAYER && m_modifier.m_miscvalue == POWER_MANA)
+ ((Player*)m_target)->UpdateManaRegen();
- // Warrior talent, gain 1 rage every 3 seconds while in combat
- if(pt == POWER_RAGE && m_target->isInCombat())
- {
- m_target->ModifyPower(pt, m_modifier.m_amount*10/17);
- m_periodicTimer += 1000;
- }
- }
m_isPeriodic = apply;
- if (Real && m_target->GetTypeId() == TYPEID_PLAYER && m_modifier.m_miscvalue == POWER_MANA)
- ((Player*)m_target)->UpdateManaRegen();
}
void Aura::HandleModPowerRegenPCT(bool /*apply*/, bool Real)
@@ -4378,7 +4436,7 @@ void Aura::HandleAuraModIncreaseHealth(bool apply, bool Real)
{
if(apply)
{
- m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(m_modifier.m_amount), apply);
m_target->ModifyHealth(m_modifier.m_amount);
}
else
@@ -4387,7 +4445,7 @@ void Aura::HandleAuraModIncreaseHealth(bool apply, bool Real)
m_target->ModifyHealth(-m_modifier.m_amount);
else
m_target->SetHealth(1);
- m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(m_modifier.m_amount), apply);
}
}
}
@@ -4418,7 +4476,7 @@ void Aura::HandleAuraModIncreaseEnergy(bool apply, bool Real)
UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + powerType);
- m_target->HandleStatModifier(unitMod, TOTAL_VALUE, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(unitMod, TOTAL_VALUE, float(m_modifier.m_amount), apply);
}
void Aura::HandleAuraModIncreaseEnergyPercent(bool apply, bool /*Real*/)
@@ -4429,12 +4487,17 @@ void Aura::HandleAuraModIncreaseEnergyPercent(bool apply, bool /*Real*/)
UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + powerType);
- m_target->HandleStatModifier(unitMod, TOTAL_PCT, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(unitMod, TOTAL_PCT, float(m_modifier.m_amount), apply);
}
void Aura::HandleAuraModIncreaseHealthPercent(bool apply, bool /*Real*/)
{
- m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_PCT, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_PCT, float(m_modifier.m_amount), apply);
+}
+
+void Aura::HandleAuraIncreaseBaseHealthPercent(bool apply, bool /*Real*/)
+{
+ m_target->HandleStatModifier(UNIT_MOD_HEALTH, BASE_PCT, float(m_modifier.m_amount), apply);
}
/********************************/
@@ -4498,9 +4561,9 @@ void Aura::HandleAuraModCritPercent(bool apply, bool Real)
if (GetSpellProto()->EquippedItemClass == -1)
{
- ((Player*)m_target)->HandleBaseModValue(CRIT_PERCENTAGE, FLAT_MOD, float (GetModifierValue()), apply);
- ((Player*)m_target)->HandleBaseModValue(OFFHAND_CRIT_PERCENTAGE, FLAT_MOD, float (GetModifierValue()), apply);
- ((Player*)m_target)->HandleBaseModValue(RANGED_CRIT_PERCENTAGE, FLAT_MOD, float (GetModifierValue()), apply);
+ ((Player*)m_target)->HandleBaseModValue(CRIT_PERCENTAGE, FLAT_MOD, float (m_modifier.m_amount), apply);
+ ((Player*)m_target)->HandleBaseModValue(OFFHAND_CRIT_PERCENTAGE, FLAT_MOD, float (m_modifier.m_amount), apply);
+ ((Player*)m_target)->HandleBaseModValue(RANGED_CRIT_PERCENTAGE, FLAT_MOD, float (m_modifier.m_amount), apply);
}
else
{
@@ -4510,13 +4573,28 @@ void Aura::HandleAuraModCritPercent(bool apply, bool Real)
void Aura::HandleModHitChance(bool apply, bool Real)
{
- m_target->m_modMeleeHitChance += apply ? GetModifierValue() : -GetModifierValue();
- m_target->m_modRangedHitChance += apply ? GetModifierValue() : -GetModifierValue();
+ if(m_target->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)m_target)->UpdateMeleeHitChances();
+ ((Player*)m_target)->UpdateRangedHitChances();
+ }
+ else
+ {
+ m_target->m_modMeleeHitChance += apply ? m_modifier.m_amount : (-m_modifier.m_amount);
+ m_target->m_modRangedHitChance += apply ? m_modifier.m_amount : (-m_modifier.m_amount);
+ }
}
void Aura::HandleModSpellHitChance(bool apply, bool Real)
{
- m_target->m_modSpellHitChance += apply ? GetModifierValue(): -GetModifierValue();
+ if(m_target->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)m_target)->UpdateSpellHitChances();
+ }
+ else
+ {
+ m_target->m_modSpellHitChance += apply ? m_modifier.m_amount: (-m_modifier.m_amount);
+ }
}
void Aura::HandleModSpellCritChance(bool apply, bool Real)
@@ -4531,7 +4609,7 @@ void Aura::HandleModSpellCritChance(bool apply, bool Real)
}
else
{
- m_target->m_baseSpellCritChance += apply ? GetModifierValue():-GetModifierValue();
+ m_target->m_baseSpellCritChance += apply ? m_modifier.m_amount:-m_modifier.m_amount;
}
}
@@ -4555,22 +4633,22 @@ void Aura::HandleModSpellCritChanceShool(bool /*apply*/, bool Real)
void Aura::HandleModCastingSpeed(bool apply, bool Real)
{
- m_target->ApplyCastTimePercentMod(GetModifierValue(),apply);
+ m_target->ApplyCastTimePercentMod(m_modifier.m_amount,apply);
}
void Aura::HandleModMeleeRangedSpeedPct(bool apply, bool Real)
{
- m_target->ApplyAttackTimePercentMod(BASE_ATTACK,GetModifierValue(),apply);
- m_target->ApplyAttackTimePercentMod(OFF_ATTACK,GetModifierValue(),apply);
- m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, GetModifierValue(), apply);
+ m_target->ApplyAttackTimePercentMod(BASE_ATTACK,m_modifier.m_amount,apply);
+ m_target->ApplyAttackTimePercentMod(OFF_ATTACK,m_modifier.m_amount,apply);
+ m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, m_modifier.m_amount, apply);
}
void Aura::HandleModCombatSpeedPct(bool apply, bool Real)
{
- m_target->ApplyCastTimePercentMod(GetModifierValue(),apply);
- m_target->ApplyAttackTimePercentMod(BASE_ATTACK,GetModifierValue(),apply);
- m_target->ApplyAttackTimePercentMod(OFF_ATTACK,GetModifierValue(),apply);
- m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, GetModifierValue(), apply);
+ m_target->ApplyCastTimePercentMod(m_modifier.m_amount,apply);
+ m_target->ApplyAttackTimePercentMod(BASE_ATTACK,m_modifier.m_amount,apply);
+ m_target->ApplyAttackTimePercentMod(OFF_ATTACK,m_modifier.m_amount,apply);
+ m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, m_modifier.m_amount, apply);
}
void Aura::HandleModAttackSpeed(bool apply, bool Real)
@@ -4578,26 +4656,26 @@ void Aura::HandleModAttackSpeed(bool apply, bool Real)
if(!m_target->isAlive() )
return;
- m_target->ApplyAttackTimePercentMod(BASE_ATTACK,GetModifierValue(),apply);
+ m_target->ApplyAttackTimePercentMod(BASE_ATTACK,m_modifier.m_amount,apply);
}
void Aura::HandleHaste(bool apply, bool Real)
{
- m_target->ApplyAttackTimePercentMod(BASE_ATTACK, GetModifierValue(),apply);
- m_target->ApplyAttackTimePercentMod(OFF_ATTACK, GetModifierValue(),apply);
- m_target->ApplyAttackTimePercentMod(RANGED_ATTACK,GetModifierValue(),apply);
+ m_target->ApplyAttackTimePercentMod(BASE_ATTACK, m_modifier.m_amount,apply);
+ m_target->ApplyAttackTimePercentMod(OFF_ATTACK, m_modifier.m_amount,apply);
+ m_target->ApplyAttackTimePercentMod(RANGED_ATTACK,m_modifier.m_amount,apply);
}
void Aura::HandleAuraModRangedHaste(bool apply, bool Real)
{
- m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, GetModifierValue(), apply);
+ m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, m_modifier.m_amount, apply);
}
void Aura::HandleRangedAmmoHaste(bool apply, bool Real)
{
if(m_target->GetTypeId() != TYPEID_PLAYER)
return;
- m_target->ApplyAttackTimePercentMod(RANGED_ATTACK,GetModifierValue(), apply);
+ m_target->ApplyAttackTimePercentMod(RANGED_ATTACK,m_modifier.m_amount, apply);
}
/********************************/
@@ -4606,7 +4684,7 @@ void Aura::HandleRangedAmmoHaste(bool apply, bool Real)
void Aura::HandleAuraModAttackPower(bool apply, bool Real)
{
- m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(m_modifier.m_amount), apply);
}
void Aura::HandleAuraModRangedAttackPower(bool apply, bool Real)
@@ -4614,13 +4692,13 @@ void Aura::HandleAuraModRangedAttackPower(bool apply, bool Real)
if((m_target->getClassMask() & CLASSMASK_WAND_USERS)!=0)
return;
- m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(m_modifier.m_amount), apply);
}
void Aura::HandleAuraModAttackPowerPercent(bool apply, bool Real)
{
//UNIT_FIELD_ATTACK_POWER_MULTIPLIER = multiplier - 1
- m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_PCT, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_PCT, float(m_modifier.m_amount), apply);
}
void Aura::HandleAuraModRangedAttackPowerPercent(bool apply, bool Real)
@@ -4629,7 +4707,7 @@ void Aura::HandleAuraModRangedAttackPowerPercent(bool apply, bool Real)
return;
//UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = multiplier - 1
- m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_PCT, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_PCT, float(m_modifier.m_amount), apply);
}
void Aura::HandleAuraModRangedAttackPowerOfStatPercent(bool apply, bool Real)
@@ -4638,18 +4716,20 @@ void Aura::HandleAuraModRangedAttackPowerOfStatPercent(bool apply, bool Real)
if(!Real)
return;
- if(m_target->GetTypeId() == TYPEID_PLAYER && (m_target->getClassMask() & CLASSMASK_WAND_USERS)!=0)
- return;
+ // Recalculate bonus
+ if(m_target->GetTypeId() == TYPEID_PLAYER && !(m_target->getClassMask() & CLASSMASK_WAND_USERS))
+ ((Player*)m_target)->UpdateAttackPowerAndDamage(true);
+}
- if(m_modifier.m_miscvalue != STAT_INTELLECT)
- {
- // support required adding UpdateAttackPowerAndDamage calls at stat update
- sLog.outError("Aura SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT (212) need support non-intellect stats!");
+void Aura::HandleAuraModAttackPowerOfStatPercent(bool apply, bool Real)
+{
+ // spells required only Real aura add/remove
+ if(!Real)
return;
- }
// Recalculate bonus
- ((Player*)m_target)->UpdateAttackPowerAndDamage(true);
+ if(m_target->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)m_target)->UpdateAttackPowerAndDamage(false);
}
/********************************/
@@ -4679,9 +4759,9 @@ void Aura::HandleModDamageDone(bool apply, bool Real)
// apply generic physical damage bonuses including wand case
if (GetSpellProto()->EquippedItemClass == -1 || m_target->GetTypeId() != TYPEID_PLAYER)
{
- m_target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_VALUE, float(GetModifierValue()), apply);
- m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_VALUE, float(GetModifierValue()), apply);
- m_target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_VALUE, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_VALUE, float(m_modifier.m_amount), apply);
+ m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_VALUE, float(m_modifier.m_amount), apply);
+ m_target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_VALUE, float(m_modifier.m_amount), apply);
}
else
{
@@ -4691,9 +4771,9 @@ void Aura::HandleModDamageDone(bool apply, bool Real)
if(m_target->GetTypeId() == TYPEID_PLAYER)
{
if(m_positive)
- m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS,GetModifierValue(),apply);
+ m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS,m_modifier.m_amount,apply);
else
- m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG,GetModifierValue(),apply);
+ m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG,m_modifier.m_amount,apply);
}
}
@@ -4719,7 +4799,7 @@ void Aura::HandleModDamageDone(bool apply, bool Real)
for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++)
{
if((m_modifier.m_miscvalue & (1<<i)) != 0)
- m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i,GetModifierValue(),apply);
+ m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i,m_modifier.m_amount,apply);
}
}
else
@@ -4727,7 +4807,7 @@ void Aura::HandleModDamageDone(bool apply, bool Real)
for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++)
{
if((m_modifier.m_miscvalue & (1<<i)) != 0)
- m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG+i,GetModifierValue(),apply);
+ m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG+i,m_modifier.m_amount,apply);
}
}
Pet* pet = m_target->GetPet();
@@ -4762,9 +4842,9 @@ void Aura::HandleModDamagePercentDone(bool apply, bool Real)
// apply generic physical damage bonuses including wand case
if (GetSpellProto()->EquippedItemClass == -1 || m_target->GetTypeId() != TYPEID_PLAYER)
{
- m_target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, float(GetModifierValue()), apply);
- m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(GetModifierValue()), apply);
- m_target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_PCT, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, float(m_modifier.m_amount), apply);
+ m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(m_modifier.m_amount), apply);
+ m_target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_PCT, float(m_modifier.m_amount), apply);
}
else
{
@@ -4803,7 +4883,7 @@ void Aura::HandleModOffhandDamagePercent(bool apply, bool Real)
sLog.outDebug("AURA MOD OFFHAND DAMAGE");
- m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(m_modifier.m_amount), apply);
}
/********************************/
@@ -4816,7 +4896,7 @@ void Aura::HandleModPowerCostPCT(bool apply, bool Real)
if(!Real)
return;
- float amount = GetModifierValue() /100.0f;
+ float amount = m_modifier.m_amount /100.0f;
for(int i = 0; i < MAX_SPELL_SCHOOL; ++i)
if(m_modifier.m_miscvalue & (1<<i))
m_target->ApplyModSignedFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER+i,amount,apply);
@@ -4830,13 +4910,47 @@ void Aura::HandleModPowerCost(bool apply, bool Real)
for(int i = 0; i < MAX_SPELL_SCHOOL; ++i)
if(m_modifier.m_miscvalue & (1<<i))
- m_target->ApplyModInt32Value(UNIT_FIELD_POWER_COST_MODIFIER+i,GetModifierValue(),apply);
+ m_target->ApplyModInt32Value(UNIT_FIELD_POWER_COST_MODIFIER+i,m_modifier.m_amount,apply);
+}
+
+void Aura::HandleNoReagentUseAura(bool Apply, bool Real)
+{
+ // spells required only Real aura add/remove
+ if(!Real)
+ return;
+ if(m_target->GetTypeId() != TYPEID_PLAYER)
+ return;
+ flag96 mask;
+ Unit::AuraList const& noReagent = m_target->GetAurasByType(SPELL_AURA_NO_REAGENT_USE);
+ for(Unit::AuraList::const_iterator i = noReagent.begin(); i != noReagent.end(); ++i)
+ mask |= (*i)->m_spellProto->EffectSpellClassMask[(*i)->m_effIndex];
+
+ m_target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1 , mask[0]);
+ m_target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1+1, mask[1]);
+ m_target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1+2, mask[2]);
}
/*********************************************************/
/*** OTHERS ***/
/*********************************************************/
+void Aura::HandleAuraAllowOnlyAbility(bool apply, bool Real)
+{
+ if(!Real)
+ return;
+
+ if(!apply && m_target->HasAuraType(SPELL_AURA_ALLOW_ONLY_ABILITY))
+ return;
+
+ if(m_target->GetTypeId()==TYPEID_PLAYER)
+ {
+ if (apply)
+ m_target->SetFlag(PLAYER_FLAGS, PLAYER_ALLOW_ONLY_ABILITY);
+ else
+ m_target->RemoveFlag(PLAYER_FLAGS, PLAYER_ALLOW_ONLY_ABILITY);
+ }
+}
+
void Aura::HandleShapeshiftBoosts(bool apply)
{
uint32 spellId = 0;
@@ -4851,6 +4965,7 @@ void Aura::HandleShapeshiftBoosts(bool apply)
break;
case FORM_TREE:
spellId = 5420;
+ spellId2 = 34123;
break;
case FORM_TRAVEL:
spellId = 5419;
@@ -4884,11 +4999,16 @@ void Aura::HandleShapeshiftBoosts(bool apply)
break;
case FORM_FLIGHT:
spellId = 33948;
+ spellId2 = 34764;
break;
case FORM_FLIGHT_EPIC:
spellId = 40122;
spellId2 = 40121;
break;
+ case FORM_METAMORPHOSIS:
+ spellId = 54817;
+ spellId2 = 54879;
+ break;
case FORM_SPIRITOFREDEMPTION:
spellId = 27792;
spellId2 = 27795; // must be second, this important at aura remove to prevent to early iterator invalidation.
@@ -4919,7 +5039,7 @@ void Aura::HandleShapeshiftBoosts(bool apply)
if(itr->second->state == PLAYERSPELL_REMOVED) continue;
if(itr->first==spellId || itr->first==spellId2) continue;
SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first);
- if (!spellInfo || !(spellInfo->Attributes & ((1<<6) | (1<<7)))) continue;
+ if (!spellInfo || !(spellInfo->Attributes & (SPELL_ATTR_PASSIVE | (1<<7)))) continue;
if (spellInfo->Stances & (1<<form))
m_target->CastSpell(m_target, itr->first, true, NULL, this);
}
@@ -4986,9 +5106,9 @@ void Aura::HandleAuraEmpathy(bool apply, bool Real)
void Aura::HandleAuraUntrackable(bool apply, bool Real)
{
if(apply)
- m_target->SetFlag(UNIT_FIELD_BYTES_1, PLAYER_STATE_FLAG_UNTRACKABLE);
+ m_target->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_UNTRACKABLE);
else
- m_target->RemoveFlag(UNIT_FIELD_BYTES_1, PLAYER_STATE_FLAG_UNTRACKABLE);
+ m_target->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_UNTRACKABLE);
}
void Aura::HandleAuraModPacify(bool apply, bool Real)
@@ -5051,7 +5171,21 @@ void Aura::HandleModRating(bool apply, bool Real)
for (uint32 rating = 0; rating < MAX_COMBAT_RATING; ++rating)
if (m_modifier.m_miscvalue & (1 << rating))
- ((Player*)m_target)->ApplyRatingMod(CombatRating(rating), GetModifierValue(), apply);
+ ((Player*)m_target)->ApplyRatingMod(CombatRating(rating), m_modifier.m_amount, apply);
+}
+
+void Aura::HandleModRatingFromStat(bool apply, bool Real)
+{
+ // spells required only Real aura add/remove
+ if(!Real)
+ return;
+
+ if(m_target->GetTypeId() != TYPEID_PLAYER)
+ return;
+ // Just recalculate ratings
+ for (uint32 rating = 0; rating < MAX_COMBAT_RATING; ++rating)
+ if (m_modifier.m_miscvalue & (1 << rating))
+ ((Player*)m_target)->ApplyRatingMod(CombatRating(rating), 0, apply);
}
void Aura::HandleForceMoveForward(bool apply, bool Real)
@@ -5082,11 +5216,11 @@ void Aura::HandleModTargetResistance(bool apply, bool Real)
// show armor penetration
if (m_target->GetTypeId() == TYPEID_PLAYER && (m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL))
- m_target->ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE,GetModifierValue(), apply);
+ m_target->ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE,m_modifier.m_amount, apply);
// show as spell penetration only full spell penetration bonuses (all resistances except armor and holy
if (m_target->GetTypeId() == TYPEID_PLAYER && (m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_SPELL)==SPELL_SCHOOL_MASK_SPELL)
- m_target->ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_RESISTANCE,GetModifierValue(), apply);
+ m_target->ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_RESISTANCE,m_modifier.m_amount, apply);
}
void Aura::HandleShieldBlockValue(bool apply, bool Real)
@@ -5096,7 +5230,7 @@ void Aura::HandleShieldBlockValue(bool apply, bool Real)
modType = PCT_MOD;
if(m_target->GetTypeId() == TYPEID_PLAYER)
- ((Player*)m_target)->HandleBaseModValue(SHIELD_BLOCK_VALUE, modType, float(GetModifierValue()), apply);
+ ((Player*)m_target)->HandleBaseModValue(SHIELD_BLOCK_VALUE, modType, float(m_modifier.m_amount), apply);
}
void Aura::HandleAuraRetainComboPoints(bool apply, bool Real)
@@ -5114,7 +5248,7 @@ void Aura::HandleAuraRetainComboPoints(bool apply, bool Real)
// remove only if aura expire by time (in case combo points amount change aura removed without combo points lost)
if( !apply && m_duration==0 && target->GetComboTarget())
if(Unit* unit = ObjectAccessor::GetUnit(*m_target,target->GetComboTarget()))
- target->AddComboPoints(unit, -GetModifierValue());
+ target->AddComboPoints(unit, -m_modifier.m_amount);
}
void Aura::HandleModUnattackable( bool Apply, bool Real )
@@ -5144,7 +5278,7 @@ void Aura::HandleSpiritOfRedemption( bool apply, bool Real )
// set stand state (expected in this form)
if(!m_target->IsStandState())
- m_target->SetStandState(PLAYER_STATE_NONE);
+ m_target->SetStandState(UNIT_STAND_STATE_STAND);
}
m_target->SetHealth(1);
@@ -5156,6 +5290,14 @@ void Aura::HandleSpiritOfRedemption( bool apply, bool Real )
void Aura::CleanupTriggeredSpells()
{
+ if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARRIOR && m_spellProto->SpellFamilyFlags[1] & 0x00000010 || m_spellProto->SpellFamilyFlags[0] & 0x00000020)
+ {
+ // Blood Frenzy remove
+ m_target->RemoveAurasDueToSpell(30069);
+ m_target->RemoveAurasDueToSpell(30070);
+ return;
+ }
+
uint32 tSpellId = m_spellProto->EffectTriggerSpell[GetEffIndex()];
if(!tSpellId)
return;
@@ -5175,14 +5317,6 @@ void Aura::CleanupTriggeredSpells()
m_target->RemoveAurasDueToSpell(tSpellId);
}
-void Aura::HandleAuraPowerBurn(bool apply, bool Real)
-{
- if (m_periodicTimer <= 0)
- m_periodicTimer += m_modifier.periodictime;
-
- m_isPeriodic = apply;
-}
-
void Aura::HandleSchoolAbsorb(bool apply, bool Real)
{
if(!Real)
@@ -5205,7 +5339,7 @@ void Aura::HandleSchoolAbsorb(bool apply, bool Real)
}
break;
case SPELLFAMILY_MAGE:
- if(m_spellProto->SpellFamilyFlags == 0x80100 || m_spellProto->SpellFamilyFlags == 0x8 || m_spellProto->SpellFamilyFlags == 0x100000000LL)
+ if(m_spellProto->SpellFamilyFlags.IsEqual(0x80100) || m_spellProto->SpellFamilyFlags.IsEqual(0x8) || m_spellProto->SpellFamilyFlags.IsEqual(0,0x1))
{
//frost ward, fire ward, ice barrier
//+10% from +spd bonus
@@ -5214,7 +5348,7 @@ void Aura::HandleSchoolAbsorb(bool apply, bool Real)
}
break;
case SPELLFAMILY_WARLOCK:
- if(m_spellProto->SpellFamilyFlags == 0x00)
+ if(m_spellProto->SpellFamilyFlags.IsEqual(0,0,0x40))
{
//shadow ward
//+10% from +spd bonus
@@ -5306,28 +5440,25 @@ void Aura::PeriodicTick()
CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL );
// ignore non positive values (can be result apply spellmods to aura damage
- uint32 amount = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
-
- uint32 pdamage;
+ //uint32 amount = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
+ uint32 pdamage = GetModifier()->m_amount > 0 ? GetModifier()->m_amount : 0;
if(m_modifier.m_auraname == SPELL_AURA_PERIODIC_DAMAGE)
{
- pdamage = pCaster->SpellDamageBonus(m_target,GetSpellProto(),amount,DOT);
+ pdamage = pCaster->SpellDamageBonus(m_target, GetSpellProto(), pdamage, DOT, GetStackAmount());
// Calculate armor mitigation if it is a physical spell
// But not for bleed mechanic spells
if ( GetSpellSchoolMask(GetSpellProto()) & SPELL_SCHOOL_MASK_NORMAL &&
GetEffectMechanic(GetSpellProto(), m_effIndex) != MECHANIC_BLEED)
{
- uint32 pdamageReductedArmor = pCaster->CalcArmorReducedDamage(m_target, pdamage);
+ uint32 pdamageReductedArmor = pCaster->CalcArmorReducedDamage(m_target, pdamage, GetSpellProto());
cleanDamage.damage += pdamage - pdamageReductedArmor;
pdamage = pdamageReductedArmor;
}
- //pdamage = pCaster->SpellDamageBonus(m_target,GetSpellProto(),pdamage,DOT);
-
// Curse of Agony damage-per-tick calculation
- if (GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 0x0000000000000400LL) && GetSpellProto()->SpellIconID==544)
+ if (GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags[0] & 0x400) && GetSpellProto()->SpellIconID==544)
{
// 1..4 ticks, 1/2 from normal tick damage
if (m_duration>=((m_maxduration-m_modifier.periodictime)*2/3))
@@ -5339,16 +5470,14 @@ void Aura::PeriodicTick()
}
}
else
- pdamage = uint32(m_target->GetMaxHealth()*amount/100);
+ pdamage = uint32(m_target->GetMaxHealth()*pdamage/100);
//As of 2.2 resilience reduces damage from DoT ticks as much as the chance to not be critically hit
// Reduce dot damage from resilience for players
if (m_target->GetTypeId()==TYPEID_PLAYER)
pdamage-=((Player*)m_target)->GetDotDamageReduction(pdamage);
- pdamage *= GetStackAmount();
-
- pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist);
+ pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist, m_spellProto);
sLog.outDetail("PeriodicTick: %u (TypeId: %u) attacked %u (TypeId: %u) for %u dmg inflicted by %u abs is %u",
GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId(),absorb);
@@ -5360,6 +5489,7 @@ void Aura::PeriodicTick()
data << uint32(1);
data << uint32(m_modifier.m_auraname);
data << (uint32)pdamage;
+ data << uint32(0); // overkill
data << (uint32)GetSpellSchoolMask(GetSpellProto()); // will be mask in 2.4.x
data << (uint32)absorb;
data << (uint32)resist;
@@ -5380,6 +5510,7 @@ void Aura::PeriodicTick()
break;
}
case SPELL_AURA_PERIODIC_LEECH:
+ case SPELL_AURA_PERIODIC_HEALTH_FUNNEL:
{
Unit *pCaster = GetCaster();
if(!pCaster)
@@ -5392,7 +5523,7 @@ void Aura::PeriodicTick()
pCaster->SpellHitResult(m_target,GetSpellProto(),false)!=SPELL_MISS_NONE)
return;
- // Check for immune (not use charges)
+ // Check for immune
if(m_target->IsImmunedToDamage(GetSpellSchoolMask(GetSpellProto())))
return;
@@ -5400,80 +5531,24 @@ void Aura::PeriodicTick()
uint32 resist=0;
CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL );
- uint32 pdamage = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
- pdamage = pCaster->SpellDamageBonus(m_target,GetSpellProto(),pdamage,DOT);
+ //uint32 pdamage = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
+ uint32 pdamage = GetModifier()->m_amount > 0 ? GetModifier()->m_amount : 0;
+ pdamage = pCaster->SpellDamageBonus(m_target, GetSpellProto(), pdamage, DOT, GetStackAmount());
//Calculate armor mitigation if it is a physical spell
if (GetSpellSchoolMask(GetSpellProto()) & SPELL_SCHOOL_MASK_NORMAL)
{
- uint32 pdamageReductedArmor = pCaster->CalcArmorReducedDamage(m_target, pdamage);
+ uint32 pdamageReductedArmor = pCaster->CalcArmorReducedDamage(m_target, pdamage, GetSpellProto());
cleanDamage.damage += pdamage - pdamageReductedArmor;
pdamage = pdamageReductedArmor;
}
- //pdamage = pCaster->SpellDamageBonus(m_target,GetSpellProto(),pdamage,DOT);
-
- // talent Soul Siphon add bonus to Drain Life spells
- if( GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 0x8) )
- {
- // find talent max bonus percentage
- Unit::AuraList const& mClassScriptAuras = pCaster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
- for(Unit::AuraList::const_iterator i = mClassScriptAuras.begin(); i != mClassScriptAuras.end(); ++i)
- {
- if ((*i)->GetModifier()->m_miscvalue == 4992 || (*i)->GetModifier()->m_miscvalue == 4993)
- {
- if((*i)->GetEffIndex()!=1)
- {
- sLog.outError("Expected spell %u structure change, need code update",(*i)->GetId());
- break;
- }
-
- // effect 1 m_amount
- int32 maxPercent = (*i)->GetModifier()->m_amount;
- // effect 0 m_amount
- int32 stepPercent = pCaster->CalculateSpellDamage((*i)->GetSpellProto(),0,(*i)->GetSpellProto()->EffectBasePoints[0],pCaster);
-
- // count affliction effects and calc additional damage in percentage
- int32 modPercent = 0;
- Unit::AuraMap const& victimAuras = m_target->GetAuras();
- for (Unit::AuraMap::const_iterator itr = victimAuras.begin(); itr != victimAuras.end(); ++itr)
- {
- Aura* aura = itr->second;
- if (aura->IsPositive())continue;
- SpellEntry const* m_spell = aura->GetSpellProto();
- if (m_spell->SpellFamilyName != SPELLFAMILY_WARLOCK)
- continue;
-
- SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(m_spell->Id);
- SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(m_spell->Id);
-
- for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
- {
- if(_spell_idx->second->skillId == SKILL_AFFLICTION)
- {
- modPercent += stepPercent;
- if (modPercent >= maxPercent)
- {
- modPercent = maxPercent;
- break;
- }
- }
- }
- }
- pdamage += (pdamage*modPercent/100);
- break;
- }
- }
- }
-
//As of 2.2 resilience reduces damage from DoT ticks as much as the chance to not be critically hit
// Reduce dot damage from resilience for players
if (m_target->GetTypeId()==TYPEID_PLAYER)
pdamage-=((Player*)m_target)->GetDotDamageReduction(pdamage);
- pdamage *= GetStackAmount();
-
- pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist);
+ pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist, m_spellProto);
if(m_target->GetHealth() < pdamage)
pdamage = uint32(m_target->GetHealth());
@@ -5487,6 +5562,7 @@ void Aura::PeriodicTick()
Unit* target = m_target; // aura can be deleted in DealDamage
SpellEntry const* spellProto = GetSpellProto();
float multiplier = spellProto->EffectMultipleValue[GetEffIndex()] > 0 ? spellProto->EffectMultipleValue[GetEffIndex()] : 1;
+ int32 stackAmount = GetStackAmount();
// Set trigger flag
uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC;// | PROC_FLAG_SUCCESSFUL_HARMFUL_SPELL_HIT;
@@ -5510,7 +5586,7 @@ void Aura::PeriodicTick()
if(Player *modOwner = pCaster->GetSpellModOwner())
modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_MULTIPLE_VALUE, multiplier);
- uint32 heal = pCaster->SpellHealingBonus(spellProto, uint32(new_damage * multiplier), DOT, pCaster);
+ uint32 heal = pCaster->SpellHealingBonus(pCaster, spellProto, uint32(new_damage * multiplier), DOT, stackAmount);
int32 gain = pCaster->ModifyHealth(heal);
pCaster->getHostilRefManager().threatAssist(pCaster, gain * 0.5f, spellProto);
@@ -5526,22 +5602,17 @@ void Aura::PeriodicTick()
return;
// heal for caster damage (must be alive)
- if(m_target != pCaster && GetSpellProto()->SpellVisual==163 && !pCaster->isAlive())
+ if(m_target != pCaster && GetSpellProto()->SpellVisual[0]==163 && !pCaster->isAlive())
return;
// ignore non positive values (can be result apply spellmods to aura damage
- uint32 amount = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
-
- uint32 pdamage;
+ //uint32 amount = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
+ uint32 pdamage = GetModifier()->m_amount > 0 ? GetModifier()->m_amount : 0;
if(m_modifier.m_auraname==SPELL_AURA_OBS_MOD_HEALTH)
- pdamage = uint32(m_target->GetMaxHealth() * amount/100);
+ pdamage = uint32(m_target->GetMaxHealth() * pdamage * GetStackAmount() / 100);
else
- pdamage = pCaster->SpellHealingBonus(GetSpellProto(), amount, DOT, m_target);
-
- pdamage *= GetStackAmount();
-
- //pdamage = pCaster->SpellHealingBonus(GetSpellProto(), pdamage, DOT, m_target);
+ pdamage = pCaster->SpellHealingBonus(m_target, GetSpellProto(), pdamage, DOT, GetStackAmount());
sLog.outDetail("PeriodicTick: %u (TypeId: %u) heal of %u (TypeId: %u) for %u health inflicted by %u",
GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId());
@@ -5553,6 +5624,7 @@ void Aura::PeriodicTick()
data << uint32(1);
data << uint32(m_modifier.m_auraname);
data << (uint32)pdamage;
+ data << uint32(0); // wotlk
m_target->SendMessageToSet(&data,true);
int32 gain = m_target->ModifyHealth(pdamage);
@@ -5572,7 +5644,7 @@ void Aura::PeriodicTick()
bool haveCastItem = GetCastItemGUID()!=0;
// heal for caster damage
- if(m_target!=pCaster && spellProto->SpellVisual==163)
+ if(m_target!=pCaster && spellProto->SpellVisual[0]==163)
{
uint32 dmg = spellProto->manaPerSecond;
if(pCaster->GetHealth() <= dmg && pCaster->GetTypeId()==TYPEID_PLAYER)
@@ -5624,12 +5696,12 @@ void Aura::PeriodicTick()
return;
// ignore non positive values (can be result apply spellmods to aura damage
- uint32 pdamage = GetModifierValue() > 0 ? GetModifierValue() : 0;
+ uint32 pdamage = m_modifier.m_amount > 0 ? m_modifier.m_amount : 0;
sLog.outDetail("PeriodicTick: %u (TypeId: %u) power leech of %u (TypeId: %u) for %u dmg inflicted by %u",
GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId());
- if(m_modifier.m_miscvalue < 0 || m_modifier.m_miscvalue > 4)
+ if(m_modifier.m_miscvalue < 0 || m_modifier.m_miscvalue >= MAX_POWERS)
break;
Powers power = Powers(m_modifier.m_miscvalue);
@@ -5686,12 +5758,12 @@ void Aura::PeriodicTick()
case SPELL_AURA_PERIODIC_ENERGIZE:
{
// ignore non positive values (can be result apply spellmods to aura damage
- uint32 pdamage = GetModifierValue() > 0 ? GetModifierValue() : 0;
+ uint32 pdamage = m_modifier.m_amount > 0 ? m_modifier.m_amount : 0;
sLog.outDetail("PeriodicTick: %u (TypeId: %u) energize %u (TypeId: %u) for %u dmg inflicted by %u",
GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId());
- if(m_modifier.m_miscvalue < 0 || m_modifier.m_miscvalue > 4)
+ if(m_modifier.m_miscvalue < 0 || m_modifier.m_miscvalue >= MAX_POWERS)
break;
Powers power = Powers(m_modifier.m_miscvalue);
@@ -5718,7 +5790,7 @@ void Aura::PeriodicTick()
case SPELL_AURA_OBS_MOD_MANA:
{
// ignore non positive values (can be result apply spellmods to aura damage
- uint32 amount = GetModifierValue() > 0 ? GetModifierValue() : 0;
+ uint32 amount = m_modifier.m_amount > 0 ? m_modifier.m_amount : 0;
uint32 pdamage = uint32(m_target->GetMaxPower(POWER_MANA) * amount/100);
@@ -5754,7 +5826,7 @@ void Aura::PeriodicTick()
if(m_target->IsImmunedToDamage(GetSpellSchoolMask(GetSpellProto())))
return;
- int32 pdamage = GetModifierValue() > 0 ? GetModifierValue() : 0;
+ int32 pdamage = m_modifier.m_amount > 0 ? m_modifier.m_amount : 0;
Powers powerType = Powers(m_modifier.m_miscvalue);
@@ -5788,12 +5860,51 @@ void Aura::PeriodicTick()
pCaster->DealSpellDamage(&damageInfo, true);
break;
}
+ case SPELL_AURA_MOD_REGEN:
+ {
+ int32 gain = m_target->ModifyHealth(m_modifier.m_amount);
+ if (Unit *caster = GetCaster())
+ m_target->getHostilRefManager().threatAssist(caster, float(gain) * 0.5f, GetSpellProto());
+ break;
+ }
+ case SPELL_AURA_MOD_POWER_REGEN:
+ {
+ Powers pt = m_target->getPowerType();
+ if(int32(pt) != m_modifier.m_miscvalue)
+ return;
+
+ if ( GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED )
+ {
+ // eating anim
+ m_target->HandleEmoteCommand(EMOTE_ONESHOT_EAT);
+ }
+ else if( GetId() == 20577 )
+ {
+ // cannibalize anim
+ m_target->HandleEmoteCommand(EMOTE_STATE_CANNIBALIZE);
+ }
+
+ // Warrior talent, gain 1 rage every 3 seconds while in combat
+ if(pt == POWER_RAGE && m_target->isInCombat())
+ m_target->ModifyPower(pt, m_modifier.m_amount*10/17);
+ break;
+ }
// Here tick dummy auras
case SPELL_AURA_PERIODIC_DUMMY:
{
PeriodicDummyTick();
break;
}
+ case SPELL_AURA_PERIODIC_TRIGGER_SPELL:
+ {
+ TriggerSpell();
+ break;
+ }
+ case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE:
+ {
+ TriggerSpellWithValue();
+ break;
+ }
default:
break;
}
@@ -5801,114 +5912,77 @@ void Aura::PeriodicTick()
void Aura::PeriodicDummyTick()
{
+ Unit *caster = GetCaster();
SpellEntry const* spell = GetSpellProto();
- switch (spell->Id)
- {
- // Drink
- case 430:
- case 431:
- case 432:
- case 1133:
- case 1135:
- case 1137:
- case 10250:
- case 22734:
- case 27089:
- case 34291:
- case 43706:
- case 46755:
+ switch (spell->SpellFamilyName)
+ {
+ case SPELLFAMILY_GENERIC:
+ switch (spell->Id)
{
- if (m_target->GetTypeId() != TYPEID_PLAYER)
- return;
- // Search SPELL_AURA_MOD_POWER_REGEN aura for this spell and add bonus
- Unit::AuraList const& aura = m_target->GetAurasByType(SPELL_AURA_MOD_POWER_REGEN);
- for(Unit::AuraList::const_iterator i = aura.begin(); i != aura.end(); ++i)
+ // Drink
+ case 430:
+ case 431:
+ case 432:
+ case 1133:
+ case 1135:
+ case 1137:
+ case 10250:
+ case 22734:
+ case 27089:
+ case 34291:
+ case 43706:
+ case 46755:
+ case 49472: // Drink Coffee
+ case 61830:
{
- if ((*i)->GetId() == GetId())
+ if (m_target->GetTypeId() != TYPEID_PLAYER)
+ return;
+ // Search SPELL_AURA_MOD_POWER_REGEN aura for this spell and add bonus
+ Unit::AuraList const& aura = m_target->GetAurasByType(SPELL_AURA_MOD_POWER_REGEN);
+ for(Unit::AuraList::const_iterator i = aura.begin(); i != aura.end(); ++i)
{
- // Get tick number
- int32 tick = (m_maxduration - m_duration) / m_modifier.periodictime;
- // Default case (not on arenas)
- if (tick == 0)
+ if ((*i)->GetId() == GetId())
{
(*i)->GetModifier()->m_amount = m_modifier.m_amount;
((Player*)m_target)->UpdateManaRegen();
// Disable continue
m_isPeriodic = false;
- }
- return;
- //**********************************************
- // Code commended since arena patch not added
- // This feature uses only in arenas
- //**********************************************
- // Here need increase mana regen per tick (6 second rule)
- // on 0 tick - 0 (handled in 2 second)
- // on 1 tick - 166% (handled in 4 second)
- // on 2 tick - 133% (handled in 6 second)
- // Not need update after 3 tick
- /*
- if (tick > 3)
return;
- // Apply bonus for 0 - 3 tick
- switch (tick)
- {
- case 0: // 0%
- (*i)->GetModifier()->m_amount = m_modifier.m_amount = 0;
- break;
- case 1: // 166%
- (*i)->GetModifier()->m_amount = m_modifier.m_amount * 5 / 3;
- break;
- case 2: // 133%
- (*i)->GetModifier()->m_amount = m_modifier.m_amount * 4 / 3;
- break;
- default: // 100% - normal regen
- (*i)->GetModifier()->m_amount = m_modifier.m_amount;
- break;
}
- ((Player*)m_target)->UpdateManaRegen();
- return;*/
}
+ return;
+ }
+ // Forsaken Skills
+ case 7054:
+ {
+ // Possibly need cast one of them (but
+ // 7038 Forsaken Skill: Swords
+ // 7039 Forsaken Skill: Axes
+ // 7040 Forsaken Skill: Daggers
+ // 7041 Forsaken Skill: Maces
+ // 7042 Forsaken Skill: Staves
+ // 7043 Forsaken Skill: Bows
+ // 7044 Forsaken Skill: Guns
+ // 7045 Forsaken Skill: 2H Axes
+ // 7046 Forsaken Skill: 2H Maces
+ // 7047 Forsaken Skill: 2H Swords
+ // 7048 Forsaken Skill: Defense
+ // 7049 Forsaken Skill: Fire
+ // 7050 Forsaken Skill: Frost
+ // 7051 Forsaken Skill: Holy
+ // 7053 Forsaken Skill: Shadow
+ return;
}
- return;
- }
// // Panda
// case 19230: break;
-// // Master of Subtlety
-// case 31666: break;
// // Gossip NPC Periodic - Talk
// case 33208: break;
// // Gossip NPC Periodic - Despawn
// case 33209: break;
-// // Force of Nature
-// case 33831: break;
- // Aspect of the Viper
- case 34074:
- {
- if (m_target->GetTypeId() != TYPEID_PLAYER)
- return;
- // Should be manauser
- if (m_target->getPowerType()!=POWER_MANA)
- return;
- Unit *caster = GetCaster();
- if (!caster)
- return;
- // Regen amount is max (100% from spell) on 21% or less mana and min on 92.5% or greater mana (20% from spell)
- int mana = m_target->GetPower(POWER_MANA);
- int max_mana = m_target->GetMaxPower(POWER_MANA);
- int32 base_regen = caster->CalculateSpellDamage(m_spellProto, m_effIndex, m_currentBasePoints, m_target);
- float regen_pct = 1.20f - 1.1f * mana / max_mana;
- if (regen_pct > 1.0f) regen_pct = 1.0f;
- else if (regen_pct < 0.2f) regen_pct = 0.2f;
- m_modifier.m_amount = int32 (base_regen * regen_pct);
- ((Player*)m_target)->UpdateManaRegen();
- return;
- }
// // Steal Weapon
// case 36207: break;
// // Simon Game START timer, (DND)
// case 39993: break;
-// // Harpooner's Mark
-// case 40084: break;
// // Knockdown Fel Cannon: break; The Aggro Burst
// case 40119: break;
// // Old Mount Spell
@@ -5921,6 +5995,8 @@ void Aura::PeriodicDummyTick()
// case 40846: break;
// // Copy Weapon
// case 41054: break;
+// // Dementia
+// case 41404: break;
// // Ethereal Ring Visual, Lightning Aura
// case 41477: break;
// // Ethereal Ring Visual, Lightning Aura (Fork)
@@ -5969,6 +6045,8 @@ void Aura::PeriodicDummyTick()
// case 43310: break;
// // Headless Horseman - Maniacal Laugh, Maniacal, Delayed 17
// case 43884: break;
+// // Wretched!
+// case 43963: break;
// // Headless Horseman - Maniacal Laugh, Maniacal, other, Delayed 17
// case 44000: break;
// // Energy Feedback
@@ -6035,14 +6113,190 @@ void Aura::PeriodicDummyTick()
// case 47407: break;
// // Mole Machine Port Schedule
// case 47489: break;
+// case 47941: break; // Crystal Spike
+// case 48200: break; // Healer Aura
+// case 48630: break; // Summon Gauntlet Mobs Periodic
+// case 49313: break; // Proximity Mine Area Aura
// // Mole Machine Portal Schedule
// case 49466: break;
-// // Drink Coffee
-// case 49472: break;
+// case 49555: break; // Corpse Explode
+// case 49592: break; // Temporal Rift
+// case 49957: break; // Cutting Laser
+// case 50085: break; // Slow Fall
// // Listening to Music
// case 50493: break;
// // Love Rocket Barrage
// case 50530: break;
+// Exist more after, need add later
+ default:
+ break;
+ }
+ break;
+ case SPELLFAMILY_MAGE:
+ {
+ // Mirror Image
+// if (spell->Id == 55342)
+// return;
+ break;
+ }
+ case SPELLFAMILY_WARRIOR:
+ {
+ // Armored to the Teeth
+ if (spell->SpellIconID == 3516)
+ {
+ // Increases your attack power by $s1 for every $s2 armor value you have.
+ // Calculate AP bonus (from 1 efect of this spell)
+ int32 apBonus = m_modifier.m_amount * m_target->GetArmor() / m_target->CalculateSpellDamage(spell, 1, spell->EffectBasePoints[1], m_target);
+ m_target->CastCustomSpell(m_target, 61217, &apBonus, &apBonus, 0, true, 0, this);
+ return;
+ }
+ break;
+ }
+ case SPELLFAMILY_DRUID:
+ {
+ switch (spell->Id)
+ {
+ // Frenzied Regeneration
+ case 22842:
+ {
+ // Converts up to 10 rage per second into health for $d. Each point of rage is converted into ${$m2/10}.1% of max health.
+ // Should be manauser
+ if (m_target->getPowerType()!=POWER_RAGE)
+ return;
+ uint32 rage = m_target->GetPower(POWER_RAGE);
+ // Nothing todo
+ if (rage == 0)
+ return;
+ int32 mod = (rage < 100) ? rage : 100;
+ int32 points = m_target->CalculateSpellDamage(spell, 1, spell->EffectBasePoints[1], m_target);
+ int32 regen = m_target->GetMaxHealth() * (mod * points / 10) / 1000;
+ m_target->CastCustomSpell(m_target, 22845, &regen, 0, 0, true, 0, this);
+ m_target->SetPower(POWER_RAGE, rage-mod);
+ return;
+ }
+ // Force of Nature
+ case 33831:
+ return;
+ default:
+ break;
+ }
+ break;
+ }
+ case SPELLFAMILY_ROGUE:
+ {
+// switch (spell->Id)
+// {
+ // Master of Subtlety
+// case 31666: break;
+ // Killing Spree
+// case 51690: break;
+ // Overkill
+// case 58428: break;
+// default:
+// break;
+// }
+ break;
+ }
+ case SPELLFAMILY_HUNTER:
+ {
+ // Explosive Shot
+ if (spell->SpellFamilyFlags[1] & 0x80000000)
+ {
+ if (!caster)
+ return;
+ int32 damage = m_modifier.m_amount;
+ // Full damage to target at 0 tick
+ if (m_duration > m_modifier.periodictime)
+ {
+ caster->CastCustomSpell(m_target, 53352, &damage, 0, 0, true, 0, this);
+ return;
+ }
+ damage/=4;
+ caster->CastCustomSpell(m_target, 56298, &damage, 0, 0, true, 0, this);
+ return;
+ }
+ switch (spell->Id)
+ {
+ // Harpooner's Mark
+ // case 40084:
+ // return;
+ // Feeding Frenzy Rank 1
+ case 53511:
+ if ( m_target->GetHealth() * 100 < m_target->GetMaxHealth() * 35 )
+ m_target->CastSpell(m_target, 60096, true, 0, this);
+ return;
+ // Feeding Frenzy Rank 2
+ case 53512:
+ if ( m_target->GetHealth() * 100 < m_target->GetMaxHealth() * 35 )
+ m_target->CastSpell(m_target, 60097, true, 0, this);
+ return;
+ default:
+ break;
+ }
+ break;
+ }
+ case SPELLFAMILY_SHAMAN:
+ {
+ // Astral Shift
+ if (spell->Id == 52179)
+ {
+ // Periodic need for remove visual on stun/fear/silence lost
+ if (!(m_target->GetUInt32Value(UNIT_FIELD_FLAGS)&(UNIT_FLAG_STUNNED|UNIT_FLAG_FLEEING|UNIT_FLAG_SILENCED)))
+ m_target->RemoveAurasDueToSpell(52179);
+ return;
+ }
+ break;
+ }
+ case SPELLFAMILY_DEATHKNIGHT:
+ {
+ // Death and Decay
+ if (spell->SpellFamilyFlags[0] & 0x20)
+ {
+ if (caster)
+ caster->CastCustomSpell(m_target, 52212, &m_modifier.m_amount, NULL, NULL, true, 0, this);
+ return;
+ }
+ // Raise Dead
+// if (spell->SpellFamilyFlags & 0x0000000000001000LL)
+// return;
+ // Chains of Ice
+ if (spell->SpellFamilyFlags[1] & 0x00004000)
+ {
+ // Get 0 effect aura
+ Aura *slow = m_target->GetAura(GetId(), 0);
+ if (slow)
+ {
+ slow->ApplyModifier(false, true);
+ Modifier *mod = slow->GetModifier();
+ mod->m_amount+= m_modifier.m_amount;
+ if (mod->m_amount > 0) mod->m_amount = 0;
+ slow->ApplyModifier(true, true);
+ }
+ return;
+ }
+ // Summon Gargoyle
+// if (spell->SpellFamilyFlags & 0x0000008000000000LL)
+// return;
+ // Death Rune Mastery
+// if (spell->SpellFamilyFlags & 0x0000000000004000LL)
+// return;
+ // Bladed Armor
+ if (spell->SpellIconID == 2653)
+ {
+ // Increases your attack power by $s1 for every $s2 armor value you have.
+ // Calculate AP bonus (from 1 efect of this spell)
+ int32 apBonus = m_modifier.m_amount * m_target->GetArmor() / m_target->CalculateSpellDamage(spell, 1, spell->EffectBasePoints[1], m_target);
+ m_target->CastCustomSpell(m_target, 61217, &apBonus, &apBonus, 0, true, 0, this);
+ return;
+ }
+ // Reaping
+// if (spell->SpellIconID == 22)
+// return;
+ // Blood of the North
+// if (spell->SpellIconID == 30412)
+// return;
+ break;
+ }
default:
break;
}
@@ -6078,7 +6332,7 @@ void Aura::HandleManaShield(bool apply, bool Real)
switch(m_spellProto->SpellFamilyName)
{
case SPELLFAMILY_MAGE:
- if(m_spellProto->SpellFamilyFlags & 0x8000)
+ if(m_spellProto->SpellFamilyFlags[0] & 0x8000)
{
// Mana Shield
// +50% from +spd bonus
@@ -6107,3 +6361,157 @@ void Aura::HandleArenaPreparation(bool apply, bool Real)
else
m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION);
}
+
+void Aura::HandleAuraControlVehicle(bool apply, bool Real)
+{
+ if(!Real)
+ return;
+
+ if(m_target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ if(Pet *pet = m_target->GetPet())
+ pet->Remove(PET_SAVE_AS_CURRENT);
+
+ WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0);
+ ((Player*)m_target)->GetSession()->SendPacket(&data);
+}
+
+void Aura::HandleAuraConvertRune(bool apply, bool Real)
+{
+ if(!Real)
+ return;
+
+ if(m_target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ Player *plr = (Player*)m_target;
+
+ if(plr->getClass() != CLASS_DEATH_KNIGHT)
+ return;
+
+ // how to determine what rune need to be converted?
+ for(uint32 i = 0; i < MAX_RUNES; ++i)
+ {
+ if(apply)
+ {
+ if(!plr->GetRuneCooldown(i))
+ {
+ plr->ConvertRune(i, GetSpellProto()->EffectMiscValueB[m_effIndex]);
+ break;
+ }
+ }
+ else
+ {
+ if(plr->GetCurrentRune(i) == GetSpellProto()->EffectMiscValueB[m_effIndex])
+ {
+ plr->ConvertRune(i, plr->GetBaseRune(i));
+ break;
+ }
+ }
+ }
+}
+
+void Aura::HandleModPossess(bool apply, bool Real)
+{
+ if(!Real)
+ return;
+
+ Unit* caster = GetCaster();
+ if(caster && caster->GetTypeId() == TYPEID_UNIT)
+ {
+ HandleModCharm(apply, Real);
+ return;
+ }
+
+ if(apply)
+ {
+ if(m_target->getLevel() > m_modifier.m_amount)
+ return;
+
+ m_target->SetCharmedOrPossessedBy(caster, true);
+ }
+ else
+ m_target->RemoveCharmedOrPossessedBy(caster);
+}
+
+void Aura::HandleModPossessPet(bool apply, bool Real)
+{
+ if(!Real)
+ return;
+
+ Unit* caster = GetCaster();
+ if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
+ return;
+ if(caster->GetPet() != m_target)
+ return;
+
+ if(apply)
+ m_target->SetCharmedOrPossessedBy(caster, true);
+ else
+ {
+ m_target->RemoveCharmedOrPossessedBy(caster);
+
+ // Reinitialize the pet bar and make the pet come back to the owner
+ ((Player*)caster)->PetSpellInitialize();
+ if(!m_target->getVictim())
+ {
+ m_target->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
+ m_target->GetCharmInfo()->SetCommandState(COMMAND_FOLLOW);
+ }
+ }
+}
+
+void Aura::HandleModCharm(bool apply, bool Real)
+{
+ if(!Real)
+ return;
+
+ Unit* caster = GetCaster();
+
+ if(apply)
+ {
+ if(int32(m_target->getLevel()) > m_modifier.m_amount)
+ return;
+
+ m_target->SetCharmedOrPossessedBy(caster, false);
+ }
+ else
+ m_target->RemoveCharmedOrPossessedBy(caster);
+}
+
+void Aura::HandlePhase(bool apply, bool Real)
+{
+ if(!Real)
+ return;
+
+ // always non stackable
+ if(apply)
+ {
+ Unit::AuraList const& phases = m_target->GetAurasByType(SPELL_AURA_PHASE);
+ if(!phases.empty())
+ m_target->RemoveAurasDueToSpell(phases.front()->GetId(),this);
+ }
+
+ // no-phase is also phase state so same code for apply and remove
+
+ // phase auras normally not expected at BG but anyway better check
+ if(m_target->GetTypeId()==TYPEID_PLAYER)
+ {
+ // drop flag at invisible in bg
+ if(((Player*)m_target)->InBattleGround())
+ if(BattleGround *bg = ((Player*)m_target)->GetBattleGround())
+ bg->EventPlayerDroppedFlag((Player*)m_target);
+
+ // GM-mode have mask 0xFFFFFFFF
+ if(!((Player*)m_target)->isGameMaster())
+ m_target->SetPhaseMask(apply ? GetMiscValue() : PHASEMASK_NORMAL,false);
+ }
+ else
+ m_target->SetPhaseMask(apply ? GetMiscValue() : PHASEMASK_NORMAL,false);
+
+ // need triggering visibility update base at phase update of not GM invisible (other GMs anyway see in any phases)
+ if(m_target->GetVisibility()!=VISIBILITY_OFF)
+ m_target->SetVisibility(m_target->GetVisibility());
+}
+
diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h
index 4912548d5b3..c09feca92b9 100644
--- a/src/game/SpellAuras.h
+++ b/src/game/SpellAuras.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -22,15 +22,6 @@
#include "SpellAuraDefines.h"
-struct DamageManaShield
-{
- uint32 m_spellId;
- uint32 m_modType;
- int32 m_schoolType;
- uint32 m_totalAbsorb;
- uint32 m_currAbsorb;
-};
-
struct Modifier
{
AuraType m_auraname;
@@ -100,6 +91,7 @@ class TRINITY_DLL_SPEC Aura
void HandleAuraFeatherFall(bool Apply, bool Real);
void HandleAuraHover(bool Apply, bool Real);
void HandleAddModifier(bool Apply, bool Real);
+ void HandleAddTargetTrigger(bool Apply, bool Real);
void HandleAuraModStun(bool Apply, bool Real);
void HandleModDamageDone(bool Apply, bool Real);
void HandleAuraUntrackable(bool Apply, bool Real);
@@ -111,8 +103,10 @@ class TRINITY_DLL_SPEC Aura
void HandleAuraModRegenInterrupt(bool Apply, bool Real);
void HandleHaste(bool Apply, bool Real);
void HandlePeriodicTriggerSpell(bool Apply, bool Real);
+ void HandlePeriodicTriggerSpellWithValue(bool apply, bool Real);
void HandlePeriodicEnergize(bool Apply, bool Real);
void HandleAuraModResistanceExclusive(bool Apply, bool Real);
+ void HandleAuraModPetTalentsPoints(bool Apply, bool Real);
void HandleModStealth(bool Apply, bool Real);
void HandleInvisibility(bool Apply, bool Real);
void HandleInvisibilityDetect(bool Apply, bool Real);
@@ -147,6 +141,7 @@ class TRINITY_DLL_SPEC Aura
void HandleModSpellHitChance(bool Apply, bool Real);
void HandleAuraModScale(bool Apply, bool Real);
void HandlePeriodicManaLeech(bool Apply, bool Real);
+ void HandlePeriodicHealthFunnel(bool apply, bool Real);
void HandleModCastingSpeed(bool Apply, bool Real);
void HandleAuraMounted(bool Apply, bool Real);
void HandleWaterBreathing(bool Apply, bool Real);
@@ -184,10 +179,12 @@ class TRINITY_DLL_SPEC Aura
void HandleAuraGhost(bool Apply, bool Real);
void HandleAuraAllowFlight(bool Apply, bool Real);
void HandleModRating(bool apply, bool Real);
+ void HandleModRatingFromStat(bool apply, bool Real);
void HandleModTargetResistance(bool apply, bool Real);
void HandleAuraModAttackPowerPercent(bool apply, bool Real);
void HandleAuraModRangedAttackPowerPercent(bool apply, bool Real);
void HandleAuraModRangedAttackPowerOfStatPercent(bool apply, bool Real);
+ void HandleAuraModAttackPowerOfStatPercent(bool apply, bool Real);
void HandleSpiritOfRedemption(bool apply, bool Real);
void HandleModManaRegen(bool apply, bool Real);
void HandleComprehendLanguage(bool apply, bool Real);
@@ -197,6 +194,7 @@ class TRINITY_DLL_SPEC Aura
void HandleModSpellDamagePercentFromStat(bool apply, bool Real);
void HandleModSpellHealingPercentFromStat(bool apply, bool Real);
void HandleAuraModDispelResist(bool apply, bool Real);
+ void HandleAuraControlVehicle(bool apply, bool Real);
void HandleModSpellDamagePercentFromAttackPower(bool apply, bool Real);
void HandleModSpellHealingPercentFromAttackPower(bool apply, bool Real);
void HandleAuraModPacifyAndSilence(bool Apply, bool Real);
@@ -209,13 +207,15 @@ class TRINITY_DLL_SPEC Aura
void HandlePreventFleeing(bool apply, bool Real);
void HandleManaShield(bool apply, bool Real);
void HandleArenaPreparation(bool apply, bool Real);
+ void HandleAuraConvertRune(bool apply, bool Real);
+ void HandleAuraIncreaseBaseHealthPercent(bool Apply, bool Real);
+ void HandleNoReagentUseAura(bool Apply, bool Real);
+ void HandlePhase(bool Apply, bool Real);
virtual ~Aura();
void SetModifier(AuraType t, int32 a, uint32 pt, int32 miscValue);
Modifier* GetModifier() {return &m_modifier;}
- int32 GetModifierValuePerStack() {return m_modifier.m_amount;}
- int32 GetModifierValue() {return m_modifier.m_amount * m_stackAmount;}
int32 GetMiscValue() {return m_spellProto->EffectMiscValue[m_effIndex];}
int32 GetMiscBValue() {return m_spellProto->EffectMiscValueB[m_effIndex];}
@@ -229,10 +229,15 @@ class TRINITY_DLL_SPEC Aura
void SetAuraMaxDuration(int32 duration) { m_maxduration = duration; }
int32 GetAuraDuration() const { return m_duration; }
void SetAuraDuration(int32 duration) { m_duration = duration; }
+ void SetAuraDurationAndUpdate(int32 duration)
+ {
+ m_duration = duration;
+ if(GetAuraSlot() < MAX_AURAS) // slot found send data to client
+ { m_target->UpdateAuraForGroup(GetAuraSlot()); }
+ }
time_t GetAuraApplyTime() { return m_applyTime; }
- void UpdateAuraDuration();
- void SendAuraDurationForCaster(Player* caster);
- void UpdateSlotCounterAndDuration();
+
+ SpellModifier *getAuraSpellMod() {return m_spellmod; }
uint64 const& GetCasterGUID() const { return m_caster_guid; }
Unit* GetCaster() const;
@@ -249,14 +254,30 @@ class TRINITY_DLL_SPEC Aura
uint8 GetAuraSlot() const { return m_auraSlot; }
void SetAuraSlot(uint8 slot) { m_auraSlot = slot; }
- void UpdateAuraCharges()
+ uint8 GetAuraCharges() const { return m_procCharges; }
+ void SetAuraCharges(uint8 charges)
{
- uint8 slot = GetAuraSlot();
-
- // only aura in slot with charges and without stack limitation
- if (slot < MAX_AURAS && m_procCharges >= 1 && GetSpellProto()->StackAmount==0)
- SetAuraApplication(slot, m_procCharges - 1);
+ if (m_procCharges == charges)
+ return;
+ m_procCharges = charges;
+ if(GetAuraSlot() < MAX_AURAS) // slot found send data to client
+ { m_target->UpdateAuraForGroup(GetAuraSlot()); }
}
+ bool DropAuraCharge() // return true if last charge dropped
+ {
+ if (m_procCharges == 0)
+ return false;
+ m_procCharges--;
+ if(GetAuraSlot() < MAX_AURAS) // slot found send data to client
+ { m_target->UpdateAuraForGroup(GetAuraSlot()); }
+ return m_procCharges == 0;
+ }
+
+ int8 GetStackAmount() {return m_stackAmount;}
+ //int32 GetModifierValuePerStack() {return m_modifier.m_amount / m_stackAmount;}
+ void SetStackAmount(uint8 num);
+ bool modStackAmount(int32 num); // return true if last charge dropped
+ void RefreshAura();
bool IsPositive() { return m_positive; }
void SetNegative() { m_positive = false; }
@@ -265,7 +286,6 @@ class TRINITY_DLL_SPEC Aura
bool IsPermanent() const { return m_permanent; }
bool IsAreaAura() const { return m_isAreaAura; }
bool IsPeriodic() const { return m_isPeriodic; }
- bool IsTrigger() const { return m_isTrigger; }
bool IsPassive() const { return m_isPassive; }
bool IsPersistent() const { return m_isPersistent; }
bool IsDeathPersistent() const { return m_isDeathPersist; }
@@ -278,72 +298,67 @@ class TRINITY_DLL_SPEC Aura
void _AddAura();
void _RemoveAura();
- void TriggerSpell();
-
bool IsUpdated() { return m_updated; }
void SetUpdated(bool val) { m_updated = val; }
void SetRemoveMode(AuraRemoveMode mode) { m_removeMode = mode; }
- int32 m_procCharges;
- void SetAuraProcCharges(int32 charges) { m_procCharges = charges; }
-
Unit* GetTriggerTarget() const;
// add/remove SPELL_AURA_MOD_SHAPESHIFT (36) linked auras
+ void HandleAuraAllowOnlyAbility(bool apply, bool Real);
void HandleShapeshiftBoosts(bool apply);
// Allow Apply Aura Handler to modify and access m_AuraDRGroup
void setDiminishGroup(DiminishingGroup group) { m_AuraDRGroup = group; }
DiminishingGroup getDiminishGroup() const { return m_AuraDRGroup; }
+ void TriggerSpell();
+ void TriggerSpellWithValue();
void PeriodicTick();
void PeriodicDummyTick();
- int32 GetStackAmount() {return m_stackAmount;}
- void SetStackAmount(int32 amount) {m_stackAmount=amount;}
+ bool isAffectedOnSpell(SpellEntry const *spell) const;
protected:
Aura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster = NULL, Item* castItem = NULL);
Modifier m_modifier;
SpellModifier *m_spellmod;
- uint32 m_effIndex;
+
SpellEntry const *m_spellProto;
- int32 m_currentBasePoints; // cache SpellEntry::EffectBasePoints and use for set custom base points
- uint64 m_caster_guid;
Unit* m_target;
- int32 m_maxduration;
- int32 m_duration;
- int32 m_timeCla;
+ uint64 m_caster_guid;
uint64 m_castItemGuid; // it is NOT safe to keep a pointer to the item because it may get deleted
time_t m_applyTime;
- AuraRemoveMode m_removeMode;
+ int32 m_currentBasePoints; // cache SpellEntry::EffectBasePoints and use for set custom base points
+ int32 m_maxduration; // Max aura duration
+ int32 m_duration; // Current time
+ int32 m_timeCla; // Timer for power per sec calcultion
+ int32 m_periodicTimer; // Timer for periodic auras
- uint8 m_auraSlot;
+ AuraRemoveMode m_removeMode:8; // Store info for know remove aura reason
+ DiminishingGroup m_AuraDRGroup:8; // Diminishing
+
+ uint8 m_effIndex; // Aura effect index in spell
+ uint8 m_auraSlot; // Aura slot on unit (for show in client)
+ uint8 m_auraFlags; // Aura info flag (for send data to client)
+ uint8 m_auraLevel; // Aura level (store caster level for correct show level dep amount)
+ uint8 m_procCharges; // Aura charges (0 for infinite)
+ uint8 m_stackAmount; // Aura stack amount
bool m_positive:1;
bool m_permanent:1;
bool m_isPeriodic:1;
- bool m_isTrigger:1;
bool m_isAreaAura:1;
bool m_isPassive:1;
bool m_isPersistent:1;
bool m_isDeathPersist:1;
bool m_isRemovedOnShapeLost:1;
- bool m_updated:1;
+ bool m_updated:1; // Prevent remove aura by stack if set
bool m_in_use:1; // true while in Aura::ApplyModifier call
- int32 m_periodicTimer;
- uint32 m_PeriodicEventId;
- DiminishingGroup m_AuraDRGroup;
-
- int32 m_stackAmount;
private:
void CleanupTriggeredSpells();
- void SetAura(uint32 slot, bool remove) { m_target->SetUInt32Value(UNIT_FIELD_AURA + slot, remove ? 0 : GetId()); }
- void SetAuraFlag(uint32 slot, bool add);
- void SetAuraLevel(uint32 slot, uint32 level);
- void SetAuraApplication(uint32 slot, int8 count);
};
class TRINITY_DLL_SPEC AreaAura : public Aura
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index 07e5d4afef9..545d03ee76e 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -47,6 +47,7 @@
#include "Creature.h"
#include "Totem.h"
#include "CreatureAI.h"
+#include "BattleGroundMgr.h"
#include "BattleGround.h"
#include "BattleGroundEY.h"
#include "BattleGroundWS.h"
@@ -60,6 +61,7 @@
#include "CellImpl.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
+#include "SkillDiscovery.h"
pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
{
@@ -104,8 +106,8 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
&Spell::EffectDispel, // 38 SPELL_EFFECT_DISPEL
&Spell::EffectUnused, // 39 SPELL_EFFECT_LANGUAGE
&Spell::EffectDualWield, // 40 SPELL_EFFECT_DUAL_WIELD
- &Spell::EffectSummonWild, // 41 SPELL_EFFECT_SUMMON_WILD
- &Spell::EffectSummonGuardian, // 42 SPELL_EFFECT_SUMMON_GUARDIAN
+ &Spell::EffectUnused, // 41 SPELL_EFFECT_JUMP
+ &Spell::EffectUnused, // 42 SPELL_EFFECT_JUMP2
&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
@@ -128,16 +130,16 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
&Spell::EffectPowerBurn, // 62 SPELL_EFFECT_POWER_BURN
&Spell::EffectThreat, // 63 SPELL_EFFECT_THREAT
&Spell::EffectTriggerSpell, // 64 SPELL_EFFECT_TRIGGER_SPELL
- &Spell::EffectUnused, // 65 SPELL_EFFECT_HEALTH_FUNNEL unused
- &Spell::EffectUnused, // 66 SPELL_EFFECT_POWER_FUNNEL unused
+ &Spell::EffectApplyAreaAura, // 65 SPELL_EFFECT_APPLY_AREA_AURA_RAID
+ &Spell::EffectUnused, // 66 SPELL_EFFECT_CREATE_MANA_GEM (possibly recharge it, misc - is item ID)
&Spell::EffectHealMaxHealth, // 67 SPELL_EFFECT_HEAL_MAX_HEALTH
&Spell::EffectInterruptCast, // 68 SPELL_EFFECT_INTERRUPT_CAST
&Spell::EffectDistract, // 69 SPELL_EFFECT_DISTRACT
&Spell::EffectPull, // 70 SPELL_EFFECT_PULL one spell: Distract Move
&Spell::EffectPickPocket, // 71 SPELL_EFFECT_PICKPOCKET
&Spell::EffectAddFarsight, // 72 SPELL_EFFECT_ADD_FARSIGHT
- &Spell::EffectSummonPossessed, // 73 SPELL_EFFECT_SUMMON_POSSESSED
- &Spell::EffectSummonTotem, // 74 SPELL_EFFECT_SUMMON_TOTEM
+ &Spell::EffectUnused, // 73 SPELL_EFFECT_UNTRAIN_TALENTS
+ &Spell::EffectApplyGlyph, // 74 SPELL_EFFECT_APPLY_GLYPH
&Spell::EffectHealMechanical, // 75 SPELL_EFFECT_HEAL_MECHANICAL one spell: Mechanical Patch Kit
&Spell::EffectSummonObjectWild, // 76 SPELL_EFFECT_SUMMON_OBJECT_WILD
&Spell::EffectScriptEffect, // 77 SPELL_EFFECT_SCRIPT_EFFECT
@@ -150,17 +152,17 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
&Spell::EffectStuck, // 84 SPELL_EFFECT_STUCK
&Spell::EffectSummonPlayer, // 85 SPELL_EFFECT_SUMMON_PLAYER
&Spell::EffectActivateObject, // 86 SPELL_EFFECT_ACTIVATE_OBJECT
- &Spell::EffectSummonTotem, // 87 SPELL_EFFECT_SUMMON_TOTEM_SLOT1
- &Spell::EffectSummonTotem, // 88 SPELL_EFFECT_SUMMON_TOTEM_SLOT2
- &Spell::EffectSummonTotem, // 89 SPELL_EFFECT_SUMMON_TOTEM_SLOT3
- &Spell::EffectSummonTotem, // 90 SPELL_EFFECT_SUMMON_TOTEM_SLOT4
+ &Spell::EffectUnused, // 87 SPELL_EFFECT_WMO_DAMAGE
+ &Spell::EffectUnused, // 88 SPELL_EFFECT_WMO_REPAIR
+ &Spell::EffectUnused, // 89 SPELL_EFFECT_WMO_CHANGE
+ &Spell::EffectUnused, // 90 SPELL_EFFECT_KILL_CREDIT
&Spell::EffectUnused, // 91 SPELL_EFFECT_THREAT_ALL one spell: zzOLDBrainwash
&Spell::EffectEnchantHeldItem, // 92 SPELL_EFFECT_ENCHANT_HELD_ITEM
&Spell::EffectUnused, // 93 SPELL_EFFECT_SUMMON_PHANTASM
&Spell::EffectSelfResurrect, // 94 SPELL_EFFECT_SELF_RESURRECT
&Spell::EffectSkinning, // 95 SPELL_EFFECT_SKINNING
&Spell::EffectUnused, // 96 SPELL_EFFECT_CHARGE
- &Spell::EffectSummonCritter, // 97 SPELL_EFFECT_SUMMON_CRITTER
+ &Spell::EffectUnused, // 97 SPELL_EFFECT_97
&Spell::EffectKnockBack, // 98 SPELL_EFFECT_KNOCK_BACK
&Spell::EffectDisEnchant, // 99 SPELL_EFFECT_DISENCHANT
&Spell::EffectInebriate, //100 SPELL_EFFECT_INEBRIATE
@@ -175,7 +177,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
&Spell::EffectSummonDeadPet, //109 SPELL_EFFECT_SUMMON_DEAD_PET
&Spell::EffectDestroyAllTotems, //110 SPELL_EFFECT_DESTROY_ALL_TOTEMS
&Spell::EffectDurabilityDamage, //111 SPELL_EFFECT_DURABILITY_DAMAGE
- &Spell::EffectSummonDemon, //112 SPELL_EFFECT_SUMMON_DEMON
+ &Spell::EffectUnused, //112 SPELL_EFFECT_112
&Spell::EffectResurrectNew, //113 SPELL_EFFECT_RESURRECT_NEW
&Spell::EffectTaunt, //114 SPELL_EFFECT_ATTACK_ME
&Spell::EffectDurabilityDamagePCT, //115 SPELL_EFFECT_DURABILITY_DAMAGE_PCT
@@ -195,21 +197,21 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
&Spell::EffectApplyAreaAura, //129 SPELL_EFFECT_APPLY_AREA_AURA_ENEMY
&Spell::EffectRedirectThreat, //130 SPELL_EFFECT_REDIRECT_THREAT
&Spell::EffectUnused, //131 SPELL_EFFECT_131 used in some test spells
- &Spell::EffectNULL, //132 SPELL_EFFECT_PLAY_MUSIC sound id in misc value
+ &Spell::EffectNULL, //132 SPELL_EFFECT_PLAY_MUSIC sound id in misc value (SoundEntries.dbc)
&Spell::EffectUnlearnSpecialization, //133 SPELL_EFFECT_UNLEARN_SPECIALIZATION unlearn profession specialization
&Spell::EffectKillCredit, //134 SPELL_EFFECT_KILL_CREDIT misc value is creature entry
&Spell::EffectNULL, //135 SPELL_EFFECT_CALL_PET
&Spell::EffectHealPct, //136 SPELL_EFFECT_HEAL_PCT
&Spell::EffectEnergisePct, //137 SPELL_EFFECT_ENERGIZE_PCT
&Spell::EffectNULL, //138 SPELL_EFFECT_138 Leap
- &Spell::EffectUnused, //139 SPELL_EFFECT_139 unused
+ &Spell::EffectUnused, //139 SPELL_EFFECT_CLEAR_QUEST (misc - is quest ID)
&Spell::EffectForceCast, //140 SPELL_EFFECT_FORCE_CAST
&Spell::EffectNULL, //141 SPELL_EFFECT_141 damage and reduce speed?
&Spell::EffectTriggerSpellWithValue, //142 SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
&Spell::EffectApplyAreaAura, //143 SPELL_EFFECT_APPLY_AREA_AURA_OWNER
&Spell::EffectKnockBack, //144 SPELL_EFFECT_KNOCK_BACK_2 Spectral Blast
&Spell::EffectNULL, //145 SPELL_EFFECT_145 Black Hole Effect
- &Spell::EffectUnused, //146 SPELL_EFFECT_146 unused
+ &Spell::EffectActivateRune, //146 SPELL_EFFECT_ACTIVATE_RUNE
&Spell::EffectQuestFail, //147 SPELL_EFFECT_QUEST_FAIL quest fail
&Spell::EffectUnused, //148 SPELL_EFFECT_148 unused
&Spell::EffectNULL, //149 SPELL_EFFECT_149 swoop
@@ -217,6 +219,12 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
&Spell::EffectTriggerRitualOfSummoning, //151 SPELL_EFFECT_TRIGGER_SPELL_2
&Spell::EffectNULL, //152 SPELL_EFFECT_152 summon Refer-a-Friend
&Spell::EffectNULL, //153 SPELL_EFFECT_CREATE_PET misc value is creature entry
+ &Spell::EffectNULL, //154 unused
+ &Spell::EffectTitanGrip, //155 SPELL_EFFECT_TITAN_GRIP Allows you to equip two-handed axes, maces and swords in one hand, but you attack $49152s1% slower than normal.
+ &Spell::EffectEnchantItemPrismatic, //156 SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
+ &Spell::EffectCreateItem2, //157 SPELL_EFFECT_CREATE_ITEM_2 create/learn item/spell for profession
+ &Spell::EffectMilling, //158 SPELL_EFFECT_MILLING milling
+ &Spell::EffectRenamePet //159 SPELL_EFFECT_ALLOW_RENAME_PET allow rename pet once again
};
void Spell::EffectNULL(uint32 /*i*/)
@@ -293,7 +301,7 @@ void Spell::EffectEnvirinmentalDMG(uint32 i)
// currently each enemy selected explicitly and self cast damage, we prevent apply self casted spell bonuses/etc
damage = m_spellInfo->EffectBasePoints[i]+m_spellInfo->EffectBaseDice[i];
- m_caster->CalcAbsorbResist(m_caster,GetSpellSchoolMask(m_spellInfo), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
+ m_caster->CalcAbsorbResist(m_caster,GetSpellSchoolMask(m_spellInfo), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist, m_spellInfo);
m_caster->SendSpellNonMeleeDamageLog(m_caster, m_spellInfo->Id, damage, GetSpellSchoolMask(m_spellInfo), absorb, resist, false, 0, false);
if(m_caster->GetTypeId() == TYPEID_PLAYER)
@@ -347,6 +355,13 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
damage = 200;
break;
}
+ // Intercept (warrior spell trigger)
+ case 20253:
+ case 61491:
+ {
+ damage+= uint32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.12f);
+ break;
+ }
// arcane charge. must only affect demons (also undead?)
case 45072:
{
@@ -374,7 +389,7 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
case SPELLFAMILY_MAGE:
{
// Arcane Blast
- if(m_spellInfo->SpellFamilyFlags & 0x20000000LL)
+ if(m_spellInfo->SpellFamilyFlags[0] & 0x20000000)
{
m_caster->CastSpell(m_caster,36032,true);
}
@@ -383,29 +398,43 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
case SPELLFAMILY_WARRIOR:
{
// Bloodthirst
- if(m_spellInfo->SpellFamilyFlags & 0x40000000000LL)
+ if(m_spellInfo->SpellFamilyFlags[1] & 0x400)
{
damage = uint32(damage * (m_caster->GetTotalAttackPowerValue(BASE_ATTACK)) / 100);
}
// Shield Slam
- else if(m_spellInfo->SpellFamilyFlags & 0x100000000LL)
+ else if(m_spellInfo->SpellFamilyFlags[1] & 0x1)
damage += int32(m_caster->GetShieldBlockValue());
// Victory Rush
- else if(m_spellInfo->SpellFamilyFlags & 0x10000000000LL)
+ else if(m_spellInfo->SpellFamilyFlags[1] & 0x100)
{
damage = uint32(damage * m_caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100);
m_caster->ModifyAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH, false);
}
+ // Revenge ${$m1+$AP*0.207} to ${$M1+$AP*0.207}
+ else if(m_spellInfo->SpellFamilyFlags[0] & 0x400)
+ damage+= uint32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.207f);
+ // Heroic Throw ${$m1+$AP*.50}
+ else if(m_spellInfo->SpellFamilyFlags[1] & 0x00000001)
+ damage+= uint32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.5f);
+ // Shockwave ${$m3/100*$AP}
+ else if(m_spellInfo->SpellFamilyFlags[1] & 0x00008000)
+ {
+ int32 pct = m_caster->CalculateSpellDamage(m_spellInfo, 2, m_spellInfo->EffectBasePoints[2], unitTarget);
+ if (pct > 0)
+ damage+= int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * pct / 100);
+ break;
+ }
break;
}
case SPELLFAMILY_WARLOCK:
{
// Incinerate Rank 1 & 2
- if((m_spellInfo->SpellFamilyFlags & 0x00004000000000LL) && m_spellInfo->SpellIconID==2128)
+ if((m_spellInfo->SpellFamilyFlags[1] & 0x000040) && m_spellInfo->SpellIconID==2128)
{
// Incinerate does more dmg (dmg*0.25) if the target is Immolated.
if(unitTarget->HasAuraState(AURA_STATE_IMMOLATE))
- damage += int32(damage*0.25);
+ damage += int32(damage*0.25f);
}
// Conflagrate - consumes immolate
@@ -415,75 +444,52 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
Unit::AuraList const &mPeriodic = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
for(Unit::AuraList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i)
{
- if( (*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && ((*i)->GetSpellProto()->SpellFamilyFlags & 4) &&
+ if( (*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && ((*i)->GetSpellProto()->SpellFamilyFlags[0] & 4) &&
(*i)->GetCasterGUID()==m_caster->GetGUID() )
{
- unitTarget->RemoveAurasDueToCasterSpell((*i)->GetId(), m_caster->GetGUID());
+ unitTarget->RemoveAurasByCasterSpell((*i)->GetId(), m_caster->GetGUID());
break;
}
}
}
break;
}
+ case SPELLFAMILY_PRIEST:
+ {
+ // Shadow Word: Death - deals damage equal to damage done to caster
+ if (m_spellInfo->SpellFamilyFlags[1] & 0x2)
+ m_caster->CastCustomSpell(m_caster, 32409, &damage, 0, 0, true);
+ break;
+ }
case SPELLFAMILY_DRUID:
{
// Ferocious Bite
- if((m_spellInfo->SpellFamilyFlags & 0x000800000) && m_spellInfo->SpellVisual==6587)
+ 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/630) additional damage
- float multiple = m_caster->GetTotalAttackPowerValue(BASE_ATTACK) / 630 + m_spellInfo->DmgMultiplier[effect_idx];
+ // 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->DmgMultiplier[effect_idx];
damage += int32(m_caster->GetPower(POWER_ENERGY) * multiple);
+ damage += int32(((Player*)m_caster)->GetComboPoints() * ap * 7 / 100);
m_caster->SetPower(POWER_ENERGY,0);
}
// Rake
- else if(m_spellInfo->SpellFamilyFlags & 0x0000000000001000LL)
+ else if(m_spellInfo->SpellFamilyFlags[0] & 0x1000)
{
damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100);
}
// Swipe
- else if(m_spellInfo->SpellFamilyFlags & 0x0010000000000000LL)
+ else if(m_spellInfo->SpellFamilyFlags[1] & 0x00100000)
{
damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.08f);
}
- // Starfire
- else if ( m_spellInfo->SpellFamilyFlags & 0x0004LL )
- {
- Unit::AuraList const& m_OverrideClassScript = m_caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
- for(Unit::AuraList::const_iterator i = m_OverrideClassScript.begin(); i != m_OverrideClassScript.end(); ++i)
- {
- // Starfire Bonus (caster)
- switch((*i)->GetModifier()->m_miscvalue)
- {
- case 5481: // Nordrassil Regalia - bonus
- {
- Unit::AuraList const& m_periodicDamageAuras = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
- for(Unit::AuraList::const_iterator itr = m_periodicDamageAuras.begin(); itr != m_periodicDamageAuras.end(); ++itr)
- {
- // Moonfire or Insect Swarm (target debuff from any casters)
- if ( (*itr)->GetSpellProto()->SpellFamilyFlags & 0x00200002LL )
- {
- int32 mod = (*i)->GetModifier()->m_amount;
- damage += damage*mod/100;
- break;
- }
- }
- break;
- }
- case 5148: //Improved Starfire - Ivory Idol of the Moongoddes Aura
- {
- damage += (*i)->GetModifier()->m_amount;
- break;
- }
- }
- }
- }
//Mangle Bonus for the initial damage of Lacerate and Rake
- if((m_spellInfo->SpellFamilyFlags==0x0000000000001000LL && m_spellInfo->SpellIconID==494) ||
- (m_spellInfo->SpellFamilyFlags==0x0000010000000000LL && m_spellInfo->SpellIconID==2246))
+ if((m_spellInfo->SpellFamilyFlags.IsEqual(0x1000,0,0) && m_spellInfo->SpellIconID==494) ||
+ (m_spellInfo->SpellFamilyFlags.IsEqual(0,0x100,0) && m_spellInfo->SpellIconID==2246))
{
Unit::AuraList const& mDummyAuras = unitTarget->GetAurasByType(SPELL_AURA_DUMMY);
for(Unit::AuraList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i)
- if((*i)->GetSpellProto()->SpellFamilyFlags & 0x0000044000000000LL && (*i)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_DRUID)
+ if((*i)->GetSpellProto()->SpellFamilyFlags[1] & 0x00000440 && (*i)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_DRUID)
{
damage = int32(damage*(100.0f+(*i)->GetModifier()->m_amount)/100.0f);
break;
@@ -494,69 +500,88 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
case SPELLFAMILY_ROGUE:
{
// Envenom
- if(m_caster->GetTypeId()==TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags & 0x800000000LL))
+ if(m_caster->GetTypeId()==TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags[1] & 0x8))
{
// consume from stack dozes not more that have combo-points
if(uint32 combo = ((Player*)m_caster)->GetComboPoints())
{
- // count consumed deadly poison doses at target
- uint32 doses = 0;
-
- // remove consumed poison doses
+ Aura *poison = 0;
+ // Lookup for Deadly poison (only attacker applied)
Unit::AuraList const& auras = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
- for(Unit::AuraList::const_iterator itr = auras.begin(); itr!=auras.end() && combo;)
- {
- // Deadly poison (only attacker applied)
- if( (*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_ROGUE && ((*itr)->GetSpellProto()->SpellFamilyFlags & 0x10000) &&
- (*itr)->GetSpellProto()->SpellVisual==5100 && (*itr)->GetCasterGUID()==m_caster->GetGUID() )
+ for(Unit::AuraList::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr)
+ if( (*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_ROGUE &&
+ (*itr)->GetSpellProto()->SpellFamilyFlags[0] & 0x10000 &&
+ (*itr)->GetCasterGUID()==m_caster->GetGUID() )
{
- --combo;
- ++doses;
-
- unitTarget->RemoveSingleAuraFromStack((*itr)->GetId(), (*itr)->GetEffIndex());
-
- itr = auras.begin();
+ poison = *itr;
+ break;
}
- else
- ++itr;
+ // count consumed deadly poison doses at target
+ if (poison)
+ {
+ uint32 spellId = poison->GetId();
+ uint32 doses = poison->GetStackAmount();
+ if (doses > combo)
+ doses = combo;
+ for (int i=0; i< doses; i++)
+ unitTarget->RemoveSingleSpellAurasFromStack(spellId);
+ damage *= doses;
+ damage += int32(((Player*)m_caster)->GetTotalAttackPowerValue(BASE_ATTACK) * 0.03f * doses);
}
-
- damage *= doses;
- damage += int32(((Player*)m_caster)->GetTotalAttackPowerValue(BASE_ATTACK) * 0.03f * doses);
-
// Eviscerate and Envenom Bonus Damage (item set effect)
if(m_caster->GetDummyAura(37169))
damage += ((Player*)m_caster)->GetComboPoints()*40;
}
}
// Eviscerate
- else if((m_spellInfo->SpellFamilyFlags & 0x00020000LL) && m_caster->GetTypeId()==TYPEID_PLAYER)
+ else if((m_spellInfo->SpellFamilyFlags[0] & 0x00020000) && m_caster->GetTypeId()==TYPEID_PLAYER)
{
if(uint32 combo = ((Player*)m_caster)->GetComboPoints())
{
- damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * combo * 0.03f);
+ float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
+ damage += irand(int32(ap * combo * 0.03f), int32(ap * combo * 0.07f));
// Eviscerate and Envenom Bonus Damage (item set effect)
if(m_caster->GetDummyAura(37169))
damage += combo*40;
}
}
+ // Gouge
+ else if(m_spellInfo->SpellFamilyFlags[0] & 0x8)
+ {
+ damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.02f);
+ }
+ // Instant Poison
+ else if(m_spellInfo->SpellFamilyFlags[0] & 0x2000)
+ {
+ damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.10f);
+ }
+ // Wound Poison
+ else if(m_spellInfo->SpellFamilyFlags[0] & 0x10000000)
+ {
+ damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.04f);
+ }
break;
}
case SPELLFAMILY_HUNTER:
{
// Mongoose Bite
- if((m_spellInfo->SpellFamilyFlags & 0x000000002) && m_spellInfo->SpellVisual==342)
+ if((m_spellInfo->SpellFamilyFlags[0] & 0x2) && m_spellInfo->SpellVisual[0]==342)
+ {
+ damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2f);
+ }
+ // Counterattack
+ else if(m_spellInfo->SpellFamilyFlags[1] & 0x00080000)
{
- damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2);
+ damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2f);
}
// Arcane Shot
- else if((m_spellInfo->SpellFamilyFlags & 0x00000800) && m_spellInfo->maxLevel > 0)
+ else if((m_spellInfo->SpellFamilyFlags[0] & 0x00000800) && m_spellInfo->maxLevel > 0)
{
- damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.15);
+ damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.15f);
}
// Steady Shot
- else if(m_spellInfo->SpellFamilyFlags & 0x100000000LL)
+ else if(m_spellInfo->SpellFamilyFlags[1] & 0x1)
{
int32 base = irand((int32)m_caster->GetWeaponDamageRange(RANGED_ATTACK, MINDAMAGE),(int32)m_caster->GetWeaponDamageRange(RANGED_ATTACK, MAXDAMAGE));
damage += int32(float(base)/m_caster->GetAttackTime(RANGED_ATTACK)*2800 + m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.2f);
@@ -578,28 +603,58 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
if(found)
damage += m_spellInfo->EffectBasePoints[1];
}
- //Explosive Trap Effect
- else if(m_spellInfo->SpellFamilyFlags & 0x00000004)
+ // Explosive Trap Effect
+ else if(m_spellInfo->SpellFamilyFlags[0] & 0x00000004)
{
- damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.1);
+ damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.1f);
}
break;
}
case SPELLFAMILY_PALADIN:
{
- //Judgement of Vengeance
- if((m_spellInfo->SpellFamilyFlags & 0x800000000LL) && m_spellInfo->SpellIconID==2292)
+ // Judgement of Vengeance ${1+0.22*$SPH+0.14*$AP} + 10% for each application of Holy Vengeance on the target
+ if((m_spellInfo->SpellFamilyFlags[1] & 0x8) && m_spellInfo->SpellIconID==2292)
{
+ float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
+ int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) +
+ m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget);
+ damage+=int32(ap * 0.14f) + int32(holy * 22 / 100);
+ // Get stack of Holy Vengeance on the target added by caster
uint32 stacks = 0;
Unit::AuraList const& auras = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
for(Unit::AuraList::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr)
if((*itr)->GetId() == 31803 && (*itr)->GetCasterGUID()==m_caster->GetGUID())
- ++stacks;
- if(!stacks)
- //No damage if the target isn't affected by this
- damage = -1;
- else
- damage *= stacks;
+ {
+ stacks = (*itr)->GetStackAmount();
+ break;
+ }
+ // + 10% for each application of Holy Vengeance on the target
+ if(stacks)
+ damage += damage * stacks * 10 /100;
+ }
+ // Avenger's Shield ($m1+0.07*$SPH+0.07*$AP) - ranged sdb for future
+ else if(m_spellInfo->SpellFamilyFlags[0] & 0x4000)
+ {
+ float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
+ int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) +
+ m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget);
+ damage += int32(ap * 0.07f) + int32(holy * 7 / 100);
+ }
+ // Hammer of Wrath ($m1+0.15*$SPH+0.15*$AP) - ranged type sdb future fix
+ else if(m_spellInfo->SpellFamilyFlags[1] & 0x00000080)
+ {
+ float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
+ int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) +
+ m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget);
+ damage += int32(ap * 0.15f) + int32(holy * 15 / 100);
+ }
+ // Hammer of the Righteous
+ else if(m_spellInfo->SpellFamilyFlags[1]&0x00040000)
+ {
+ // Add main hand dps * effect[2] amount
+ float averange = (m_caster->GetFloatValue(UNIT_FIELD_MINDAMAGE) + m_caster->GetFloatValue(UNIT_FIELD_MAXDAMAGE)) / 2;
+ int32 count = m_caster->CalculateSpellDamage(m_spellInfo, 2, m_spellInfo->EffectBasePoints[2], unitTarget);
+ damage += count * int32(averange * 1000) / m_caster->GetAttackTime(BASE_ATTACK);
}
break;
}
@@ -637,7 +692,7 @@ void Spell::EffectDummy(uint32 i)
if (!creatureTarget || !pGameObj) return;
- if (!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), 181574, creatureTarget->GetMap(),
+ if (!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), 181574, creatureTarget->GetMap(), creatureTarget->GetPhaseMask(),
creatureTarget->GetPositionX(), creatureTarget->GetPositionY(), creatureTarget->GetPositionZ(),
creatureTarget->GetOrientation(), 0, 0, 0, 0, 100, 1))
{
@@ -745,12 +800,6 @@ void Spell::EffectDummy(uint32 i)
m_caster->CastCustomSpell(unitTarget, 12721, &deepWoundsDotBasePoints0, NULL, NULL, true, NULL);
return;
}
- case 12975: //Last Stand
- {
- int32 healthModSpellBasePoints0 = int32(m_caster->GetMaxHealth()*0.3);
- m_caster->CastCustomSpell(m_caster, 12976, &healthModSpellBasePoints0, NULL, NULL, true, NULL);
- return;
- }
case 13120: // net-o-matic
{
if(!unitTarget)
@@ -787,30 +836,6 @@ void Spell::EffectDummy(uint32 i)
}
return;
}
- case 14185: // Preparation Rogue
- {
- if(m_caster->GetTypeId()!=TYPEID_PLAYER)
- return;
-
- //immediately finishes the cooldown on certain Rogue abilities
- const PlayerSpellMap& sp_list = ((Player *)m_caster)->GetSpellMap();
- for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
- {
- uint32 classspell = itr->first;
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(classspell);
-
- if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && (spellInfo->SpellFamilyFlags & 0x26000000860LL))
- {
- ((Player*)m_caster)->RemoveSpellCooldown(classspell);
-
- WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8));
- data << uint32(classspell);
- data << uint64(m_caster->GetGUID());
- ((Player*)m_caster)->GetSession()->SendPacket(&data);
- }
- }
- return;
- }
case 15998: // Capture Worg Pup
case 29435: // Capture Female Kaliri Hatchling
{
@@ -875,19 +900,20 @@ void Spell::EffectDummy(uint32 i)
if(creatureTarget->isPet())
return;
+ GameObject* Crystal_Prison = m_caster->SummonGameObject(179644, creatureTarget->GetPositionX(), creatureTarget->GetPositionY(), creatureTarget->GetPositionZ(), creatureTarget->GetOrientation(), 0, 0, 0, 0, creatureTarget->GetRespawnTime()-time(NULL));
+ sLog.outDebug("SummonGameObject at SpellEfects.cpp EffectDummy for Spell 23019\n");
+
creatureTarget->setDeathState(JUST_DIED);
creatureTarget->RemoveCorpse();
creatureTarget->SetHealth(0); // just for nice GM-mode view
- GameObject* Crystal_Prison = m_caster->SummonGameObject(179644, creatureTarget->GetPositionX(), creatureTarget->GetPositionY(), creatureTarget->GetPositionZ(), creatureTarget->GetOrientation(), 0, 0, 0, 0, creatureTarget->GetRespawnTime()-time(NULL));
- sLog.outDebug("SummonGameObject at SpellEfects.cpp EffectDummy for Spell 23019\n");
WorldPacket data(SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE, 8);
data << uint64(Crystal_Prison->GetGUID());
m_caster->SendMessageToSet(&data,true);
return;
}
- case 23074: // Arc. Dragonling
+ case 23074: // Arcanite Dragonling
if (!m_CastItem) return;
m_caster->CastSpell(m_caster,19804,true,m_CastItem);
return;
@@ -1205,6 +1231,12 @@ void Spell::EffectDummy(uint32 i)
m_caster->CastSpell(m_caster, 30452, true, NULL);
return;
}
+ case 53341:
+ case 53343:
+ {
+ m_caster->CastSpell(m_caster,54586,true);
+ return;
+ }
}
//All IconID Check in there
@@ -1278,65 +1310,119 @@ void Spell::EffectDummy(uint32 i)
break;
case SPELLFAMILY_WARRIOR:
// Charge
- if(m_spellInfo->SpellFamilyFlags & 0x1 && m_spellInfo->SpellVisual == 867)
+ if(m_spellInfo->SpellFamilyFlags & 0x1 && m_spellInfo->SpellVisual[0] == 867)
{
int32 chargeBasePoints0 = damage;
m_caster->CastCustomSpell(m_caster,34846,&chargeBasePoints0,NULL,NULL,true);
return;
}
+ //Slam
+ if(m_spellInfo->SpellFamilyFlags[0] & 0x200000 && m_spellInfo->SpellIconID == 559)
+ {
+ int32 bp0 = damage;
+ m_caster->CastCustomSpell(unitTarget, 50783, &bp0, NULL, NULL, true, 0);
+ }
// Execute
- if(m_spellInfo->SpellFamilyFlags & 0x20000000)
+ if(m_spellInfo->SpellFamilyFlags[0] & 0x20000000)
{
if(!unitTarget)
return;
+ uint32 rage = m_caster->GetPower(POWER_RAGE);
+ // Glyph of Execution bonus
+ if (Aura *aura = m_caster->GetDummyAura(58367))
+ rage+=aura->GetModifier()->m_amount;
+
spell_id = 20647;
- bp = damage+int32(m_caster->GetPower(POWER_RAGE) * m_spellInfo->DmgMultiplier[i]);
+ bp = damage+int32(rage * m_spellInfo->DmgMultiplier[i] +
+ m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2f);
m_caster->SetPower(POWER_RAGE,0);
break;
}
- if(m_spellInfo->Id==21977) //Warrior's Wrath
+ // Slam
+ if(m_spellInfo->SpellFamilyFlags[0] & 0x200000)
{
if(!unitTarget)
return;
-
- m_caster->CastSpell(unitTarget,21887,true); // spell mod
+ m_damage+=m_caster->CalculateDamage(m_attackType, false);
+ m_damage+=damage;
return;
}
+ switch(m_spellInfo->Id)
+ {
+ // Warrior's Wrath
+ case 21977:
+ {
+ if(!unitTarget)
+ return;
+ m_caster->CastSpell(unitTarget,21887,true); // spell mod
+ return;
+ }
+ // Last Stand
+ case 12975:
+ {
+ int32 healthModSpellBasePoints0 = int32(m_caster->GetMaxHealth()*0.3);
+ m_caster->CastCustomSpell(m_caster, 12976, &healthModSpellBasePoints0, NULL, NULL, true, NULL);
+ return;
+ }
+ // Bloodthirst
+ case 23881:
+ {
+ m_caster->CastCustomSpell(unitTarget, 23885, &damage, NULL, NULL, true, NULL);
+ return;
+ }
+ }
break;
case SPELLFAMILY_WARLOCK:
- //Life Tap (only it have this with dummy effect)
- if (m_spellInfo->SpellFamilyFlags == 0x40000)
+ // Life Tap
+ if (m_spellInfo->SpellFamilyFlags[0] & 0x40000)
{
- float cost = damage;
-
- if(Player* modOwner = m_caster->GetSpellModOwner())
- modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, cost,this);
-
- int32 dmg = m_caster->SpellDamageBonus(m_caster, m_spellInfo,uint32(cost > 0 ? cost : 0), SPELL_DIRECT_DAMAGE);
-
- if(int32(m_caster->GetHealth()) > dmg)
+ // In 303 exist spirit depend
+ uint32 spirit = m_caster->GetStat(STAT_SPIRIT);
+ switch (m_spellInfo->Id)
+ {
+ case 1454: damage+=spirit; break;
+ case 1455: damage+=spirit*15/10; break;
+ case 1456: damage+=spirit*2; break;
+ case 11687: damage+=spirit*25/10; break;
+ case 11688:
+ case 11689:
+ case 27222:
+ case 57946: damage+=spirit*3; break;
+ default:
+ sLog.outError("Spell::EffectDummy: %u Life Tap need set spirit multipler", m_spellInfo->Id);
+ return;
+ }
+// Think its not need (also need remove Life Tap from SpellDamageBonus or add new value)
+// damage = m_caster->SpellDamageBonus(m_caster, m_spellInfo,uint32(damage > 0 ? damage : 0), SPELL_DIRECT_DAMAGE);
+ if(int32(unitTarget->GetHealth()) > damage)
{
// Shouldn't Appear in Combat Log
- m_caster->ModifyHealth(-dmg);
-
- int32 mana = dmg;
+ unitTarget->ModifyHealth(-damage);
+ int32 mana = damage;
+ // Improved Life Tap mod
Unit::AuraList const& auraDummy = m_caster->GetAurasByType(SPELL_AURA_DUMMY);
for(Unit::AuraList::const_iterator itr = auraDummy.begin(); itr != auraDummy.end(); ++itr)
{
- // only Imp. Life Tap have this in combination with dummy aura
if((*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (*itr)->GetSpellProto()->SpellIconID == 208)
mana = ((*itr)->GetModifier()->m_amount + 100)* mana / 100;
}
-
- m_caster->CastCustomSpell(m_caster,31818,&mana,NULL,NULL,true,NULL);
+ m_caster->CastCustomSpell(unitTarget, 31818, &mana, NULL, NULL, true);
// Mana Feed
- int32 manaFeedVal = m_caster->CalculateSpellDamage(m_spellInfo,1, m_spellInfo->EffectBasePoints[1],m_caster);
- manaFeedVal = manaFeedVal * mana / 100;
+ int32 manaFeedVal = 0;
+ Unit::AuraList const& mod = m_caster->GetAurasByType(SPELL_AURA_ADD_FLAT_MODIFIER);
+ for(Unit::AuraList::const_iterator itr = mod.begin(); itr != mod.end(); ++itr)
+ {
+ if((*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (*itr)->GetSpellProto()->SpellIconID == 1982)
+ manaFeedVal+= (*itr)->GetModifier()->m_amount;
+ }
if(manaFeedVal > 0)
- m_caster->CastCustomSpell(m_caster,32553,&manaFeedVal,NULL,NULL,true,NULL);
+ {
+ manaFeedVal = manaFeedVal * mana / 100;
+ m_caster->CastCustomSpell(m_caster, 32553, &manaFeedVal, NULL, NULL, true, NULL);
+ }
}
else
SendCastResult(SPELL_FAILED_FIZZLE);
@@ -1344,6 +1430,30 @@ void Spell::EffectDummy(uint32 i)
}
break;
case SPELLFAMILY_PRIEST:
+ // Penance
+ if (m_spellInfo->SpellFamilyFlags[1] & 0x00800000)
+ {
+ if (!unitTarget)
+ return;
+
+ int hurt = 0;
+ int heal = 0;
+ switch(m_spellInfo->Id)
+ {
+ case 47540: hurt = 47758; heal = 47757; break;
+ case 53005: hurt = 53001; heal = 52986; break;
+ case 53006: hurt = 53002; heal = 52987; break;
+ case 53007: hurt = 53003; heal = 52988; break;
+ default:
+ sLog.outError("Spell::EffectDummy: Spell %u Penance need set correct heal/damage spell", m_spellInfo->Id);
+ return;
+ }
+ if (m_caster->IsFriendlyTo(unitTarget))
+ m_caster->CastSpell(unitTarget, heal, true, 0);
+ else
+ m_caster->CastSpell(unitTarget, hurt, true, 0);
+ return;
+ }
switch(m_spellInfo->Id )
{
case 28598: // Touch of Weakness triggered spell
@@ -1371,25 +1481,10 @@ void Spell::EffectDummy(uint32 i)
}
break;
case SPELLFAMILY_DRUID:
- switch(m_spellInfo->Id )
- {
- case 5420: // Tree of Life passive
- {
- // Tree of Life area effect
- int32 health_mod = int32(m_caster->GetStat(STAT_SPIRIT)/4);
- m_caster->CastCustomSpell(m_caster,34123,&health_mod,NULL,NULL,true,NULL);
- return;
- }
- }
break;
case SPELLFAMILY_ROGUE:
switch(m_spellInfo->Id )
{
- case 31231: // Cheat Death
- {
- m_caster->CastSpell(m_caster,45182,true);
- return;
- }
case 5938: // Shiv
{
if(m_caster->GetTypeId() != TYPEID_PLAYER)
@@ -1425,36 +1520,38 @@ void Spell::EffectDummy(uint32 i)
m_caster->CastSpell(unitTarget, 5940, true);
return;
}
- }
- break;
- case SPELLFAMILY_HUNTER:
- // Kill command
- if(m_spellInfo->SpellFamilyFlags & 0x00080000000000LL)
- {
- if(m_caster->getClass()!=CLASS_HUNTER)
- return;
+ case 14185: // Preparation Rogue
+ {
+ if(m_caster->GetTypeId()!=TYPEID_PLAYER)
+ return;
- // clear hunter crit aura state
- m_caster->ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE,false);
+ //immediately finishes the cooldown on certain Rogue abilities
+ const PlayerSpellMap& sp_list = ((Player *)m_caster)->GetSpellMap();
+ for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
+ {
+ uint32 classspell = itr->first;
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(classspell);
- // additional damage from pet to pet target
- Pet* pet = m_caster->GetPet();
- if(!pet || !pet->getVictim())
- return;
+ if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && (spellInfo->SpellFamilyFlags[1] & 0x00000240 || spellInfo->SpellFamilyFlags[0] & 0x00000860))
+ {
+ ((Player*)m_caster)->RemoveSpellCooldown(classspell);
- uint32 spell_id = 0;
- switch (m_spellInfo->Id)
+ WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8));
+ data << uint32(classspell);
+ data << uint64(m_caster->GetGUID());
+ ((Player*)m_caster)->GetSession()->SendPacket(&data);
+ }
+ }
+ return;
+ }
+ case 31231: // Cheat Death
{
- case 34026: spell_id = 34027; break; // rank 1
- default:
- sLog.outError("Spell::EffectDummy: Spell %u not handled in KC",m_spellInfo->Id);
+ m_caster->CastSpell(m_caster,45182,true);
return;
}
-
- pet->CastSpell(pet->getVictim(), spell_id, true);
- return;
}
-
+ break;
+ case SPELLFAMILY_HUNTER:
switch(m_spellInfo->Id)
{
case 23989: //Readiness talent
@@ -1512,6 +1609,8 @@ void Spell::EffectDummy(uint32 i)
case 20930: hurt = 25902; heal = 25903; break;
case 27174: hurt = 27176; heal = 27175; break;
case 33072: hurt = 33073; heal = 33074; break;
+ case 48824: hurt = 48822; heal = 48820; break;
+ case 48825: hurt = 48823; heal = 48821; break;
default:
sLog.outError("Spell::EffectDummy: Spell %u not handled in HS",m_spellInfo->Id);
return;
@@ -1542,10 +1641,7 @@ void Spell::EffectDummy(uint32 i)
mod->value = -50;
mod->type = SPELLMOD_PCT;
mod->spellId = m_spellInfo->Id;
- mod->effectId = i;
- mod->lastAffected = NULL;
- mod->mask = 0x0000020000000000LL;
- mod->charges = 0;
+ mod->mask[1] = 0x00000200;
((Player*)m_caster)->AddSpellMod(mod, true);
m_caster->CastSpell(unitTarget,spell_proto,true,NULL);
@@ -1561,6 +1657,14 @@ void Spell::EffectDummy(uint32 i)
switch(m_spellInfo->Id)
{
+ // Judgement of Righteousness (0.2*$AP+0.32*$SPH) holy added in spellDamagBonus
+ case 20187:
+ {
+ if (!unitTarget)
+ return;
+ m_damage+=int32(0.2f*m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
+ return;
+ }
case 31789: // Righteous Defense (step 1)
{
// 31989 -> dummy effect (step 1) + dummy effect (step 2) -> 31709 (taunt like spell for each target)
@@ -1627,8 +1731,10 @@ void Spell::EffectDummy(uint32 i)
break;
case SPELLFAMILY_SHAMAN:
//Shaman Rockbiter Weapon
- if (m_spellInfo->SpellFamilyFlags == 0x400000)
+ if (m_spellInfo->SpellFamilyFlags.IsEqual(0x400000))
{
+ // TODO: use expect spell for enchant (if exist talent)
+ // In 3.0.3 no mods present for rockbiter
uint32 spell_id = 0;
switch(m_spellInfo->Id)
{
@@ -1636,11 +1742,6 @@ void Spell::EffectDummy(uint32 i)
case 8018: spell_id = 36750; break; // Rank 2
case 8019: spell_id = 36755; break; // Rank 3
case 10399: spell_id = 36759; break; // Rank 4
- case 16314: spell_id = 36763; break; // Rank 5
- case 16315: spell_id = 36766; break; // Rank 6
- case 16316: spell_id = 36771; break; // Rank 7
- case 25479: spell_id = 36775; break; // Rank 8
- case 25485: spell_id = 36499; break; // Rank 9
default:
sLog.outError("Spell::EffectDummy: Spell %u not handled in RW",m_spellInfo->Id);
return;
@@ -1678,18 +1779,57 @@ void Spell::EffectDummy(uint32 i)
}
return;
}
-
- if(m_spellInfo->Id == 39610) // Mana-Tide Totem effect
+ // Healing Stream Totem
+ if(m_spellInfo->SpellFamilyFlags[0] & 0x2000)
+ {
+ m_caster->CastCustomSpell(unitTarget, 52042, &damage, 0, 0, true, 0, 0, m_originalCasterGUID);
+ return;
+ }
+ // Mana Spring Totem
+ if(m_spellInfo->SpellFamilyFlags[0] & 0x4000)
+ {
+ if(unitTarget->getPowerType()!=POWER_MANA)
+ return;
+ m_caster->CastCustomSpell(unitTarget, 52032, &damage, 0, 0, true, 0, 0, m_originalCasterGUID);
+ return;
+ }
+ if(m_spellInfo->Id == 39610) // Mana Tide Totem effect
{
if(!unitTarget || unitTarget->getPowerType() != POWER_MANA)
return;
-
+ // Glyph of Mana Tide
+ Unit *owner = m_caster->GetOwner();
+ if (owner)
+ if (Aura *dummy = owner->GetDummyAura(55441))
+ damage+=dummy->GetModifier()->m_amount;
// Regenerate 6% of Total Mana Every 3 secs
int32 EffectBasePoints0 = unitTarget->GetMaxPower(POWER_MANA) * damage / 100;
m_caster->CastCustomSpell(unitTarget,39609,&EffectBasePoints0,NULL,NULL,true,NULL,NULL,m_originalCasterGUID);
return;
}
-
+ // Lava Lash
+ if (m_spellInfo->SpellFamilyFlags[2] & 0x00000004)
+ {
+ if (m_caster->GetTypeId()!=TYPEID_PLAYER)
+ return;
+ Item *item = ((Player*)m_caster)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
+ if (item)
+ {
+ // Damage is increased if your off-hand weapon is enchanted with Flametongue.
+ Unit::AuraList const& auraDummy = m_caster->GetAurasByType(SPELL_AURA_DUMMY);
+ for(Unit::AuraList::const_iterator itr = auraDummy.begin(); itr != auraDummy.end(); ++itr)
+ {
+ if( (*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_SHAMAN &&
+ (*itr)->GetSpellProto()->SpellFamilyFlags[0] & 0x200000 &&
+ (*itr)->GetCastItemGUID() == item->GetGUID())
+ {
+ m_damage += m_damage * damage / 100;
+ return;
+ }
+ }
+ }
+ return;
+ }
break;
}
@@ -1703,7 +1843,7 @@ void Spell::EffectDummy(uint32 i)
sLog.outError("EffectDummy of spell %u: triggering unknown spell id %i\n", m_spellInfo->Id, spell_id);
return;
}
-
+
Spell* spell = new Spell(m_caster, spellInfo, true, m_originalCasterGUID, NULL, true);
if(bp) spell->m_currentBasePoints[0] = bp;
SpellCastTargets targets;
@@ -1809,7 +1949,7 @@ void Spell::EffectTriggerSpell(uint32 i)
if (!spellInfo)
continue;
- if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && spellInfo->SpellFamilyFlags & SPELLFAMILYFLAG_ROGUE_STEALTH)
+ if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && spellInfo->SpellFamilyFlags[0] & SPELLFAMILYFLAG_ROGUE_STEALTH)
{
spellId = spellInfo->Id;
break;
@@ -1966,12 +2106,7 @@ void Spell::EffectTriggerMissileSpell(uint32 effect_idx)
if (m_CastItem)
DEBUG_LOG("WORLD: cast Item spellId - %i", spellInfo->Id);
- Spell *spell = new Spell(m_caster, spellInfo, true, m_originalCasterGUID );
-
- SpellCastTargets targets;
- targets.setDestination(m_targets.m_destX,m_targets.m_destY,m_targets.m_destZ);
- spell->m_CastItem = m_CastItem;
- spell->prepare(&targets, NULL);
+ m_caster->CastSpell(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, spellInfo->Id, true, m_CastItem, 0, m_originalCasterGUID);
}
void Spell::EffectTeleportUnits(uint32 i)
@@ -2106,17 +2241,12 @@ void Spell::EffectApplyAura(uint32 i)
if(!unitTarget)
return;
- SpellImmuneList const& list = unitTarget->m_spellImmune[IMMUNITY_STATE];
- for(SpellImmuneList::const_iterator itr = list.begin(); itr != list.end(); ++itr)
- if(itr->type == m_spellInfo->EffectApplyAuraName[i])
- return;
-
// ghost spell check, allow apply any auras at player loading in ghost mode (will be cleanup after load)
if( !unitTarget->isAlive() && m_spellInfo->Id != 20584 && m_spellInfo->Id != 8326 &&
(unitTarget->GetTypeId()!=TYPEID_PLAYER || !((Player*)unitTarget)->GetSession()->PlayerLoading()) )
return;
- Unit* caster = m_originalCasterGUID ? m_originalCaster : m_caster;
+ Unit* caster = m_originalCaster ? m_originalCaster : m_caster;
if(!caster)
return;
@@ -2129,6 +2259,13 @@ void Spell::EffectApplyAura(uint32 i)
unitTarget->ApplyDiminishingToDuration(m_diminishGroup,duration,caster,m_diminishLevel);
Aur->setDiminishGroup(m_diminishGroup);
+ //apply mods only here, area auras don't have duration
+ duration = caster->ModSpellDuration(m_spellInfo, i, unitTarget, duration);
+
+ //mod duration of channeled aura by spell haste
+ if (IsChanneledSpell(m_spellInfo))
+ m_caster->ModSpellCastTime(m_spellInfo, duration);
+
// if Aura removed and deleted, do not continue.
if(duration== 0 && !(Aur->IsPermanent()))
{
@@ -2153,33 +2290,8 @@ void Spell::EffectApplyAura(uint32 i)
if(!Aur)
return;
- // TODO Make a way so it works for every related spell!
- if(unitTarget->GetTypeId()==TYPEID_PLAYER) // Negative buff should only be applied on players
- {
- uint32 spellId = 0;
- if(m_spellInfo->CasterAuraStateNot==AURA_STATE_WEAKENED_SOUL || m_spellInfo->TargetAuraStateNot==AURA_STATE_WEAKENED_SOUL)
- spellId = 6788; // Weakened Soul
- else if(m_spellInfo->CasterAuraStateNot==AURA_STATE_FORBEARANCE || m_spellInfo->TargetAuraStateNot==AURA_STATE_FORBEARANCE)
- spellId = 25771; // Forbearance
- else if(m_spellInfo->CasterAuraStateNot==AURA_STATE_HYPOTHERMIA)
- spellId = 41425; // Hypothermia
- else if (m_spellInfo->Mechanic == MECHANIC_BANDAGE) // Bandages
- spellId = 11196; // Recently Bandaged
- else if( (m_spellInfo->AttributesEx & 0x20) && (m_spellInfo->AttributesEx2 & 0x20000) )
- spellId = 23230; // Blood Fury - Healing Reduction
-
- SpellEntry const *AdditionalSpellInfo = sSpellStore.LookupEntry(spellId);
- if (AdditionalSpellInfo)
- {
- // applied at target by target
- Aura* AdditionalAura = CreateAura(AdditionalSpellInfo, 0, NULL, unitTarget,unitTarget, 0);
- unitTarget->AddAura(AdditionalAura);
- sLog.outDebug("Spell: Additional Aura is: %u", AdditionalSpellInfo->EffectApplyAuraName[0]);
- }
- }
-
// Prayer of Mending (jump animation), we need formal caster instead original for correct animation
- if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && (m_spellInfo->SpellFamilyFlags & 0x00002000000000LL))
+ if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && (m_spellInfo->SpellFamilyFlags[1] & 0x000020))
m_caster->CastSpell(unitTarget, 41637, true, NULL, Aur, m_originalCasterGUID);
}
@@ -2230,7 +2342,8 @@ void Spell::EffectPowerDrain(uint32 i)
unitTarget->ModifyPower(drain_power,-new_damage);
- if(drain_power == POWER_MANA)
+ // Don`t restore from self drain
+ if(drain_power == POWER_MANA && m_caster != unitTarget)
{
float manaMultiplier = m_spellInfo->EffectMultipleValue[i];
if(manaMultiplier==0)
@@ -2371,7 +2484,7 @@ void Spell::SpellDamageHeal(uint32 /*i*/)
Unit::AuraList const& mDummyAuras = m_caster->GetAurasByType(SPELL_AURA_DUMMY);
for(Unit::AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i)
if((*i)->GetId() == 45062)
- damageAmount+=(*i)->GetModifierValue();
+ damageAmount+=(*i)->GetModifier()->m_amount;
if (damageAmount)
m_caster->RemoveAurasDueToSpell(45062);
@@ -2386,7 +2499,7 @@ void Spell::SpellDamageHeal(uint32 /*i*/)
for(Unit::AuraList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)
{
if((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID
- && ((*i)->GetSpellProto()->SpellFamilyFlags == 0x40 || (*i)->GetSpellProto()->SpellFamilyFlags == 0x10) )
+ && ((*i)->GetSpellProto()->SpellFamilyFlags.IsEqual(0x40) || (*i)->GetSpellProto()->SpellFamilyFlags.IsEqual(0x10)) )
{
if(!targetAura || (*i)->GetAuraDuration() < targetAura->GetAuraDuration())
targetAura = *i;
@@ -2406,21 +2519,21 @@ void Spell::SpellDamageHeal(uint32 /*i*/)
idx++;
}
- int32 tickheal = targetAura->GetModifierValuePerStack();
+ int32 tickheal = targetAura->GetModifier()->m_amount;
if(Unit* auraCaster = targetAura->GetCaster())
- tickheal = auraCaster->SpellHealingBonus(targetAura->GetSpellProto(), tickheal, DOT, unitTarget);
+ tickheal = auraCaster->SpellHealingBonus(unitTarget, targetAura->GetSpellProto(), tickheal, DOT);
//int32 tickheal = targetAura->GetSpellProto()->EffectBasePoints[idx] + 1;
//It is said that talent bonus should not be included
- //int32 tickheal = targetAura->GetModifierValue();
+
int32 tickcount = GetSpellDuration(targetAura->GetSpellProto()) / targetAura->GetSpellProto()->EffectAmplitude[idx];
addhealth += tickheal * tickcount;
- unitTarget->RemoveAurasDueToCasterSpell(targetAura->GetId(), targetAura->GetCasterGUID());
+ unitTarget->RemoveAurasByCasterSpell(targetAura->GetId(), targetAura->GetCasterGUID());
//addhealth += tickheal * tickcount;
//addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth,HEAL, unitTarget);
}
else
- addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth,HEAL, unitTarget);
+ addhealth = caster->SpellHealingBonus(unitTarget, m_spellInfo, addhealth, HEAL);
m_damage -= addhealth;
}
@@ -2461,7 +2574,7 @@ void Spell::EffectHealMechanical( uint32 /*i*/ )
if (!caster)
return;
- uint32 addhealth = caster->SpellHealingBonus(m_spellInfo, uint32(damage), HEAL, unitTarget);
+ uint32 addhealth = caster->SpellHealingBonus(unitTarget, m_spellInfo, uint32(damage), HEAL);
caster->SendHealSpellLog(unitTarget, m_spellInfo->Id, addhealth, false);
unitTarget->ModifyHealth( int32(damage) );
}
@@ -2492,7 +2605,7 @@ void Spell::EffectHealthLeech(uint32 i)
if(m_caster->isAlive())
{
- new_damage = m_caster->SpellHealingBonus(m_spellInfo, new_damage, HEAL, m_caster);
+ new_damage = m_caster->SpellHealingBonus(m_caster, m_spellInfo, new_damage, HEAL);
m_caster->ModifyHealth(new_damage);
@@ -2545,8 +2658,8 @@ void Spell::DoCreateItem(uint32 i, uint32 itemtype)
if (num_to_add < 1)
num_to_add = 1;
- if (num_to_add > pProto->Stackable)
- num_to_add = pProto->Stackable;
+ if (num_to_add > pProto->GetMaxStackSize())
+ num_to_add = pProto->GetMaxStackSize();
// init items_count to 1, since 1 item will be created regardless of specialization
int items_count=1;
@@ -2638,6 +2751,21 @@ void Spell::EffectCreateItem(uint32 i)
DoCreateItem(i,m_spellInfo->EffectItemType[i]);
}
+void Spell::EffectCreateItem2(uint32 i)
+{
+ // special case: generate using spell_loot_template
+ if(!m_spellInfo->EffectItemType[i])
+ {
+ if(m_caster->GetTypeId()!=TYPEID_PLAYER)
+ return;
+
+ // create some random items
+ ((Player*)m_caster)->AutoStoreLoot(m_spellInfo->Id,LootTemplates_Spell);
+ return;
+ }
+ DoCreateItem(i,m_spellInfo->EffectItemType[i]);
+}
+
void Spell::EffectPersistentAA(uint32 i)
{
float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
@@ -2668,6 +2796,8 @@ void Spell::EffectEnergize(uint32 i)
if(m_spellInfo->EffectMiscValue[i] < 0 || m_spellInfo->EffectMiscValue[i] >= MAX_POWERS)
return;
+ Powers power = Powers(m_spellInfo->EffectMiscValue[i]);
+
// Some level depends spells
int multiplier = 0;
int level_diff = 0;
@@ -2698,8 +2828,6 @@ void Spell::EffectEnergize(uint32 i)
if(damage < 0)
return;
- Powers power = Powers(m_spellInfo->EffectMiscValue[i]);
-
if(unitTarget->GetMaxPower(power) == 0)
return;
@@ -2767,7 +2895,7 @@ void Spell::EffectEnergisePct(uint32 i)
uint32 gain = damage * maxPower / 100;
unitTarget->ModifyPower(power, gain);
- m_caster->SendEnergizeSpellLog(unitTarget, m_spellInfo->Id, damage, power);
+ m_caster->SendEnergizeSpellLog(unitTarget, m_spellInfo->Id, gain, power);
}
void Spell::SendLoot(uint64 guid, LootType loottype)
@@ -2930,10 +3058,10 @@ void Spell::EffectOpenLock(uint32 /*i*/)
}
// check key
- for(int i = 0; i < 5; ++i)
+ for(int i = 0; i < 8; ++i)
{
- // type==1 This means lockInfo->key[i] is an item
- if(lockInfo->keytype[i]==LOCK_KEY_ITEM && lockInfo->key[i] && m_CastItem && m_CastItem->GetEntry()==lockInfo->key[i])
+ // Type==1 This means lockInfo->Index[i] is an item
+ if(lockInfo->Type[i]==LOCK_KEY_ITEM && lockInfo->Index[i] && m_CastItem && m_CastItem->GetEntry()==lockInfo->Index[i])
{
SendLoot(guid, loottype);
return;
@@ -2951,9 +3079,9 @@ void Spell::EffectOpenLock(uint32 /*i*/)
// skill bonus provided by casting spell (mostly item spells)
uint32 spellSkillBonus = uint32(damage/*m_currentBasePoints[0]+1*/);
- uint32 reqSkillValue = lockInfo->requiredminingskill;
+ uint32 reqSkillValue = lockInfo->Skill[0];
- if(lockInfo->requiredlockskill) // required pick lock skill applying
+ if(lockInfo->Skill[1]) // required pick lock skill applying
{
if(SkillId != SKILL_LOCKPICKING) // wrong skill (cheating?)
{
@@ -2961,7 +3089,7 @@ void Spell::EffectOpenLock(uint32 /*i*/)
return;
}
- reqSkillValue = lockInfo->requiredlockskill;
+ reqSkillValue = lockInfo->Skill[1];
}
else if(SkillId == SKILL_LOCKPICKING) // apply picklock skill to wrong target
{
@@ -3144,6 +3272,9 @@ void Spell::EffectSummonType(uint32 i)
case SUMMON_TYPE_POSESSED2:
case SUMMON_TYPE_POSESSED3:
EffectSummonPossessed(i);
+ case SUMMON_TYPE_FORCE_OF_NATURE:
+ case SUMMON_TYPE_GUARDIAN2:
+ EffectSummonGuardian(i);
break;
case SUMMON_TYPE_WILD:
EffectSummonWild(i);
@@ -3191,7 +3322,7 @@ void Spell::EffectSummon(uint32 i)
Pet* spawnCreature = new Pet(SUMMON_PET);
spawnCreature->setActive(m_caster->isActive());
- if(spawnCreature->LoadPetFromDB(m_caster,pet_entry))
+ if(m_caster->GetTypeId()==TYPEID_PLAYER && spawnCreature->LoadPetFromDB((Player*)m_caster,pet_entry))
{
// set timer for unsummon
int32 duration = GetSpellDuration(m_spellInfo);
@@ -3203,7 +3334,8 @@ void Spell::EffectSummon(uint32 i)
Map *map = m_caster->GetMap();
uint32 pet_number = objmgr.GeneratePetNumber();
- if(!spawnCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_PET),map,m_spellInfo->EffectMiscValue[i], pet_number))
+ if(!spawnCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_PET),map,m_caster->GetPhaseMask(),
+ m_spellInfo->EffectMiscValue[i], pet_number))
{
sLog.outErrorDb("Spell::EffectSummon: no such creature entry %u",m_spellInfo->EffectMiscValue[i]);
delete spawnCreature;
@@ -3288,8 +3420,8 @@ void Spell::EffectLearnSpell(uint32 i)
Player *player = (Player*)unitTarget;
- uint32 spellToLearn = (m_spellInfo->Id==SPELL_ID_GENERIC_LEARN) ? damage : m_spellInfo->EffectTriggerSpell[i];
- player->learnSpell(spellToLearn);
+ uint32 spellToLearn = ((m_spellInfo->Id==SPELL_ID_GENERIC_LEARN) || (m_spellInfo->Id==SPELL_ID_GENERIC_LEARN_PET)) ? damage : m_spellInfo->EffectTriggerSpell[i];
+ player->learnSpell(spellToLearn,false);
sLog.outDebug( "Spell: Player %u have learned spell %u from NpcGUID=%u", player->GetGUIDLow(), spellToLearn, m_caster->GetGUIDLow() );
}
@@ -3385,12 +3517,7 @@ void Spell::EffectDispel(uint32 i)
SpellEntry const* spellInfo = sSpellStore.LookupEntry(j->first);
data << uint32(spellInfo->Id); // Spell Id
data << uint8(0); // 0 - dispelled !=0 cleansed
- if(spellInfo->StackAmount!= 0)
- {
- //Why are Aura's Removed by EffIndex? Auras should be removed as a whole.....
- unitTarget->RemoveSingleAuraFromStackByDispel(spellInfo->Id);
- }
- else
+ //Why are Aura's Removed by EffIndex? Auras should be removed as a whole.....
unitTarget->RemoveAurasDueToSpellByDispel(spellInfo->Id, j->second, m_caster);
}
m_caster->SendMessageToSet(&data, true);
@@ -3658,7 +3785,8 @@ void Spell::EffectSummonGuardian(uint32 i)
Map *map = m_caster->GetMap();
uint32 pet_number = objmgr.GeneratePetNumber();
- if(!spawnCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_PET), map,m_spellInfo->EffectMiscValue[i], pet_number))
+ if(!spawnCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_PET), map,m_caster->GetPhaseMask(),
+ m_spellInfo->EffectMiscValue[i], pet_number))
{
sLog.outError("no such creature entry %u",m_spellInfo->EffectMiscValue[i]);
delete spawnCreature;
@@ -3797,7 +3925,7 @@ void Spell::EffectTradeSkill(uint32 /*i*/)
// ((Player*)unitTarget)->SetSkill(skillid,skillval?skillval:1,skillmax+75);
}
-void Spell::EffectEnchantItemPerm(uint32 i)
+void Spell::EffectEnchantItemPerm(uint32 effect_idx)
{
if(m_caster->GetTypeId() != TYPEID_PLAYER)
return;
@@ -3806,37 +3934,95 @@ void Spell::EffectEnchantItemPerm(uint32 i)
Player* p_caster = (Player*)m_caster;
+ // not grow at item use at item case
p_caster->UpdateCraftSkill(m_spellInfo->Id);
- if (m_spellInfo->EffectMiscValue[i])
+ uint32 enchant_id = m_spellInfo->EffectMiscValue[effect_idx];
+ if (!enchant_id)
+ return;
+
+ SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
+ if(!pEnchant)
+ return;
+
+ // item can be in trade slot and have owner diff. from caster
+ Player* item_owner = itemTarget->GetOwner();
+ if(!item_owner)
+ return;
+
+ if(item_owner!=p_caster && p_caster->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE) )
{
- uint32 enchant_id = m_spellInfo->EffectMiscValue[i];
+ sLog.outCommand(p_caster->GetSession()->GetAccountId(),"GM %s (Account: %u) enchanting(perm): %s (Entry: %d) for player: %s (Account: %u)",
+ p_caster->GetName(),p_caster->GetSession()->GetAccountId(),
+ itemTarget->GetProto()->Name1,itemTarget->GetEntry(),
+ item_owner->GetName(),item_owner->GetSession()->GetAccountId());
+ }
- SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
- if(!pEnchant)
- return;
+ // remove old enchanting before applying new if equipped
+ item_owner->ApplyEnchantment(itemTarget,PERM_ENCHANTMENT_SLOT,false);
- // item can be in trade slot and have owner diff. from caster
- Player* item_owner = itemTarget->GetOwner();
- if(!item_owner)
- return;
+ itemTarget->SetEnchantment(PERM_ENCHANTMENT_SLOT, enchant_id, 0, 0);
+
+ // add new enchanting if equipped
+ item_owner->ApplyEnchantment(itemTarget,PERM_ENCHANTMENT_SLOT,true);
+}
+
+void Spell::EffectEnchantItemPrismatic(uint32 effect_idx)
+{
+ if(m_caster->GetTypeId() != TYPEID_PLAYER)
+ return;
+ if (!itemTarget)
+ return;
+
+ Player* p_caster = (Player*)m_caster;
+
+ uint32 enchant_id = m_spellInfo->EffectMiscValue[effect_idx];
+ if (!enchant_id)
+ return;
+
+ SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
+ if(!pEnchant)
+ return;
- if(item_owner!=p_caster && p_caster->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE) )
+ // support only enchantings with add socket in this slot
+ {
+ bool add_socket = false;
+ for(int i = 0; i < 3; ++i)
{
- sLog.outCommand(p_caster->GetSession()->GetAccountId(),"GM %s (Account: %u) enchanting(perm): %s (Entry: %d) for player: %s (Account: %u)",
- p_caster->GetName(),p_caster->GetSession()->GetAccountId(),
- itemTarget->GetProto()->Name1,itemTarget->GetEntry(),
- item_owner->GetName(),item_owner->GetSession()->GetAccountId());
+ if(pEnchant->type[i]==ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET)
+ {
+ add_socket = true;
+ break;
+ }
}
+ if(!add_socket)
+ {
+ sLog.outError("Spell::EffectEnchantItemPrismatic: attempt apply enchant spell %u with SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC (%u) but without ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET (u), not suppoted yet.",
+ m_spellInfo->Id,SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC,ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET);
+ return;
+ }
+ }
- // remove old enchanting before applying new if equipped
- item_owner->ApplyEnchantment(itemTarget,PERM_ENCHANTMENT_SLOT,false);
-
- itemTarget->SetEnchantment(PERM_ENCHANTMENT_SLOT, enchant_id, 0, 0);
+ // item can be in trade slot and have owner diff. from caster
+ Player* item_owner = itemTarget->GetOwner();
+ if(!item_owner)
+ return;
- // add new enchanting if equipped
- item_owner->ApplyEnchantment(itemTarget,PERM_ENCHANTMENT_SLOT,true);
+ if(item_owner!=p_caster && p_caster->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE) )
+ {
+ sLog.outCommand(p_caster->GetSession()->GetAccountId(),"GM %s (Account: %u) enchanting(perm): %s (Entry: %d) for player: %s (Account: %u)",
+ p_caster->GetName(),p_caster->GetSession()->GetAccountId(),
+ itemTarget->GetProto()->Name1,itemTarget->GetEntry(),
+ item_owner->GetName(),item_owner->GetSession()->GetAccountId());
}
+
+ // remove old enchanting before applying new if equipped
+ item_owner->ApplyEnchantment(itemTarget,PRISMATIC_ENCHANTMENT_SLOT,false);
+
+ itemTarget->SetEnchantment(PRISMATIC_ENCHANTMENT_SLOT, enchant_id, 0, 0);
+
+ // add new enchanting if equipped
+ item_owner->ApplyEnchantment(itemTarget,PRISMATIC_ENCHANTMENT_SLOT,true);
}
void Spell::EffectEnchantItemTmp(uint32 i)
@@ -3931,13 +4117,13 @@ void Spell::EffectEnchantItemTmp(uint32 i)
else if(m_spellInfo->SpellFamilyName==SPELLFAMILY_SHAMAN)
duration = 1800; // 30 mins
// other cases with this SpellVisual already selected
- else if(m_spellInfo->SpellVisual==215)
+ else if(m_spellInfo->SpellVisual[0]==215)
duration = 1800; // 30 mins
// some fishing pole bonuses
- else if(m_spellInfo->SpellVisual==563)
+ else if(m_spellInfo->SpellVisual[0]==563)
duration = 600; // 10 mins
// shaman rockbiter enchantments
- else if(m_spellInfo->SpellVisual==0)
+ else if(m_spellInfo->SpellVisual[0]==0)
duration = 1800; // 30 mins
else if(m_spellInfo->Id==29702)
duration = 300; // 5 mins
@@ -4000,14 +4186,16 @@ void Spell::EffectTameCreature(uint32 /*i*/)
creatureTarget->RemoveCorpse();
creatureTarget->SetHealth(0); // just for nice GM-mode view
+ uint32 level = (creatureTarget->getLevel() < (m_caster->getLevel() - 5)) ? (m_caster->getLevel() - 5) : creatureTarget->getLevel();
+
// prepare visual effect for levelup
- pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()-1);
+ pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
// add to world
pet->GetMap()->Add((Creature*)pet);
// visual effect for levelup
- pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel());
+ pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
// caster have pet now
m_caster->SetPet(pet);
@@ -4066,7 +4254,7 @@ void Spell::EffectSummonPet(uint32 i)
NewSummon->setActive(m_caster->isActive());
// petentry==0 for hunter "call pet" (current pet summoned if any)
- if(NewSummon->LoadPetFromDB(m_caster,petentry))
+ if(m_caster->GetTypeId() == TYPEID_PLAYER && NewSummon->LoadPetFromDB((Player*)m_caster,petentry))
{
if(NewSummon->getPetType()==SUMMON_PET)
{
@@ -4105,7 +4293,8 @@ void Spell::EffectSummonPet(uint32 i)
Map *map = m_caster->GetMap();
uint32 pet_number = objmgr.GeneratePetNumber();
- if(!NewSummon->Create(objmgr.GenerateLowGuid(HIGHGUID_PET), map, petentry, pet_number))
+ if(!NewSummon->Create(objmgr.GenerateLowGuid(HIGHGUID_PET), map, m_caster->GetPhaseMask(),
+ petentry, pet_number))
{
delete NewSummon;
return;
@@ -4151,10 +4340,12 @@ void Spell::EffectSummonPet(uint32 i)
// this enables pet details window (Shift+P)
// this enables popup window (pet dismiss, cancel), hunter pet additional flags set later
- NewSummon->SetUInt32Value(UNIT_FIELD_FLAGS,UNIT_FLAG_PVP_ATTACKABLE);
+ if(m_caster->GetTypeId() == TYPEID_PLAYER)
+ NewSummon->SetUInt32Value(UNIT_FIELD_FLAGS,UNIT_FLAG_PVP_ATTACKABLE);
NewSummon->InitStatsForLevel(petlevel);
NewSummon->InitPetCreateSpells();
+ NewSummon->InitTalentForLevel();
if(NewSummon->getPetType()==SUMMON_PET)
{
@@ -4212,7 +4403,6 @@ void Spell::EffectLearnPetSpell(uint32 i)
if(!learn_spellproto)
return;
- pet->SetTP(pet->m_TrainingPoints - pet->GetTPForSpell(learn_spellproto->Id));
pet->learnSpell(learn_spellproto->Id);
pet->SavePetToDB(PET_SAVE_AS_CURRENT);
@@ -4276,20 +4466,18 @@ void Spell::SpellDamageWeaponDmg(uint32 i)
case SPELLFAMILY_WARRIOR:
{
// Devastate bonus and sunder armor refresh
- if(m_spellInfo->SpellVisual == 671 && m_spellInfo->SpellIconID == 1508)
+ if(m_spellInfo->SpellVisual[0] == 671 && m_spellInfo->SpellIconID == 1508)
{
uint32 stack = 0;
-
Unit::AuraList const& list = unitTarget->GetAurasByType(SPELL_AURA_MOD_RESISTANCE);
for(Unit::AuraList::const_iterator itr=list.begin();itr!=list.end();++itr)
{
SpellEntry const *proto = (*itr)->GetSpellProto();
if(proto->SpellFamilyName == SPELLFAMILY_WARRIOR
- && proto->SpellFamilyFlags == SPELLFAMILYFLAG_WARRIOR_SUNDERARMOR)
+ && proto->SpellFamilyFlags.IsEqual(SPELLFAMILYFLAG_WARRIOR_SUNDERARMOR)
+ && (*itr)->GetCasterGUID() == m_caster->GetGUID())
{
- int32 duration = GetSpellDuration(proto);
- (*itr)->SetAuraDuration(duration);
- (*itr)->UpdateAuraDuration();
+ (*itr)->RefreshAura();
stack = (*itr)->GetStackAmount();
break;
}
@@ -4318,7 +4506,7 @@ void Spell::SpellDamageWeaponDmg(uint32 i)
if (!spellInfo)
continue;
- if (spellInfo->SpellFamilyFlags == SPELLFAMILYFLAG_WARRIOR_SUNDERARMOR
+ if (spellInfo->SpellFamilyFlags.IsEqual(SPELLFAMILYFLAG_WARRIOR_SUNDERARMOR)
&& spellInfo->Id != m_spellInfo->Id
&& spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR)
{
@@ -4327,19 +4515,21 @@ void Spell::SpellDamageWeaponDmg(uint32 i)
}
}
}
+ if (stack)
+ spell_bonus += stack * CalculateDamage(2, unitTarget);
}
break;
}
case SPELLFAMILY_ROGUE:
{
// Hemorrhage
- if(m_spellInfo->SpellFamilyFlags & 0x2000000)
+ if(m_spellInfo->SpellFamilyFlags[0] & 0x2000000)
{
if(m_caster->GetTypeId()==TYPEID_PLAYER)
((Player*)m_caster)->AddComboPoints(unitTarget, 1);
}
// Mutilate (for each hand)
- else if(m_spellInfo->SpellFamilyFlags & 0x600000000LL)
+ else if(m_spellInfo->SpellFamilyFlags[1] & 0x6)
{
bool found = false;
// fast check
@@ -4367,7 +4557,7 @@ void Spell::SpellDamageWeaponDmg(uint32 i)
case SPELLFAMILY_PALADIN:
{
// Seal of Command - receive benefit from Spell Damage and Healing
- if(m_spellInfo->SpellFamilyFlags & 0x00000002000000LL)
+ if(m_spellInfo->SpellFamilyFlags[0] & 0x2000000)
{
spell_bonus += int32(0.20f*m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)));
spell_bonus += int32(0.29f*m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget));
@@ -4378,7 +4568,7 @@ void Spell::SpellDamageWeaponDmg(uint32 i)
{
// Skyshatter Harness item set bonus
// Stormstrike
- if(m_spellInfo->SpellFamilyFlags & 0x001000000000LL)
+ if(m_spellInfo->SpellFamilyFlags[1] & 0x0010)
{
Unit::AuraList const& m_OverrideClassScript = m_caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
for(Unit::AuraList::const_iterator i = m_OverrideClassScript.begin(); i != m_OverrideClassScript.end(); ++i)
@@ -4396,7 +4586,7 @@ void Spell::SpellDamageWeaponDmg(uint32 i)
case SPELLFAMILY_DRUID:
{
// Mangle (Cat): CP
- if(m_spellInfo->SpellFamilyFlags==0x0000040000000000LL)
+ if(m_spellInfo->SpellFamilyFlags.IsEqual(0,0x00000400))
{
if(m_caster->GetTypeId()==TYPEID_PLAYER)
((Player*)m_caster)->AddComboPoints(unitTarget,1);
@@ -4481,33 +4671,6 @@ void Spell::SpellDamageWeaponDmg(uint32 i)
// Add melee damage bonuses (also check for negative)
m_caster->MeleeDamageBonus(unitTarget, &eff_damage, m_attackType, m_spellInfo);
m_damage+= eff_damage;
-
- // take ammo
- if(m_attackType == RANGED_ATTACK && m_caster->GetTypeId() == TYPEID_PLAYER)
- {
- Item *pItem = ((Player*)m_caster)->GetWeaponForAttack( RANGED_ATTACK );
-
- // wands don't have ammo
- if(!pItem || pItem->IsBroken() || pItem->GetProto()->SubClass==ITEM_SUBCLASS_WEAPON_WAND)
- return;
-
- if( pItem->GetProto()->InventoryType == INVTYPE_THROWN )
- {
- if(pItem->GetMaxStackCount()==1)
- {
- // decrease durability for non-stackable throw weapon
- ((Player*)m_caster)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_RANGED);
- }
- else
- {
- // decrease items amount for stackable throw weapon
- uint32 count = 1;
- ((Player*)m_caster)->DestroyItemCount( pItem, count, true);
- }
- }
- else if(uint32 ammo = ((Player*)m_caster)->GetUInt32Value(PLAYER_AMMO_ID))
- ((Player*)m_caster)->DestroyItemCount(ammo, 1, true);
- }
}
void Spell::EffectThreat(uint32 /*i*/)
@@ -4552,7 +4715,7 @@ void Spell::EffectInterruptCast(uint32 i)
{
if(m_originalCaster)
{
- int32 duration = m_originalCaster->CalculateSpellDuration(m_spellInfo, i, unitTarget);
+ int32 duration = m_originalCaster->ModSpellDuration(m_spellInfo, i, unitTarget, m_originalCaster->CalcSpellDuration(m_spellInfo));
unitTarget->ProhibitSpellScholl(GetSpellSchoolMask(unitTarget->m_currentSpells[i]->m_spellInfo), duration/*GetSpellDuration(m_spellInfo)*/);
}
unitTarget->InterruptSpell(i,false);
@@ -4584,7 +4747,7 @@ void Spell::EffectSummonObjectWild(uint32 i)
Map *map = target->GetMap();
if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), gameobject_id, map,
- x, y, z, target->GetOrientation(), 0, 0, 0, 0, 100, 1))
+ m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), 0, 0, 0, 0, 100, 1))
{
delete pGameObj;
return;
@@ -4632,7 +4795,7 @@ void Spell::EffectSummonObjectWild(uint32 i)
{
GameObject* linkedGO = new GameObject;
if(linkedGO->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), linkedEntry, map,
- x, y, z, target->GetOrientation(), 0, 0, 0, 0, 100, 1))
+ m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), 0, 0, 0, 0, 100, 1))
{
linkedGO->SetRespawnTime(duration > 0 ? duration/1000 : 0);
linkedGO->SetSpellId(m_spellInfo->Id);
@@ -4653,408 +4816,556 @@ void Spell::EffectScriptEffect(uint32 effIndex)
{
// TODO: we must implement hunter pet summon at login there (spell 6962)
- // by spell id
- switch(m_spellInfo->Id)
+ switch(m_spellInfo->SpellFamilyName)
{
- // PX-238 Winter Wondervolt TRAP
- case 26275:
+ case SPELLFAMILY_GENERIC:
{
- if( unitTarget->HasAura(26272,0)
- || unitTarget->HasAura(26157,0)
- || unitTarget->HasAura(26273,0)
- || unitTarget->HasAura(26274,0))
- return;
+ switch(m_spellInfo->Id)
+ {
+ // PX-238 Winter Wondervolt TRAP
+ case 26275:
+ {
+ uint32 spells[4] = { 26272, 26157, 26273, 26274 };
- uint32 iTmpSpellId;
+ // check presence
+ for(int j = 0; j < 4; ++j)
+ if(unitTarget->HasAura(spells[j],0))
+ return;
- switch(urand(0,3))
- {
- case 0:
- iTmpSpellId = 26272;
- break;
- case 1:
- iTmpSpellId = 26157;
- break;
- case 2:
- iTmpSpellId = 26273;
- break;
- case 3:
- iTmpSpellId = 26274;
- break;
- }
+ // select spell
+ uint32 iTmpSpellId = spells[urand(0,3)];
- unitTarget->CastSpell(unitTarget, iTmpSpellId, true);
+ // cast
+ unitTarget->CastSpell(unitTarget, iTmpSpellId, true);
+ return;
+ }
+ // Bending Shinbone
+ case 8856:
+ {
+ if(!itemTarget && m_caster->GetTypeId()!=TYPEID_PLAYER)
+ return;
- return;
- }
+ uint32 spell_id = 0;
+ switch(urand(1,5))
+ {
+ case 1: spell_id = 8854; break;
+ default: spell_id = 8855; break;
+ }
- // Bending Shinbone
- case 8856:
- {
- if(!itemTarget && m_caster->GetTypeId()!=TYPEID_PLAYER)
- return;
+ m_caster->CastSpell(m_caster,spell_id,true,NULL);
+ return;
+ }
+ // Brittle Armor - need remove one 24575 Brittle Armor aura
+ case 24590:
+ unitTarget->RemoveSingleSpellAurasFromStack(24575);
+ return;
+ // Mercurial Shield - need remove one 26464 Mercurial Shield aura
+ case 26465:
+ unitTarget->RemoveSingleSpellAurasFromStack(26464);
+ return;
+ // Orb teleport spells
+ case 25140:
+ case 25143:
+ case 25650:
+ case 25652:
+ case 29128:
+ case 29129:
+ case 35376:
+ case 35727:
+ {
+ if(!unitTarget)
+ return;
- uint32 spell_id = 0;
- switch(urand(1,5))
- {
- case 1: spell_id = 8854; break;
- default: spell_id = 8855; break;
- }
+ uint32 spellid;
+ switch(m_spellInfo->Id)
+ {
+ case 25140: spellid = 32571; break;
+ case 25143: spellid = 32572; break;
+ case 25650: spellid = 30140; break;
+ case 25652: spellid = 30141; break;
+ case 29128: spellid = 32568; break;
+ case 29129: spellid = 32569; break;
+ case 35376: spellid = 25649; break;
+ case 35727: spellid = 35730; break;
+ default:
+ return;
+ }
- m_caster->CastSpell(m_caster,spell_id,true,NULL);
- return;
- }
+ unitTarget->CastSpell(unitTarget,spellid,false);
+ return;
+ }
+ // Shadow Flame (All script effects, not just end ones to prevent player from dodging the last triggered spell)
+ case 22539:
+ case 22972:
+ case 22975:
+ case 22976:
+ case 22977:
+ case 22978:
+ case 22979:
+ case 22980:
+ case 22981:
+ case 22982:
+ case 22983:
+ case 22984:
+ case 22985:
+ {
+ if(!unitTarget || !unitTarget->isAlive())
+ return;
- // Healthstone creating spells
- case 6201:
- case 6202:
- case 5699:
- case 11729:
- case 11730:
- case 27230:
- {
- uint32 itemtype;
- uint32 rank = 0;
- Unit::AuraList const& mDummyAuras = unitTarget->GetAurasByType(SPELL_AURA_DUMMY);
- for(Unit::AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i)
- {
- if((*i)->GetId() == 18692)
+ // Onyxia Scale Cloak
+ if(unitTarget->GetDummyAura(22683))
+ return;
+
+ // Shadow Flame
+ m_caster->CastSpell(unitTarget, 22682, true);
+ return;
+ }
+ // Summon Black Qiraji Battle Tank
+ case 26656:
{
- rank = 1;
+ if(!unitTarget)
+ return;
+
+ // Prevent stacking of mounts
+ unitTarget->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
+
+ // Two separate mounts depending on area id (allows use both in and out of specific instance)
+ if (unitTarget->GetAreaId() == 3428)
+ unitTarget->CastSpell(unitTarget, 25863, false);
+ else
+ unitTarget->CastSpell(unitTarget, 26655, false);
break;
}
- else if((*i)->GetId() == 18693)
+ // Piccolo of the Flaming Fire
+ case 17512:
{
- rank = 2;
+ if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
+ return;
+ unitTarget->HandleEmoteCommand(EMOTE_STATE_DANCE);
break;
}
- }
+ // Mirren's Drinking Hat
+ case 29830:
+ {
+ uint32 item = 0;
+ switch ( urand(1,6) )
+ {
+ case 1:case 2:case 3:
+ item = 23584;break; // Loch Modan Lager
+ case 4:case 5:
+ item = 23585;break; // Stouthammer Lite
+ case 6:
+ item = 23586;break; // Aerie Peak Pale Ale
+ }
+ if (item)
+ DoCreateItem(effIndex,item);
+ break;
+ }
+ // Improved Sprint
+ case 30918:
+ {
+ // Removes snares and roots.
+ uint32 mechanic_mask = (1<<MECHANIC_ROOT) | (1<<MECHANIC_SNARE);
+ Unit::AuraMap& Auras = unitTarget->GetAuras();
+ for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next)
+ {
+ next = iter;
+ ++next;
+ Aura *aur = iter->second;
+ if (!aur->IsPositive()) //only remove negative spells
+ {
+ // check for mechanic mask
+ if(GetSpellMechanicMask(aur->GetSpellProto(), aur->GetEffIndex()) & mechanic_mask)
+ {
+ unitTarget->RemoveAurasDueToSpell(aur->GetId());
+ if(Auras.empty())
+ break;
+ else
+ next = Auras.begin();
+ }
+ }
+ }
+ break;
+ }
+ /*// Flame Crash
+ case 41126:
+ {
+ if(!unitTarget)
+ return;
- static uint32 const itypes[6][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
- };
+ unitTarget->CastSpell(unitTarget, 41131, true);
+ break;
+ }*/
+ // Draw Soul
+ case 40904:
+ {
+ if(!unitTarget)
+ return;
- switch(m_spellInfo->Id)
- {
- case 6201: itemtype=itypes[0][rank];break; // Minor Healthstone
- case 6202: itemtype=itypes[1][rank];break; // Lesser Healthstone
- case 5699: itemtype=itypes[2][rank];break; // Healthstone
- case 11729: itemtype=itypes[3][rank];break; // Greater Healthstone
- case 11730: itemtype=itypes[4][rank];break; // Major Healthstone
- case 27230: itemtype=itypes[5][rank];break; // Master Healthstone
- default:
- return;
- }
- DoCreateItem( effIndex, itemtype );
- return;
- }
- // Brittle Armor - need remove one 24575 Brittle Armor aura
- case 24590:
- unitTarget->RemoveSingleAuraFromStack(24575, 0);
- unitTarget->RemoveSingleAuraFromStack(24575, 1);
- return;
- // Mercurial Shield - need remove one 26464 Mercurial Shield aura
- case 26465:
- unitTarget->RemoveSingleAuraFromStack(26464, 0);
- return;
- // Orb teleport spells
- case 25140:
- case 25143:
- case 25650:
- case 25652:
- case 29128:
- case 29129:
- case 35376:
- case 35727:
- {
- if(!unitTarget)
- return;
+ unitTarget->CastSpell(m_caster, 40903, true);
+ break;
+ }
+ case 41931:
+ {
+ if(m_caster->GetTypeId() != TYPEID_PLAYER)
+ return;
- uint32 spellid;
- switch(m_spellInfo->Id)
- {
- case 25140: spellid = 32571; break;
- case 25143: spellid = 32572; break;
- case 25650: spellid = 30140; break;
- case 25652: spellid = 30141; break;
- case 29128: spellid = 32568; break;
- case 29129: spellid = 32569; break;
- case 35376: spellid = 25649; break;
- case 35727: spellid = 35730; break;
- default:
- return;
- }
+ int bag=19;
+ int slot=0;
+ Item* item = NULL;
+
+ while (bag < 256)
+ {
+ item = ((Player*)m_caster)->GetItemByPos(bag,slot);
+ if (item && item->GetEntry() == 38587) break;
+ slot++;
+ if (slot == 39)
+ {
+ slot = 0;
+ bag++;
+ }
+ }
+ if (bag < 256)
+ {
+ if (((Player*)m_caster)->GetItemByPos(bag,slot)->GetCount() == 1) ((Player*)m_caster)->RemoveItem(bag,slot,true);
+ else ((Player*)m_caster)->GetItemByPos(bag,slot)->SetCount(((Player*)m_caster)->GetItemByPos(bag,slot)->GetCount()-1);
+ // Spell 42518 (Braufest - Gratisprobe des Braufest herstellen)
+ m_caster->CastSpell(m_caster,42518,true);
+ return;
+ }
+ break;
+ }
+ // Force Cast - Portal Effect: Sunwell Isle
+ case 44876:
+ {
+ if(!unitTarget)
+ return;
- unitTarget->CastSpell(unitTarget,spellid,false);
- return;
- }
+ unitTarget->CastSpell(unitTarget, 44870, true);
+ break;
+ }
+ // Goblin Weather Machine
+ case 46203:
+ {
+ if(!unitTarget)
+ return;
- // Shadow Flame (All script effects, not just end ones to prevent player from dodging the last triggered spell)
- case 22539:
- case 22972:
- case 22975:
- case 22976:
- case 22977:
- case 22978:
- case 22979:
- case 22980:
- case 22981:
- case 22982:
- case 22983:
- case 22984:
- case 22985:
- {
- if(!unitTarget || !unitTarget->isAlive())
- return;
+ uint32 spellId;
+ switch(rand()%4)
+ {
+ case 0: spellId = 46740; break;
+ case 1: spellId = 46739; break;
+ case 2: spellId = 46738; break;
+ case 3: spellId = 46736; break;
+ }
+ unitTarget->CastSpell(unitTarget, spellId, true);
+ break;
+ }
+ //5,000 Gold
+ case 46642:
+ {
+ if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
+ return;
- // Onyxia Scale Cloak
- if(unitTarget->GetDummyAura(22683))
- return;
+ ((Player*)unitTarget)->ModifyMoney(50000000);
- // Shadow Flame
- m_caster->CastSpell(unitTarget, 22682, true);
- return;
- }
- break;
+ break;
+ }
+ // Emblazon Runeblade
+ case 51770:
+ {
+ if(!unitTarget)
+ return;
- // Summon Black Qiraji Battle Tank
- case 26656:
- {
- if(!unitTarget)
- return;
+ unitTarget->CastSpell(unitTarget,51771,false);
+ break;
+ }
+ // Death Gate
+ case 52751:
+ {
+ if(!unitTarget || unitTarget->getClass() != CLASS_DEATH_KNIGHT)
+ return;
+ // triggered spell is stored in m_spellInfo->EffectBasePoints[0]
+ unitTarget->CastSpell(unitTarget, damage, false);
+ break;
+ }
+ // random spell learn instead placeholder
+ case 60893: // Northrend Alchemy Research
+ case 61177: // Northrend Inscription Research
+ case 61288: // Minor Inscription Research
+ case 61756: // Northrend Inscription Research (FAST QA VERSION)
+ {
+ if(!IsExplicitDiscoverySpell(m_spellInfo))
+ {
+ sLog.outError("Wrong explicit discovery spell %u structure, or outdated...",m_spellInfo->Id);
+ return;
+ }
- // Prevent stacking of mounts
- unitTarget->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
+ if(m_caster->GetTypeId()!=TYPEID_PLAYER)
+ return;
+ Player* player = (Player*)m_caster;
- // Two separate mounts depending on area id (allows use both in and out of specific instance)
- if (unitTarget->GetAreaId() == 3428)
- unitTarget->CastSpell(unitTarget, 25863, false);
- else
- unitTarget->CastSpell(unitTarget, 26655, false);
- break;
- }
- // Piccolo of the Flaming Fire
- case 17512:
- {
- if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
- return;
- unitTarget->HandleEmoteCommand(EMOTE_STATE_DANCE);
- break;
- }
- // Netherbloom
- case 28702:
- {
- if(!unitTarget)
- return;
- // 25% chance of casting a random buff
- if(roll_chance_i(75))
- return;
+ // need replace effect 0 item by loot
+ uint32 reagent_id = m_spellInfo->EffectItemType[0];
- // triggered spells are 28703 to 28707
- // Note: some sources say, that there was the possibility of
- // receiving a debuff. However, this seems to be removed by a patch.
- const uint32 spellid = 28703;
+ if(!player->HasItemCount(reagent_id,1))
+ return;
- // don't overwrite an existing aura
- for(uint8 i=0; i<5; i++)
- if(unitTarget->HasAura(spellid+i, 0))
- return;
- unitTarget->CastSpell(unitTarget, spellid+urand(0, 4), true);
- break;
- }
+ // remove reagent
+ uint32 count = 1;
+ player->DestroyItemCount (reagent_id,count,true);
- // Nightmare Vine
- case 28720:
- {
- if(!unitTarget)
- return;
- // 25% chance of casting Nightmare Pollen
- if(roll_chance_i(75))
- return;
- unitTarget->CastSpell(unitTarget, 28721, true);
- break;
- }
+ // create some random items
+ player->AutoStoreLoot(m_spellInfo->Id,LootTemplates_Spell);
- // Mirren's Drinking Hat
- case 29830:
- {
- uint32 item = 0;
- switch ( urand(1,6) )
- {
- case 1: case 2: case 3: item = 23584; break;// Loch Modan Lager
- case 4: case 5: item = 23585; break;// Stouthammer Lite
- case 6: item = 23586; break;// Aerie Peak Pale Ale
+ // learn random explicit discovery recipe (if any)
+ if(uint32 discoveredSpell = GetExplicitDiscoverySpell(m_spellInfo->Id, player))
+ player->learnSpell(discoveredSpell,false);
+ return;
+ }
}
- if (item)
- DoCreateItem(effIndex,item);
break;
}
- // Improved Sprint
- case 30918:
+ case SPELLFAMILY_WARLOCK:
{
- // Removes snares and roots.
- uint32 mechanic_mask = (1<<MECHANIC_ROOT) | (1<<MECHANIC_SNARE);
- Unit::AuraMap& Auras = unitTarget->GetAuras();
- for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next)
+ switch(m_spellInfo->Id)
{
- next = iter;
- ++next;
- Aura *aur = iter->second;
- if (!aur->IsPositive()) //only remove negative spells
+ // Healthstone creating spells
+ case 6201:
+ case 6202:
+ case 5699:
+ case 11729:
+ case 11730:
+ case 27230:
+ case 47871:
+ case 47878:
{
- // check for mechanic mask
- if(GetSpellMechanicMask(aur->GetSpellProto(), aur->GetEffIndex()) & mechanic_mask)
+ uint32 itemtype;
+ uint32 rank = 0;
+ Unit::AuraList const& mDummyAuras = unitTarget->GetAurasByType(SPELL_AURA_DUMMY);
+ for(Unit::AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i)
{
- unitTarget->RemoveAurasDueToSpell(aur->GetId());
- if(Auras.empty())
+ if((*i)->GetId() == 18692)
+ {
+ rank = 1;
break;
- else
- next = Auras.begin();
+ }
+ else if((*i)->GetId() == 18693)
+ {
+ rank = 2;
+ break;
+ }
+ }
+
+ static uint32 const 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
+ };
+
+ switch(m_spellInfo->Id)
+ {
+ case 6201:
+ itemtype=itypes[0][rank];break; // Minor Healthstone
+ case 6202:
+ itemtype=itypes[1][rank];break; // Lesser Healthstone
+ case 5699:
+ itemtype=itypes[2][rank];break; // Healthstone
+ case 11729:
+ itemtype=itypes[3][rank];break; // Greater Healthstone
+ case 11730:
+ itemtype=itypes[4][rank];break; // Major Healthstone
+ case 27230:
+ itemtype=itypes[5][rank];break; // Master Healthstone
+ case 47871:
+ itemtype=itypes[6][rank];break; // Demonic Healthstone
+ case 47878:
+ itemtype=itypes[7][rank];break; // Fel Healthstone
+ default:
+ return;
}
+ DoCreateItem( effIndex, itemtype );
+ return;
}
}
break;
}
-
- // Goblin Weather Machine
- case 46203:
+ case SPELLFAMILY_PRIEST:
{
- if(!unitTarget)
- return;
-
- uint32 spellId;
- switch(rand()%4)
+ switch(m_spellInfo->Id)
{
- case 0:
- spellId=46740;
- break;
- case 1:
- spellId=46739;
- break;
- case 2:
- spellId=46738;
- break;
- case 3:
- spellId=46736;
+ // Pain and Suffering
+ case 47948:
+ {
+ if (!unitTarget)
+ return;
+ // Refresh Shadow Word: Pain on target
+ Unit::AuraMap& auras = unitTarget->GetAuras();
+ for(Unit::AuraMap::iterator itr = auras.begin(); itr != auras.end(); ++itr)
+ {
+ SpellEntry const *spellInfo = (*itr).second->GetSpellProto();
+ if( spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST &&
+ spellInfo->SpellFamilyFlags[0] & 0x8000 &&
+ (*itr).second->GetCasterGUID() == m_caster->GetGUID())
+ {
+ (*itr).second->RefreshAura();
+ return;
+ }
+ }
+ return;
+ }
+ default:
break;
}
- unitTarget->CastSpell(unitTarget, spellId, true);
break;
}
-
- }
-
- if(!unitTarget || !unitTarget->isAlive()) // can we remove this check?
- {
- sLog.outError("Spell %u in EffectScriptEffect does not have unitTarget", m_spellInfo->Id);
- return;
- }
-
- switch(m_spellInfo->Id)
- {
- // Dreaming Glory
- case 28698: unitTarget->CastSpell(unitTarget, 28694, true); break;
- // Needle Spine
- //case 39835: unitTarget->CastSpell(unitTarget, 39968, true); break;
- // Draw Soul
- case 40904: unitTarget->CastSpell(m_caster, 40903, true); break;
- // Flame Crash
- //case 41126: unitTarget->CastSpell(unitTarget, 41131, true); break;
- case 41931:
+ case SPELLFAMILY_HUNTER:
{
- int bag=19;
- int slot=0;
- Item* item = NULL;
-
- while (bag < 256)
+ switch(m_spellInfo->Id)
{
- item = ((Player*)m_caster)->GetItemByPos(bag,slot);
- if (item && item->GetEntry() == 38587) break;
- slot++;
- if (slot == 39)
+ // Chimera Shot
+ case 53209:
{
- slot = 0;
- bag++;
+ uint32 spellId = 0;
+ int32 basePoint = 0;
+ Unit::AuraMap& Auras = unitTarget->GetAuras();
+ for(Unit::AuraMap::iterator i = Auras.begin(); i != Auras.end(); ++i)
+ {
+ Aura *aura = (*i).second;
+ if (aura->GetCasterGUID() != m_caster->GetGUID())
+ continue;
+ // Search only Serpent Sting, Viper Sting, Scorpid Sting auras
+ uint64 familyFlag = aura->GetSpellProto()->SpellFamilyFlags;
+ if (!(familyFlag & 0x000000800000C000LL))
+ continue;
+ // Refresh aura duration
+ aura->RefreshAura();
+
+ // Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting.
+ if (familyFlag & 0x0000000000004000LL && aura->GetEffIndex() == 0)
+ {
+ spellId = 53353; // 53353 Chimera Shot - Serpent
+ basePoint = aura->GetModifier()->m_amount * 5 * 40 / 100;
+ }
+ // Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting.
+ if (familyFlag & 0x0000008000000000LL && aura->GetEffIndex() == 0)
+ {
+ spellId = 53358; // 53358 Chimera Shot - Viper
+ basePoint = aura->GetModifier()->m_amount * 4 * 60 / 100;
+ }
+ // Scorpid Sting - Attempts to Disarm the target for 10 sec. This effect cannot occur more than once per 1 minute.
+ if (familyFlag & 0x0000000000008000LL)
+ spellId = 53359; // 53359 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
+ //}
+ }
+ if (spellId)
+ m_caster->CastCustomSpell(unitTarget, spellId, &basePoint, 0, 0, false);
+ return;
}
+ default:
+ break;
}
- if (bag < 256)
- {
- if (((Player*)m_caster)->GetItemByPos(bag,slot)->GetCount() == 1) ((Player*)m_caster)->RemoveItem(bag,slot,true);
- else ((Player*)m_caster)->GetItemByPos(bag,slot)->SetCount(((Player*)m_caster)->GetItemByPos(bag,slot)->GetCount()-1);
- // Spell 42518 (Braufest - Gratisprobe des Braufest herstellen)
- m_caster->CastSpell(m_caster,42518,true);
- return;
- }
- }
- // Force Cast - Portal Effect: Sunwell Isle
- case 44876: unitTarget->CastSpell(unitTarget, 44870, true); break;
- //5,000 Gold
- case 46642:
- {
- if(unitTarget->GetTypeId() == TYPEID_PLAYER)
- ((Player*)unitTarget)->ModifyMoney(50000000);
break;
}
- }
-
- if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN )
- {
- switch(m_spellInfo->SpellFamilyFlags)
+ case SPELLFAMILY_PALADIN:
{
// Judgement
- case 0x800000:
+ if (m_spellInfo->SpellFamilyFlags[0] & 0x800000)
{
+ if(!unitTarget || !unitTarget->isAlive())
+ return;
+ uint32 spellId1 = 0;
uint32 spellId2 = 0;
- // all seals have aura dummy
+ // Judgement self add switch
+ switch (m_spellInfo->Id)
+ {
+ case 41467: break; // Judgement
+ case 53407: spellId1 = 20184; break; // Judgement of Justice
+ case 20271: // Judgement of Light
+ case 57774: spellId1 = 20185; break; // Judgement of Light
+ case 53408: spellId1 = 20186; break; // Judgement of Wisdom
+ default:
+ return;
+ }
+ // all seals have aura dummy in 2 effect
Unit::AuraList const& m_dummyAuras = m_caster->GetAurasByType(SPELL_AURA_DUMMY);
for(Unit::AuraList::const_iterator itr = m_dummyAuras.begin(); itr != m_dummyAuras.end(); ++itr)
{
SpellEntry const *spellInfo = (*itr)->GetSpellProto();
-
// search seal (all seals have judgement's aura dummy spell id in 2 effect
- if ( !spellInfo || !IsSealSpell((*itr)->GetSpellProto()) || (*itr)->GetEffIndex() != 2 )
+ if ((*itr)->GetEffIndex() != 2 || !spellInfo || !IsSealSpell(spellInfo))
continue;
-
- // must be calculated base at raw base points in spell proto, GetModifier()->m_value for S.Righteousness modified by SPELLMOD_DAMAGE
- spellId2 = (*itr)->GetSpellProto()->EffectBasePoints[2]+1;
-
- if(spellId2 <= 1)
+ spellId2 = (*itr)->GetModifier()->m_amount;
+ SpellEntry const *judge = sSpellStore.LookupEntry(spellId2);
+ if (!judge)
continue;
+ break;
+ }
+ if (spellId1)
+ m_caster->CastSpell(unitTarget, spellId1, true);
+ if (spellId2)
+ m_caster->CastSpell(unitTarget, spellId2, true);
+ return;
+ }
+ }
+ case SPELLFAMILY_POTION:
+ {
+ switch(m_spellInfo->Id)
+ {
+ // Dreaming Glory
+ case 28698:
+ {
+ if(!unitTarget)
+ return;
+ unitTarget->CastSpell(unitTarget, 28694, true);
+ break;
+ }
+ // Netherbloom
+ case 28702:
+ {
+ if(!unitTarget)
+ return;
+ // 25% chance of casting a random buff
+ if(roll_chance_i(75))
+ return;
- // found, remove seal
- m_caster->RemoveAurasDueToSpell((*itr)->GetId());
-
- // Sanctified Judgement
- Unit::AuraList const& m_auras = m_caster->GetAurasByType(SPELL_AURA_DUMMY);
- for(Unit::AuraList::const_iterator i = m_auras.begin(); i != m_auras.end(); ++i)
- {
- if ((*i)->GetSpellProto()->SpellIconID == 205 && (*i)->GetSpellProto()->Attributes == 0x01D0LL)
- {
- int32 chance = (*i)->GetModifier()->m_amount;
- if ( roll_chance_i(chance) )
- {
- int32 mana = spellInfo->manaCost;
- if ( Player* modOwner = m_caster->GetSpellModOwner() )
- modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_COST, mana);
- mana = int32(mana* 0.8f);
- m_caster->CastCustomSpell(m_caster,31930,&mana,NULL,NULL,true,NULL,*i);
- }
- break;
- }
- }
+ // triggered spells are 28703 to 28707
+ // Note: some sources say, that there was the possibility of
+ // receiving a debuff. However, this seems to be removed by a patch.
+ const uint32 spellid = 28703;
+ // don't overwrite an existing aura
+ for(uint8 i=0; i<5; i++)
+ if(unitTarget->HasAura(spellid+i, 0))
+ return;
+ unitTarget->CastSpell(unitTarget, spellid+urand(0, 4), true);
break;
}
- m_caster->CastSpell(unitTarget,spellId2,true);
- return;
+ // Nightmare Vine
+ case 28720:
+ {
+ if(!unitTarget)
+ return;
+ // 25% chance of casting Nightmare Pollen
+ if(roll_chance_i(75))
+ return;
+ unitTarget->CastSpell(unitTarget, 28721, true);
+ break;
+ }
}
+ break;
}
}
@@ -5070,7 +5381,7 @@ void Spell::EffectSanctuary(uint32 /*i*/)
std::list<Unit*> targets;
Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(unitTarget, unitTarget, World::GetMaxVisibleDistance());
- Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(targets, u_check);
+ Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(unitTarget, targets, u_check);
unitTarget->VisitNearbyObject(World::GetMaxVisibleDistance(), searcher);
for(std::list<Unit*>::iterator iter = targets.begin(); iter != targets.end(); ++iter)
{
@@ -5090,7 +5401,7 @@ void Spell::EffectSanctuary(uint32 /*i*/)
unitTarget->CombatStop();
unitTarget->getHostilRefManager().deleteReferences(); // stop all fighting
// Vanish allows to remove all threat and cast regular stealth so other spells can be used
- if(m_spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && (m_spellInfo->SpellFamilyFlags & SPELLFAMILYFLAG_ROGUE_VANISH))
+ if(m_spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && (m_spellInfo->SpellFamilyFlags[0] & SPELLFAMILYFLAG_ROGUE_VANISH))
{
((Player *)m_caster)->RemoveSpellsCausingAura(SPELL_AURA_MOD_ROOT);
}
@@ -5125,6 +5436,7 @@ void Spell::EffectDuel(uint32 i)
// Players can only fight a duel with each other outside (=not inside dungeons and not in capital cities)
// Don't have to check the target's map since you cannot challenge someone across maps
if(caster->GetMap()->Instanceable())
+ //if( mapid != 0 && mapid != 1 && mapid != 530 && mapid != 571 && mapid != 609)
{
SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
return;
@@ -5150,7 +5462,8 @@ void Spell::EffectDuel(uint32 i)
uint32 gameobject_id = m_spellInfo->EffectMiscValue[i];
Map *map = m_caster->GetMap();
- if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), gameobject_id, map,
+ if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), gameobject_id,
+ map, m_caster->GetPhaseMask(),
m_caster->GetPositionX()+(unitTarget->GetPositionX()-m_caster->GetPositionX())/2 ,
m_caster->GetPositionY()+(unitTarget->GetPositionY()-m_caster->GetPositionY())/2 ,
m_caster->GetPositionZ(),
@@ -5263,6 +5576,43 @@ void Spell::EffectActivateObject(uint32 effect_idx)
sWorld.ScriptCommandStart(activateCommand, delay_secs, m_caster, gameObjTarget);
}
+void Spell::EffectApplyGlyph(uint32 i)
+{
+ if(m_caster->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ Player *player = (Player*)m_caster;
+
+ // remove old glyph
+ if(uint32 oldglyph = player->GetGlyph(m_glyphIndex))
+ {
+ if(GlyphPropertiesEntry const *old_gp = sGlyphPropertiesStore.LookupEntry(oldglyph))
+ {
+ player->RemoveAurasDueToSpell(old_gp->SpellId);
+ player->SetGlyph(m_glyphIndex, 0);
+ }
+ }
+
+ // apply new one
+ if(uint32 glyph = m_spellInfo->EffectMiscValue[i])
+ {
+ if(GlyphPropertiesEntry const *gp = sGlyphPropertiesStore.LookupEntry(glyph))
+ {
+ if(GlyphSlotEntry const *gs = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex)))
+ {
+ if(gp->TypeFlags != gs->TypeFlags)
+ {
+ SendCastResult(SPELL_FAILED_INVALID_GLYPH);
+ return; // glyph slot missmatch
+ }
+ }
+
+ player->CastSpell(m_caster, gp->SpellId, true);
+ player->SetGlyph(m_glyphIndex, glyph);
+ }
+ }
+}
+
void Spell::EffectSummonTotem(uint32 i)
{
uint8 slot = 0;
@@ -5296,7 +5646,8 @@ void Spell::EffectSummonTotem(uint32 i)
Totem* pTotem = new Totem;
- if(!pTotem->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), m_caster->GetMap(), m_spellInfo->EffectMiscValue[i], team ))
+ if(!pTotem->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), m_caster->GetMap(), m_caster->GetPhaseMask(),
+ m_spellInfo->EffectMiscValue[i], team ))
{
delete pTotem;
return;
@@ -5331,10 +5682,9 @@ void Spell::EffectSummonTotem(uint32 i)
}
pTotem->SetUInt32Value(UNIT_CREATED_BY_SPELL,m_spellInfo->Id);
- pTotem->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_PVP_ATTACKABLE);
- pTotem->ApplySpellImmune(m_spellInfo->Id,IMMUNITY_STATE,SPELL_AURA_MOD_FEAR,true);
- pTotem->ApplySpellImmune(m_spellInfo->Id,IMMUNITY_STATE,SPELL_AURA_TRANSFORM,true);
+ if(m_caster->GetTypeId() == TYPEID_PLAYER)
+ pTotem->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_PVP_ATTACKABLE);
pTotem->Summon(m_caster);
@@ -5429,7 +5779,8 @@ void Spell::EffectFeedPet(uint32 i)
Player *_player = (Player*)m_caster;
- if(!itemTarget)
+ Item* foodItem = m_targets.getItemTarget();
+ if(!foodItem)
return;
Pet *pet = _player->GetPet();
@@ -5439,15 +5790,15 @@ void Spell::EffectFeedPet(uint32 i)
if(!pet->isAlive())
return;
- int32 benefit = pet->GetCurrentFoodBenefitLevel(itemTarget->GetProto()->ItemLevel);
+ int32 benefit = pet->GetCurrentFoodBenefitLevel(foodItem->GetProto()->ItemLevel);
if(benefit <= 0)
return;
uint32 count = 1;
- _player->DestroyItemCount(itemTarget,count,true);
+ _player->DestroyItemCount(foodItem,count,true);
// TODO: fix crash when a spell has two effects, both pointed at the same item target
- m_caster->CastCustomSpell(m_caster,m_spellInfo->EffectTriggerSpell[i],&benefit,NULL,NULL,true);
+ m_caster->CastCustomSpell(pet,m_spellInfo->EffectTriggerSpell[i],&benefit,NULL,NULL,true);
}
void Spell::EffectDismissPet(uint32 /*i*/)
@@ -5507,7 +5858,8 @@ void Spell::EffectSummonObject(uint32 i)
m_caster->GetClosePoint(x,y,z,DEFAULT_WORLD_OBJECT_SIZE);
Map *map = m_caster->GetMap();
- if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), go_id, map, x, y, z, m_caster->GetOrientation(), 0, 0, rot2, rot3, 0, 1))
+ if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), go_id, map,
+ m_caster->GetPhaseMask(), x, y, z, m_caster->GetOrientation(), 0, 0, rot2, rot3, 0, 1))
{
delete pGameObj;
return;
@@ -5586,18 +5938,14 @@ void Spell::EffectAddExtraAttacks(uint32 /*i*/)
void Spell::EffectParry(uint32 /*i*/)
{
- if (unitTarget->GetTypeId() == TYPEID_PLAYER)
- {
+ if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER)
((Player*)unitTarget)->SetCanParry(true);
- }
}
void Spell::EffectBlock(uint32 /*i*/)
{
- if (unitTarget->GetTypeId() != TYPEID_PLAYER)
- return;
-
- ((Player*)unitTarget)->SetCanBlock(true);
+ if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)unitTarget)->SetCanBlock(true);
}
void Spell::EffectMomentMove(uint32 i)
@@ -5808,8 +6156,8 @@ void Spell::EffectSummonCritter(uint32 i)
Map *map = m_caster->GetMap();
uint32 pet_number = objmgr.GeneratePetNumber();
- if(!critter->Create(objmgr.GenerateLowGuid(HIGHGUID_PET),
- map, pet_entry, pet_number))
+ if(!critter->Create(objmgr.GenerateLowGuid(HIGHGUID_PET), map, m_caster->GetPhaseMask(),
+ pet_entry, pet_number))
{
sLog.outError("Spell::EffectSummonCritter, spellid %u: no such creature entry %u", m_spellInfo->Id, pet_entry);
delete critter;
@@ -5889,14 +6237,16 @@ void Spell::EffectKnockBack(uint32 i)
float vsin = dx / dist;
float vcos = dy / dist;
+ float speedxy = float(m_spellInfo->EffectMiscValue[i])/10;
+ float speedz = float(damage/-10);
WorldPacket data(SMSG_MOVE_KNOCK_BACK, (8+4+4+4+4+4));
data.append(unitTarget->GetPackGUID());
data << uint32(0); // Sequence
data << float(vcos); // x direction
data << float(vsin); // y direction
- data << float(m_spellInfo->EffectMiscValue[i])/10; // Horizontal speed
- data << float(damage/-10); // Z Movement speed (vertical)
+ data << float(speedxy); // Horizontal speed
+ data << float(speedz); // Z Movement speed (vertical)
((Player*)unitTarget)->GetSession()->SendPacket(&data);
}
@@ -5919,17 +6269,26 @@ void Spell::EffectSendTaxi(uint32 i)
uint32 mountid = 0;
switch(m_spellInfo->Id)
{
- case 31606: //Stormcrow Amulet
+ case 31606: //Stormcrow Amulet
mountid = 17447;
break;
- case 45071: //Quest - Sunwell Daily - Dead Scar Bombing Run
- case 45113: //Quest - Sunwell Daily - Ship Bombing Run
- case 45353: //Quest - Sunwell Daily - Ship Bombing Run Return
+ case 45071: //Quest - Sunwell Daily - Dead Scar Bombing Run
+ case 45113: //Quest - Sunwell Daily - Ship Bombing Run
+ case 45353: //Quest - Sunwell Daily - Ship Bombing Run Return
mountid = 22840;
break;
- case 34905: //Stealth Flight
+ case 34905: //Stealth Flight
mountid = 6851;
break;
+ case 45883: //Amber Ledge to Beryl Point
+ mountid = 23524;
+ break;
+ case 46064: //Amber Ledge to Coldarra
+ mountid = 6371;
+ break;
+ case 53335: //Stormwind Harbor Flight - Peaceful
+ mountid = 6852;
+ break;
case 41533: //Fly of the Netherwing
case 41540: //Fly of the Netherwing
mountid = 23468;
@@ -6151,7 +6510,7 @@ void Spell::EffectTransmitted(uint32 effIndex)
GameObject* pGameObj = new GameObject;
if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), name_id, cMap,
- fx, fy, fz, m_caster->GetOrientation(), 0, 0, 0, 0, 100, 1))
+ m_caster->GetPhaseMask(), fx, fy, fz, m_caster->GetOrientation(), 0, 0, 0, 0, 100, 1))
{
delete pGameObj;
return;
@@ -6165,9 +6524,9 @@ void Spell::EffectTransmitted(uint32 effIndex)
{
m_caster->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT,pGameObj->GetGUID());
// Orientation3
- pGameObj->SetFloatValue(GAMEOBJECT_ROTATION + 2, 0.88431775569915771 );
+ pGameObj->SetFloatValue(GAMEOBJECT_PARENTROTATION + 2, 0.88431775569915771 );
// Orientation4
- pGameObj->SetFloatValue(GAMEOBJECT_ROTATION + 3, -0.4668855369091033 );
+ pGameObj->SetFloatValue(GAMEOBJECT_PARENTROTATION + 3, -0.4668855369091033 );
m_caster->AddGameObject(pGameObj); // will removed at spell cancel
// end time of range when possible catch fish (FISHING_BOBBER_READY_TIME..GetDuration(m_spellInfo))
@@ -6222,7 +6581,7 @@ void Spell::EffectTransmitted(uint32 effIndex)
{
GameObject* linkedGO = new GameObject;
if(linkedGO->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), linkedEntry, cMap,
- fx, fy, fz, m_caster->GetOrientation(), 0, 0, 0, 0, 100, 1))
+ m_caster->GetPhaseMask(), fx, fy, fz, m_caster->GetOrientation(), 0, 0, 0, 0, 100, 1))
{
linkedGO->SetRespawnTime(duration > 0 ? duration/1000 : 0);
linkedGO->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel() );
@@ -6262,6 +6621,28 @@ void Spell::EffectProspecting(uint32 /*i*/)
((Player*)m_caster)->SendLoot(itemTarget->GetGUID(), LOOT_PROSPECTING);
}
+void Spell::EffectMilling(uint32 /*i*/)
+{
+ if(m_caster->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ Player* p_caster = (Player*)m_caster;
+ if(!itemTarget || !(itemTarget->GetProto()->BagFamily & BAG_FAMILY_MASK_HERBS))
+ return;
+
+ if(itemTarget->GetCount() < 5)
+ return;
+
+ if( sWorld.getConfig(CONFIG_SKILL_MILLING))
+ {
+ uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_INSCRIPTION);
+ uint32 reqSkillValue = itemTarget->GetProto()->RequiredSkillRank;
+ p_caster->UpdateGatherSkill(SKILL_INSCRIPTION, SkillValue, reqSkillValue);
+ }
+
+ ((Player*)m_caster)->SendLoot(itemTarget->GetGUID(), LOOT_MILLING);
+}
+
void Spell::EffectSkill(uint32 /*i*/)
{
sLog.outDebug("WORLD: SkillEFFECT");
@@ -6409,8 +6790,42 @@ void Spell::EffectQuestFail(uint32 i)
((Player*)unitTarget)->FailQuest(m_spellInfo->EffectMiscValue[i]);
}
+void Spell::EffectActivateRune(uint32 eff_idx)
+{
+ if(m_caster->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ Player *plr = (Player*)m_caster;
+
+ if(plr->getClass() != CLASS_DEATH_KNIGHT)
+ return;
+
+ for(uint32 j = 0; j < MAX_RUNES; ++j)
+ {
+ if(plr->GetRuneCooldown(j) && plr->GetCurrentRune(j) == m_spellInfo->EffectMiscValue[eff_idx])
+ {
+ plr->SetRuneCooldown(j, 0);
+ }
+ }
+}
+
+void Spell::EffectTitanGrip(uint32 /*eff_idx*/)
+{
+ if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)unitTarget)->SetCanTitanGrip(true);
+}
+
void Spell::EffectRedirectThreat(uint32 /*i*/)
{
if(unitTarget)
m_caster->SetReducedThreatPercent((uint32)damage, unitTarget->GetGUID());
}
+
+void Spell::EffectRenamePet(uint32 /*eff_idx*/)
+{
+ if (!unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT ||
+ !((Creature*)unitTarget)->isPet() || ((Pet*)unitTarget)->getPetType() != HUNTER_PET)
+ return;
+
+ unitTarget->SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_ALLOWED);
+}
diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp
index 940135e2db5..676bb6a2dae 100644
--- a/src/game/SpellHandler.cpp
+++ b/src/game/SpellHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -38,17 +38,19 @@
void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
{
// TODO: add targets.read() check
- CHECK_PACKET_SIZE(recvPacket,1+1+1+1+8);
+ CHECK_PACKET_SIZE(recvPacket,1+1+1+4+8+4+1);
Player* pUser = _player;
uint8 bagIndex, slot;
- uint8 spell_count; // number of spells at item, not used
+ uint8 unk_flags; // flags (if 0x02 - some additional data are received)
uint8 cast_count; // next cast if exists (single or not)
uint64 item_guid;
+ uint32 glyphIndex; // something to do with glyphs?
+ uint32 spellid; // casted spell id
- recvPacket >> bagIndex >> slot >> spell_count >> cast_count >> item_guid;
+ recvPacket >> bagIndex >> slot >> cast_count >> spellid >> item_guid >> glyphIndex >> unk_flags;
- Item *pItem = pUser->GetItemByPos(bagIndex, slot);
+ Item *pItem = pUser->GetUseableItemByPos(bagIndex, slot);
if(!pItem)
{
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL );
@@ -61,7 +63,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
return;
}
- sLog.outDetail("WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, spell_count: %u , cast_count: %u, Item: %u, data length = %i", bagIndex, slot, spell_count, cast_count, pItem->GetEntry(), recvPacket.size());
+ sLog.outDetail("WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, cast_count: %u, spellid: %u, Item: %u, glyphIndex: %u, unk_flags: %u, data length = %i", bagIndex, slot, cast_count, spellid, pItem->GetEntry(), glyphIndex, unk_flags, recvPacket.size());
ItemPrototype const *proto = pItem->GetProto();
if(!proto)
@@ -126,57 +128,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
if(!Script->ItemUse(pUser,pItem,targets))
{
// no script or script not process request by self
-
- // special learning case
- if(pItem->GetProto()->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN)
- {
- uint32 learning_spell_id = pItem->GetProto()->Spells[1].SpellId;
-
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(SPELL_ID_GENERIC_LEARN);
- if(!spellInfo)
- {
- sLog.outError("Item (Entry: %u) in have wrong spell id %u, ignoring ",proto->ItemId, SPELL_ID_GENERIC_LEARN);
- pUser->SendEquipError(EQUIP_ERR_NONE,pItem,NULL);
- return;
- }
-
- Spell *spell = new Spell(pUser, spellInfo, false);
- spell->m_CastItem = pItem;
- spell->m_cast_count = cast_count; //set count of casts
- spell->m_currentBasePoints[0] = learning_spell_id;
- spell->prepare(&targets);
- return;
- }
-
- // use triggered flag only for items with many spell casts and for not first cast
- int count = 0;
-
- for(int i = 0; i < 5; ++i)
- {
- _Spell const& spellData = pItem->GetProto()->Spells[i];
-
- // no spell
- if(!spellData.SpellId)
- continue;
-
- // wrong triggering type
- if( spellData.SpellTrigger != ITEM_SPELLTRIGGER_ON_USE && spellData.SpellTrigger != ITEM_SPELLTRIGGER_ON_NO_DELAY_USE)
- continue;
-
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellData.SpellId);
- if(!spellInfo)
- {
- sLog.outError("Item (Entry: %u) in have wrong spell id %u, ignoring ",proto->ItemId, spellData.SpellId);
- continue;
- }
-
- Spell *spell = new Spell(pUser, spellInfo, (count > 0));
- spell->m_CastItem = pItem;
- spell->m_cast_count = cast_count; //set count of casts
- spell->prepare(&targets);
-
- ++count;
- }
+ pUser->CastItemUseSpell(pItem,targets,cast_count,glyphIndex);
}
}
@@ -227,7 +179,7 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket)
}
// required picklocking
- if(lockInfo->requiredlockskill || lockInfo->requiredminingskill)
+ if(lockInfo->Skill[1] || lockInfo->Skill[0])
{
pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, pItem, NULL );
return;
@@ -281,17 +233,28 @@ void WorldSession::HandleGameObjectUseOpcode( WorldPacket & recv_data )
obj->Use(_player);
}
+void WorldSession::HandleGameobjectReportUse(WorldPacket& recvPacket)
+{
+ CHECK_PACKET_SIZE(recvPacket,8);
+
+ uint64 guid;
+ recvPacket >> guid;
+
+ sLog.outDebug( "WORLD: Recvd CMSG_GAMEOBJ_REPORT_USE Message [in game guid: %u]", GUID_LOPART(guid));
+}
+
void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
{
- CHECK_PACKET_SIZE(recvPacket,4+1+2);
+ CHECK_PACKET_SIZE(recvPacket,1+4+1);
uint32 spellId;
- uint8 cast_count;
- recvPacket >> spellId;
+ uint8 cast_count, unk_flags;
recvPacket >> cast_count;
+ recvPacket >> spellId;
+ recvPacket >> unk_flags; // flags (if 0x02 - some additional data are received)
- sLog.outDebug("WORLD: got cast spell packet, spellId - %u, cast_count: %u data length = %i",
- spellId, cast_count, recvPacket.size());
+ sLog.outDebug("WORLD: got cast spell packet, spellId - %u, cast_count: %u, unk_flags %u, data length = %i",
+ spellId, cast_count, unk_flags, recvPacket.size());
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );
@@ -301,8 +264,8 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
return;
}
- // not have spell or spell passive and not casted by client
- if ( !_player->HasSpell (spellId) || IsPassiveSpell(spellId) )
+ // not have spell in spellbook or spell passive and not casted by client
+ if ( !_player->HasActiveSpell (spellId) || IsPassiveSpell(spellId) )
{
//cheater? kick? ban?
return;
@@ -334,9 +297,12 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
void WorldSession::HandleCancelCastOpcode(WorldPacket& recvPacket)
{
- CHECK_PACKET_SIZE(recvPacket,4);
+ CHECK_PACKET_SIZE(recvPacket,5);
+ // increments with every CANCEL packet, don't use for now
+ uint8 counter;
uint32 spellId;
+ recvPacket >> counter;
recvPacket >> spellId;
//FIXME: hack, ignore unexpected client cancel Deadly Throw cast
@@ -363,7 +329,7 @@ void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket)
return;
// lifebloom must delete final heal effect
- if (spellInfo->SpellFamilyName == SPELLFAMILY_DRUID && (spellInfo->SpellFamilyFlags & 0x1000000000LL) )
+ if (spellInfo->SpellFamilyName == SPELLFAMILY_DRUID && (spellInfo->SpellFamilyFlags[1] & 0x10) )
{
Unit::AuraMap::iterator iter;
while((iter = _player->m_Auras.find(Unit::spellEffectPair(spellId, 1))) != _player->m_Auras.end())
@@ -420,7 +386,7 @@ void WorldSession::HandlePetCancelAuraOpcode( WorldPacket& recvPacket)
return;
}
- Creature* pet=ObjectAccessor::GetCreatureOrPet(*_player,guid);
+ Creature* pet=ObjectAccessor::GetCreatureOrPetOrVehicle(*_player,guid);
if(!pet)
{
diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp
index 435481de949..847f90ed0c9 100644
--- a/src/game/SpellMgr.cpp
+++ b/src/game/SpellMgr.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -26,6 +26,7 @@
#include "World.h"
#include "Chat.h"
#include "Spell.h"
+#include "BattleGroundMgr.h"
bool IsAreaEffectTarget[TOTAL_SPELL_TARGETS];
@@ -38,25 +39,25 @@ SpellMgr::SpellMgr()
case SPELL_EFFECT_PERSISTENT_AREA_AURA: //27
case SPELL_EFFECT_SUMMON: //28
case SPELL_EFFECT_TRIGGER_MISSILE: //32
- case SPELL_EFFECT_SUMMON_WILD: //41
- case SPELL_EFFECT_SUMMON_GUARDIAN: //42
+ //case SPELL_EFFECT_SUMMON_WILD: //41 not 303
+ //case SPELL_EFFECT_SUMMON_GUARDIAN: //42 not 303
case SPELL_EFFECT_TRANS_DOOR: //50 summon object
case SPELL_EFFECT_SUMMON_PET: //56
case SPELL_EFFECT_ADD_FARSIGHT: //72
- case SPELL_EFFECT_SUMMON_POSSESSED: //73
- case SPELL_EFFECT_SUMMON_TOTEM: //74
+ //case SPELL_EFFECT_SUMMON_POSSESSED: //73
+ //case SPELL_EFFECT_SUMMON_TOTEM: //74
case SPELL_EFFECT_SUMMON_OBJECT_WILD: //76
- case SPELL_EFFECT_SUMMON_TOTEM_SLOT1: //87
- case SPELL_EFFECT_SUMMON_TOTEM_SLOT2: //88
- case SPELL_EFFECT_SUMMON_TOTEM_SLOT3: //89
- case SPELL_EFFECT_SUMMON_TOTEM_SLOT4: //90
- case SPELL_EFFECT_SUMMON_CRITTER: //97
+ //case SPELL_EFFECT_SUMMON_TOTEM_SLOT1: //87
+ //case SPELL_EFFECT_SUMMON_TOTEM_SLOT2: //88
+ //case SPELL_EFFECT_SUMMON_TOTEM_SLOT3: //89
+ //case SPELL_EFFECT_SUMMON_TOTEM_SLOT4: //90
+ //case SPELL_EFFECT_SUMMON_CRITTER: //97 not 303
case SPELL_EFFECT_SUMMON_OBJECT_SLOT1: //104
case SPELL_EFFECT_SUMMON_OBJECT_SLOT2: //105
case SPELL_EFFECT_SUMMON_OBJECT_SLOT3: //106
case SPELL_EFFECT_SUMMON_OBJECT_SLOT4: //107
case SPELL_EFFECT_SUMMON_DEAD_PET: //109
- case SPELL_EFFECT_SUMMON_DEMON: //112
+ //case SPELL_EFFECT_SUMMON_DEMON: //112 not 303
case SPELL_EFFECT_TRIGGER_SPELL_2: //151 ritual of summon
EffectTargetType[i] = SPELL_REQUIRE_DEST;
break;
@@ -105,7 +106,6 @@ SpellMgr::SpellMgr()
case TARGET_UNIT_TARGET_ALLY:
case TARGET_UNIT_TARGET_RAID:
case TARGET_UNIT_TARGET_ANY:
- case TARGET_UNIT_SINGLE_UNKNOWN:
case TARGET_UNIT_TARGET_ENEMY:
case TARGET_UNIT_TARGET_PARTY:
case TARGET_UNIT_PARTY_TARGET:
@@ -244,19 +244,8 @@ uint32 GetSpellCastTime(SpellEntry const* spellInfo, Spell const* spell)
int32 castTime = spellCastTimeEntry->CastTime;
- if (spell)
- {
- if(Player* modOwner = spell->GetCaster()->GetSpellModOwner())
- modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CASTING_TIME, castTime, spell);
-
- if( !(spellInfo->Attributes & (SPELL_ATTR_UNK4|SPELL_ATTR_UNK5)) )
- castTime = int32(castTime * spell->GetCaster()->GetFloatValue(UNIT_MOD_CAST_SPEED));
- else
- {
- if (spell->IsRangedSpell() && !spell->IsAutoRepeat())
- castTime = int32(castTime * spell->GetCaster()->m_modAttackSpeedPct[RANGED_ATTACK]);
- }
- }
+ if (spell && spell->GetCaster())
+ spell->GetCaster()->ModSpellCastTime(spellInfo, castTime);
if (spellInfo->Attributes & SPELL_ATTR_RANGED && (!spell || !(spell->IsAutoRepeat())))
castTime += 500;
@@ -328,17 +317,17 @@ SpellSpecific GetSpellSpecific(uint32 spellId)
case SPELLFAMILY_MAGE:
{
// family flags 18(Molten), 25(Frost/Ice), 28(Mage)
- if (spellInfo->SpellFamilyFlags & 0x12040000)
+ if (spellInfo->SpellFamilyFlags[0] & 0x12040000)
return SPELL_MAGE_ARMOR;
- if ((spellInfo->SpellFamilyFlags & 0x1000000) && spellInfo->EffectApplyAuraName[0]==SPELL_AURA_MOD_CONFUSE)
+ if ((spellInfo->SpellFamilyFlags[0] & 0x1000000) && spellInfo->EffectApplyAuraName[0]==SPELL_AURA_MOD_CONFUSE)
return SPELL_MAGE_POLYMORPH;
break;
}
case SPELLFAMILY_WARRIOR:
{
- if (spellInfo->SpellFamilyFlags & 0x00008000010000LL)
+ if (spellInfo->SpellFamilyFlags[1] & 0x000080 || spellInfo->SpellFamilyFlags[0] & 0x10000LL)
return SPELL_POSITIVE_SHOUT;
break;
@@ -349,12 +338,12 @@ SpellSpecific GetSpellSpecific(uint32 spellId)
if (spellInfo->Dispel == DISPEL_CURSE)
return SPELL_CURSE;
- // family flag 37 (only part spells have family name)
- if (spellInfo->SpellFamilyFlags & 0x2000000000LL)
+ // Warlock (Demon Armor | Demon Skin | Fel Armor)
+ if (spellInfo->SpellFamilyFlags[1] & 0x20000020 || spellInfo->SpellFamilyFlags[2] & 0x00000010)
return SPELL_WARLOCK_ARMOR;
//seed of corruption and corruption
- if (spellInfo->SpellFamilyFlags & 0x1000000002LL)
+ if (spellInfo->SpellFamilyFlags[1] & 0x10 || spellInfo->SpellFamilyFlags[0] & 0x2)
return SPELL_WARLOCK_CORRUPTION;
break;
}
@@ -364,6 +353,13 @@ SpellSpecific GetSpellSpecific(uint32 spellId)
if (spellInfo->Dispel == DISPEL_POISON)
return SPELL_STING;
+ // only hunter aspects have this
+ if( spellInfo->SpellFamilyFlags[1] & 0x00440000 || spellInfo->SpellFamilyFlags[0] & 0x00380000 || spellInfo->SpellFamilyFlags[2] & 0x00003010)
+ return SPELL_ASPECT;
+
+ if( spellInfo->SpellFamilyFlags[2] & 0x00000002 )
+ return SPELL_TRACKER;
+
break;
}
case SPELLFAMILY_PALADIN:
@@ -371,16 +367,16 @@ SpellSpecific GetSpellSpecific(uint32 spellId)
if (IsSealSpell(spellInfo))
return SPELL_SEAL;
- if (spellInfo->SpellFamilyFlags & 0x10000100LL)
+ if (spellInfo->SpellFamilyFlags[0] & 0x11010002)
return SPELL_BLESSING;
- if ((spellInfo->SpellFamilyFlags & 0x00000820180400LL) && (spellInfo->AttributesEx3 & 0x200))
+ if ((spellInfo->SpellFamilyFlags[1] & 0x000008 || spellInfo->SpellFamilyFlags[0] & 20180400) && (spellInfo->AttributesEx3 & 0x200))
return SPELL_JUDGEMENT;
for (int i = 0; i < 3; i++)
{
- // only paladin auras have this
- if (spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PARTY)
+ // only paladin auras have this (for palaldin class family)
+ if (spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_RAID)
return SPELL_AURA;
}
break;
@@ -395,28 +391,13 @@ SpellSpecific GetSpellSpecific(uint32 spellId)
case SPELLFAMILY_POTION:
return spellmgr.GetSpellElixirSpecific(spellInfo->Id);
- }
- // only warlock armor/skin have this (in additional to family cases)
- if( spellInfo->SpellVisual == 130 && spellInfo->SpellIconID == 89)
- {
- return SPELL_WARLOCK_ARMOR;
- }
-
- // only hunter aspects have this (but not all aspects in hunter family)
- if( spellInfo->activeIconID == 122 && (GetSpellSchoolMask(spellInfo) & SPELL_SCHOOL_MASK_NATURE) &&
- (spellInfo->Attributes & 0x50000) != 0 && (spellInfo->Attributes & 0x9000010) == 0)
- {
- return SPELL_ASPECT;
+ case SPELLFAMILY_DEATHKNIGHT:
+ if ((spellInfo->Attributes & 0x10) && (spellInfo->AttributesEx2 & 0x10) && (spellInfo->AttributesEx4 & 0x200000))
+ return SPELL_PRESENCE;
+ break;
}
- for(int i = 0; i < 3; i++)
- if( spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA && (
- spellInfo->EffectApplyAuraName[i] == SPELL_AURA_TRACK_CREATURES ||
- spellInfo->EffectApplyAuraName[i] == SPELL_AURA_TRACK_RESOURCES ||
- spellInfo->EffectApplyAuraName[i] == SPELL_AURA_TRACK_STEALTHED ) )
- return SPELL_TRACKER;
-
// elixirs can have different families, but potion most ofc.
if(SpellSpecific sp = spellmgr.GetSpellElixirSpecific(spellInfo->Id))
return sp;
@@ -452,6 +433,7 @@ bool IsSingleFromSpellSpecificPerTarget(uint32 spellSpec1,uint32 spellSpec2)
case SPELL_MAGE_ARMOR:
case SPELL_ELEMENTAL_SHIELD:
case SPELL_MAGE_POLYMORPH:
+ case SPELL_PRESENCE:
case SPELL_WELL_FED:
case SPELL_DRINK:
case SPELL_FOOD:
@@ -484,8 +466,6 @@ bool IsPositiveTarget(uint32 targetA, uint32 targetB)
case TARGET_CURRENT_ENEMY_COORDINATES:
case TARGET_UNIT_CHANNEL:
return false;
- case TARGET_ALL_AROUND_CASTER:
- return (targetB == TARGET_ALL_PARTY || targetB == TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER);
default:
break;
}
@@ -891,8 +871,8 @@ void SpellMgr::LoadSpellAffects()
uint32 count = 0;
- // 0 1 2
- QueryResult *result = WorldDatabase.Query("SELECT entry, effectId, SpellFamilyMask FROM spell_affect");
+ // 0 1 2 3 4
+ QueryResult *result = WorldDatabase.Query("SELECT entry, effectId, SpellClassMask0, SpellClassMask1, SpellClassMask2 FROM spell_affect");
if( !result )
{
@@ -939,26 +919,22 @@ void SpellMgr::LoadSpellAffects()
continue;
}
- uint64 spellAffectMask = fields[2].GetUInt64();
+ flag96 affect(fields[2].GetUInt32(), fields[3].GetUInt32(), fields[4].GetUInt32());
- // Spell.dbc have own data for low part of SpellFamilyMask
- if( spellInfo->EffectItemType[effectId])
- {
- if(spellInfo->EffectItemType[effectId] == spellAffectMask)
- {
- sLog.outErrorDb("Spell %u listed in `spell_affect` have redundant (same with EffectItemType%d) data for effect index (%u) and not needed, skipped.", entry,effectId+1,effectId);
- continue;
- }
+ // Spell.dbc have own data
+ if (effectId>3)
+ continue;
- // 24429 have wrong data in EffectItemType and overwrites by DB, possible bug in client
- if(spellInfo->Id!=24429 && spellInfo->EffectItemType[effectId] != spellAffectMask)
- {
- sLog.outErrorDb("Spell %u listed in `spell_affect` have different low part from EffectItemType%d for effect index (%u) and not needed, skipped.", entry,effectId+1,effectId);
- continue;
- }
+ flag96 dbc_affect;
+ dbc_affect = spellInfo->EffectSpellClassMask[effectId];
+ if(dbc_affect[0] == affect[0] || dbc_affect[1] == affect[1] || dbc_affect[2] == affect[2])
+ {
+ char text[]="ABC";
+ sLog.outErrorDb("Spell %u listed in `spell_affect` have redundant (same with EffectSpellClassMask%c) data for effect index (%u) and not needed, skipped.", entry, text[effectId], effectId);
+ continue;
}
- mSpellAffectMap.insert(SpellAffectMap::value_type((entry<<8) + effectId,spellAffectMask));
+ mSpellAffectMap[(entry<<8) + effectId] = affect;
++count;
} while( result->NextRow() );
@@ -966,7 +942,7 @@ void SpellMgr::LoadSpellAffects()
delete result;
sLog.outString();
- sLog.outString( ">> Loaded %u spell affect definitions", count );
+ sLog.outString( ">> Loaded %u custom spell affect definitions", count );
for (uint32 id = 0; id < sSpellStore.GetNumRows(); ++id)
{
@@ -982,7 +958,9 @@ void SpellMgr::LoadSpellAffects()
spellInfo->EffectApplyAuraName[effectId] != SPELL_AURA_ADD_TARGET_TRIGGER) )
continue;
- if(spellInfo->EffectItemType[effectId] != 0)
+ flag96 dbc_affect;
+ dbc_affect = spellInfo->EffectSpellClassMask[effectId];
+ if(dbc_affect)
continue;
if(mSpellAffectMap.find((id<<8) + effectId) != mSpellAffectMap.end())
@@ -993,33 +971,19 @@ void SpellMgr::LoadSpellAffects()
}
}
-bool SpellMgr::IsAffectedBySpell(SpellEntry const *spellInfo, uint32 spellId, uint8 effectId, uint64 familyFlags) const
+bool SpellMgr::IsAffectedByMod(SpellEntry const *spellInfo, SpellModifier *mod) const
{
// false for spellInfo == NULL
- if (!spellInfo)
+ if (!spellInfo || !mod)
return false;
- SpellEntry const *affect_spell = sSpellStore.LookupEntry(spellId);
- // false for affect_spell == NULL
- if (!affect_spell)
+ SpellEntry const *affect_spell = sSpellStore.LookupEntry(mod->spellId);
+ // False if affect_spell == NULL or spellFamily not equal
+ if (!affect_spell || affect_spell->SpellFamilyName != spellInfo->SpellFamilyName)
return false;
- // False if spellFamily not equal
- if (affect_spell->SpellFamilyName != spellInfo->SpellFamilyName)
- return false;
-
- // If familyFlags == 0
- if (!familyFlags)
- {
- // Get it from spellAffect table
- familyFlags = GetSpellAffectMask(spellId,effectId);
- // false if familyFlags == 0
- if (!familyFlags)
- return false;
- }
-
// true
- if (familyFlags & spellInfo->SpellFamilyFlags)
+ if (mod->mask & spellInfo->SpellFamilyFlags)
return true;
return false;
@@ -1031,15 +995,12 @@ void SpellMgr::LoadSpellProcEvents()
uint32 count = 0;
- // 0 1 2 3 4 5 6 7 8
- QueryResult *result = WorldDatabase.Query("SELECT entry, SchoolMask, SpellFamilyName, SpellFamilyMask, procFlags, procEx, ppmRate, CustomChance, Cooldown FROM spell_proc_event");
+ // 0 1 2 3 4 5 6 7 8 9 10
+ QueryResult *result = WorldDatabase.Query("SELECT entry, SchoolMask, SpellFamilyName, SpellFamilyMask0, SpellFamilyMask1, SpellFamilyMask2, procFlags, procEx, ppmRate, CustomChance, Cooldown FROM spell_proc_event");
if( !result )
{
-
barGoLink bar( 1 );
-
bar.step();
-
sLog.outString();
sLog.outString( ">> Loaded %u spell proc event conditions", count );
return;
@@ -1053,7 +1014,7 @@ void SpellMgr::LoadSpellProcEvents()
bar.step();
- uint16 entry = fields[0].GetUInt16();
+ uint32 entry = fields[0].GetUInt32();
const SpellEntry *spell = sSpellStore.LookupEntry(entry);
if (!spell)
@@ -1066,12 +1027,13 @@ void SpellMgr::LoadSpellProcEvents()
spe.schoolMask = fields[1].GetUInt32();
spe.spellFamilyName = fields[2].GetUInt32();
- spe.spellFamilyMask = fields[3].GetUInt64();
- spe.procFlags = fields[4].GetUInt32();
- spe.procEx = fields[5].GetUInt32();
- spe.ppmRate = fields[6].GetFloat();
- spe.customChance = fields[7].GetFloat();
- spe.cooldown = fields[8].GetUInt32();
+ spe.spellFamilyMask = (uint64)fields[3].GetUInt32()|((uint64)fields[4].GetUInt32()<<32);
+ spe.spellFamilyMask2= fields[5].GetUInt32();
+ spe.procFlags = fields[6].GetUInt32();
+ spe.procEx = fields[7].GetUInt32();
+ spe.ppmRate = fields[8].GetFloat();
+ spe.customChance = fields[9].GetFloat();
+ spe.cooldown = fields[10].GetUInt32();
mSpellProcEventMap[entry] = spe;
@@ -1091,80 +1053,54 @@ void SpellMgr::LoadSpellProcEvents()
sLog.outString();
if (customProc)
- sLog.outString( ">> Loaded %u custom spell proc event conditions +%u custom", count, customProc );
+ sLog.outString( ">> Loaded %u extra spell proc event conditions +%u custom", count, customProc );
else
- sLog.outString( ">> Loaded %u spell proc event conditions", count );
+ sLog.outString( ">> Loaded %u extra spell proc event conditions", count );
+}
- /*
- // Commented for now, as it still produces many errors (still quite many spells miss spell_proc_event)
- for (uint32 id = 0; id < sSpellStore.GetNumRows(); ++id)
+void SpellMgr::LoadSpellBonusess()
+{
+ mSpellBonusMap.clear(); // need for reload case
+ uint32 count = 0;
+ // 0 1 2 3
+ QueryResult *result = WorldDatabase.Query("SELECT entry, direct_bonus, dot_bonus, ap_bonus FROM spell_bonus_data");
+ if( !result )
{
- SpellEntry const* spellInfo = sSpellStore.LookupEntry(id);
- if (!spellInfo)
- continue;
-
- bool found = false;
- for (int effectId = 0; effectId < 3; ++effectId)
- {
- // at this moment check only SPELL_AURA_PROC_TRIGGER_SPELL
- if( spellInfo->EffectApplyAuraName[effectId] == SPELL_AURA_PROC_TRIGGER_SPELL )
- {
- found = true;
- break;
- }
- }
+ barGoLink bar( 1 );
+ bar.step();
+ sLog.outString();
+ sLog.outString( ">> Loaded %u spell bonus data", count);
+ return;
+ }
- if(!found)
- continue;
+ barGoLink bar( result->GetRowCount() );
+ do
+ {
+ Field *fields = result->Fetch();
+ bar.step();
+ uint32 entry = fields[0].GetUInt32();
- if(GetSpellProcEvent(id))
+ const SpellEntry *spell = sSpellStore.LookupEntry(entry);
+ if (!spell)
+ {
+ sLog.outErrorDb("Spell %u listed in `spell_bonus_data` does not exist", entry);
continue;
+ }
- sLog.outErrorDb("Spell %u (%s) misses spell_proc_event",id,spellInfo->SpellName[sWorld.GetDBClang()]);
- }
- */
-}
-
-/*
-bool SpellMgr::IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spellProcEvent, SpellEntry const * procSpell, uint32 procFlags )
-{
- if((procFlags & spellProcEvent->procFlags) == 0)
- return false;
+ SpellBonusEntry sbe;
- // Additional checks in case spell cast/hit/crit is the event
- // Check (if set) school, category, skill line, spell talent mask
- if(spellProcEvent->schoolMask && (!procSpell || (GetSpellSchoolMask(procSpell) & spellProcEvent->schoolMask) == 0))
- return false;
- if(spellProcEvent->category && (!procSpell || procSpell->Category != spellProcEvent->category))
- return false;
- if(spellProcEvent->skillId)
- {
- if (!procSpell)
- return false;
+ sbe.direct_damage = fields[1].GetFloat();
+ sbe.dot_damage = fields[2].GetFloat();
+ sbe.ap_bonus = fields[3].GetFloat();
- SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(procSpell->Id);
- SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(procSpell->Id);
+ mSpellBonusMap[entry] = sbe;
+ } while( result->NextRow() );
- bool found = false;
- for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
- {
- if(_spell_idx->second->skillId == spellProcEvent->skillId)
- {
- found = true;
- break;
- }
- }
- if (!found)
- return false;
- }
- if(spellProcEvent->spellFamilyName && (!procSpell || spellProcEvent->spellFamilyName != procSpell->SpellFamilyName))
- return false;
- if(spellProcEvent->spellFamilyMask && (!procSpell || (spellProcEvent->spellFamilyMask & procSpell->SpellFamilyFlags) == 0))
- return false;
+ delete result;
- return true;
+ sLog.outString();
+ sLog.outString( ">> Loaded %u extra spell bonus data", count);
}
-*/
bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const * spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra, bool active)
{
@@ -1176,7 +1112,7 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const * spellP
return false;
// Always trigger for this
- if (EventProcFlag & (PROC_FLAG_KILLED | PROC_FLAG_KILL_AND_GET_XP))
+ if (EventProcFlag & (PROC_FLAG_KILLED | PROC_FLAG_KILL | PROC_FLAG_ON_TRAP_ACTIVATION))
return true;
if (spellProcEvent) // Exist event data
@@ -1202,9 +1138,9 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const * spellP
return false;
// spellFamilyName is Ok need check for spellFamilyMask if present
- if(spellProcEvent->spellFamilyMask)
+ if(spellProcEvent->spellFamilyMask || spellProcEvent->spellFamilyMask2)
{
- if ((spellProcEvent->spellFamilyMask & procSpell->SpellFamilyFlags) == 0)
+ if ((spellProcEvent->spellFamilyMask & procSpell->SpellFamilyFlags ) == 0)
return false;
active = true; // Spell added manualy -> so its active spell
}
@@ -1303,28 +1239,38 @@ bool SpellMgr::IsRankSpellDueToSpell(SpellEntry const *spellInfo_1,uint32 spellI
bool SpellMgr::canStackSpellRanks(SpellEntry const *spellInfo)
{
+ if(IsPassiveSpell(spellInfo->Id)) // ranked passive spell
+ return false;
if(spellInfo->powerType != POWER_MANA && spellInfo->powerType != POWER_HEALTH)
return false;
- if(IsProfessionSpell(spellInfo->Id))
+ if(IsProfessionOrRidingSpell(spellInfo->Id))
+ return false;
+
+ if(spellmgr.IsSkillBonusSpell(spellInfo->Id))
return false;
// All stance spells. if any better way, change it.
for (int i = 0; i < 3; i++)
{
- // Paladin aura Spell
- if(spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN
- && spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AREA_AURA_PARTY)
- return false;
- // Druid form Spell
- if(spellInfo->SpellFamilyName == SPELLFAMILY_DRUID
- && spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AURA
- && spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT)
- return false;
- // Rogue Stealth
- if(spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE
- && spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AURA
- && spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT)
- return false;
+ switch(spellInfo->SpellFamilyName)
+ {
+ case SPELLFAMILY_PALADIN:
+ // Paladin aura Spell
+ if (spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AREA_AURA_RAID)
+ return false;
+ break;
+ case SPELLFAMILY_DRUID:
+ // Druid form Spell
+ if (spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AURA &&
+ spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT)
+ return false;
+ break;
+ case SPELLFAMILY_ROGUE:
+ // Rogue Stealth
+ if (spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AURA &&
+ spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT)
+ return false;
+ }
}
return true;
}
@@ -1353,6 +1299,11 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2, bool
if(spellInfo_1->SpellFamilyName != spellInfo_2->SpellFamilyName)
return false;
+ // TODO: Is this needed?
+ // Allow stack passive and not passive spells
+ if ((spellInfo_1->Attributes & SPELL_ATTR_PASSIVE)!=(spellInfo_2->Attributes & SPELL_ATTR_PASSIVE))
+ return false;
+
// generic spells
if(!spellInfo_1->SpellFamilyName)
{
@@ -1407,6 +1358,21 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2, bool
return true;
}
+
+bool SpellMgr::IsProfessionOrRidingSpell(uint32 spellId)
+{
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId);
+ if(!spellInfo)
+ return false;
+
+ if(spellInfo->Effect[1] != SPELL_EFFECT_SKILL)
+ return false;
+
+ uint32 skill = spellInfo->EffectMiscValue[1];
+
+ return IsProfessionOrRidingSkill(skill);
+}
+
bool SpellMgr::IsProfessionSpell(uint32 spellId)
{
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId);
@@ -1440,6 +1406,24 @@ bool SpellMgr::IsPrimaryProfessionFirstRankSpell(uint32 spellId) const
return IsPrimaryProfessionSpell(spellId) && GetSpellRank(spellId)==1;
}
+bool SpellMgr::IsSkillBonusSpell(uint32 spellId) const
+{
+ SkillLineAbilityMap::const_iterator lower = GetBeginSkillLineAbilityMap(spellId);
+ SkillLineAbilityMap::const_iterator upper = GetEndSkillLineAbilityMap(spellId);
+
+ for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
+ {
+ SkillLineAbilityEntry const *pAbility = _spell_idx->second;
+ if (!pAbility || pAbility->learnOnGetSkill != ABILITY_LEARNED_ON_GET_PROFESSION_SKILL)
+ continue;
+
+ if(pAbility->req_skill_value > 0)
+ return true;
+ }
+
+ return false;
+}
+
SpellEntry const* SpellMgr::SelectAuraRankForPlayerLevel(SpellEntry const* spellInfo, uint32 playerLevel) const
{
// ignore passive spells
@@ -1451,7 +1435,8 @@ SpellEntry const* SpellMgr::SelectAuraRankForPlayerLevel(SpellEntry const* spell
{
if( IsPositiveEffect(spellInfo->Id, i) && (
spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA ||
- spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PARTY
+ spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PARTY ||
+ spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_RAID
) )
{
needRankSelection = true;
@@ -1526,21 +1511,31 @@ struct SpellRankEntry
uint32 RangeIndex;
uint32 SpellVisual;
uint32 ProcFlags;
- uint64 SpellFamilyFlags;
+ flag96 SpellFamilyFlags;
uint32 TargetAuraState;
uint32 ManaCost;
-
- bool operator()(const SpellRankEntry & _Left,const SpellRankEntry & _Right)const
- {
- return (_Left.SkillId != _Right.SkillId ? _Left.SkillId < _Right.SkillId
- : _Left.SpellName!=_Right.SpellName ? _Left.SpellName < _Right.SpellName
- : _Left.ProcFlags!=_Right.ProcFlags ? _Left.ProcFlags < _Right.ProcFlags
- : _Left.SpellFamilyFlags!=_Right.SpellFamilyFlags ? _Left.SpellFamilyFlags < _Right.SpellFamilyFlags
- : (_Left.SpellVisual!=_Right.SpellVisual) && (!_Left.SpellVisual || !_Right.SpellVisual) ? _Left.SpellVisual < _Right.SpellVisual
- : (_Left.ManaCost!=_Right.ManaCost) && (!_Left.ManaCost || !_Right.ManaCost) ? _Left.ManaCost < _Right.ManaCost
- : (_Left.DurationIndex!=_Right.DurationIndex) && (!_Left.DurationIndex || !_Right.DurationIndex)? _Left.DurationIndex < _Right.DurationIndex
- : (_Left.RangeIndex!=_Right.RangeIndex) && (!_Left.RangeIndex || !_Right.RangeIndex || _Left.RangeIndex==1 || !_Right.RangeIndex==1) ? _Left.RangeIndex < _Right.RangeIndex
- : _Left.TargetAuraState < _Right.TargetAuraState
+ uint32 CastingTimeIndex;
+ flag96 Effect;
+ flag96 Aura;
+ uint16 TalentID;
+
+ bool operator < (const SpellRankEntry & _Right) const
+ {
+ return (SkillId != _Right.SkillId ? SkillId < _Right.SkillId
+ : SpellName!=_Right.SpellName ? SpellName < _Right.SpellName
+ : ProcFlags!=_Right.ProcFlags ? ProcFlags < _Right.ProcFlags
+
+ : Effect!=_Right.Effect ? Effect < _Right.Effect
+ : Aura!=_Right.Aura ? Aura < _Right.Aura
+ : TalentID!=_Right.TalentID ? TalentID < _Right.TalentID
+ : (CastingTimeIndex!=_Right.CastingTimeIndex) && (!CastingTimeIndex || !_Right.CastingTimeIndex || CastingTimeIndex==1 || !_Right.CastingTimeIndex==1) ? CastingTimeIndex < _Right.CastingTimeIndex
+
+ : SpellFamilyFlags!=_Right.SpellFamilyFlags ? SpellFamilyFlags < _Right.SpellFamilyFlags
+ : (SpellVisual!=_Right.SpellVisual) && (!SpellVisual || !_Right.SpellVisual) ? SpellVisual < _Right.SpellVisual
+ : (ManaCost!=_Right.ManaCost) && (!ManaCost || !_Right.ManaCost) ? ManaCost < _Right.ManaCost
+ : (DurationIndex!=_Right.DurationIndex) && (!DurationIndex || !_Right.DurationIndex)? DurationIndex < _Right.DurationIndex
+ : (RangeIndex!=_Right.RangeIndex) && (!RangeIndex || !_Right.RangeIndex || RangeIndex==1 || !_Right.RangeIndex==1) ? RangeIndex < _Right.RangeIndex
+ : TargetAuraState < _Right.TargetAuraState
);
}
};
@@ -1549,6 +1544,7 @@ struct SpellRankValue
{
uint32 Id;
char const *Rank;
+ bool strict;
};
void SpellMgr::LoadSpellChains()
@@ -1561,14 +1557,12 @@ void SpellMgr::LoadSpellChains()
SkillLineAbilityEntry const *AbilityInfo=sSkillLineAbilityStore.LookupEntry(ability_id);
if (!AbilityInfo)
continue;
- if (AbilityInfo->spellId==20154) //exception to these rules (not needed in 3.0.3)
- continue;
if (!AbilityInfo->forward_spellid)
continue;
ChainedSpells.push_back(AbilityInfo->forward_spellid);
}
- std::multimap<SpellRankEntry, SpellRankValue,SpellRankEntry> RankMap;
+ std::multimap<SpellRankEntry, SpellRankValue> RankMap;
for (uint32 ability_id=0;ability_id<sSkillLineAbilityStore.GetNumRows();ability_id++)
{
@@ -1578,8 +1572,6 @@ void SpellMgr::LoadSpellChains()
//get only spell with lowest ability_id to prevent doubles
uint32 spell_id=AbilityInfo->spellId;
- if (spell_id==20154) //exception to these rules (not needed in 3.0.3)
- continue;
bool found=false;
for (uint32 i=0; i<ChainedSpells.size(); i++)
{
@@ -1598,7 +1590,7 @@ void SpellMgr::LoadSpellChains()
if(sRank.empty())
continue;
//exception to polymorph spells-make pig and turtle other chain than sheep
- if ((SpellInfo->SpellFamilyName==SPELLFAMILY_MAGE) && (SpellInfo->SpellFamilyFlags & 0x1000000) && (SpellInfo->SpellIconID!=82))
+ if ((SpellInfo->SpellFamilyName==SPELLFAMILY_MAGE) && (SpellInfo->SpellFamilyFlags[0] & 0x1000000) && (SpellInfo->SpellIconID!=82))
continue;
SpellRankEntry entry;
@@ -1610,14 +1602,16 @@ void SpellMgr::LoadSpellChains()
entry.ProcFlags=SpellInfo->procFlags;
entry.SpellFamilyFlags=SpellInfo->SpellFamilyFlags;
entry.TargetAuraState=SpellInfo->TargetAuraState;
- entry.SpellVisual=SpellInfo->SpellVisual;
+ entry.SpellVisual=SpellInfo->SpellVisual[0];
entry.ManaCost=SpellInfo->manaCost;
-
+ entry.CastingTimeIndex=0;
+ entry.TalentID=0;
for (;;)
{
AbilityInfo=mSkillLineAbilityMap.lower_bound(spell_id)->second;
value.Id=spell_id;
value.Rank=SpellInfo->Rank[sWorld.GetDefaultDbcLocale()];
+ value.strict=false;
RankMap.insert(std::pair<SpellRankEntry, SpellRankValue>(entry,value));
spell_id=AbilityInfo->forward_spellid;
SpellInfo=sSpellStore.LookupEntry(spell_id);
@@ -1630,48 +1624,109 @@ void SpellMgr::LoadSpellChains()
uint32 count=0;
- for (std::multimap<SpellRankEntry, SpellRankValue,SpellRankEntry>::iterator itr = RankMap.begin();itr!=RankMap.end();)
+ for (std::multimap<SpellRankEntry, SpellRankValue>::iterator itr = RankMap.begin();itr!=RankMap.end();)
{
SpellRankEntry entry=itr->first;
//trac errors in extracted data
- std::multimap<char const *, std::multimap<SpellRankEntry, SpellRankValue,SpellRankEntry>::iterator> RankErrorMap;
- for (std::multimap<SpellRankEntry, SpellRankValue,SpellRankEntry>::iterator itr2 = RankMap.lower_bound(entry);itr2!=RankMap.upper_bound(entry);itr2++)
+ std::multimap<char const *, std::multimap<SpellRankEntry, SpellRankValue>::iterator> RankErrorMap;
+ for (std::multimap<SpellRankEntry, SpellRankValue>::iterator itr2 = RankMap.lower_bound(entry);itr2!=RankMap.upper_bound(entry);itr2++)
{
bar.step();
- RankErrorMap.insert(std::pair<char const *, std::multimap<SpellRankEntry, SpellRankValue,SpellRankEntry>::iterator>(itr2->second.Rank,itr2));
- }
- for (std::multimap<char const *, std::multimap<SpellRankEntry, SpellRankValue,SpellRankEntry>::iterator>::iterator itr2 = RankErrorMap.begin();itr2!=RankErrorMap.end();)
- {
- char const * err_entry=itr2->first;
- uint32 rank_count=RankErrorMap.count(itr2->first);
- if (rank_count>1)
- for (itr2 = RankErrorMap.lower_bound(err_entry);itr2!=RankErrorMap.upper_bound(err_entry);itr2++)
+ RankErrorMap.insert(std::pair<char const *, std::multimap<SpellRankEntry, SpellRankValue>::iterator>(itr2->second.Rank,itr2));
+ }
+
+ bool error=false;
+ //if strict == true strict check is not needed
+ if (!itr->second.strict)
+ //check for rank duplicates, if there are any do strict check
+ for (std::multimap<char const *, std::multimap<SpellRankEntry, SpellRankValue>::iterator>::iterator itr2 = RankErrorMap.begin();itr2!=RankErrorMap.end();)
{
- sLog.outDebug("There is a duplicate rank entry (%s) for spell: %u",itr2->first,itr2->second->second.Id);
- sLog.outDebug("Spell %u removed from chain data.",itr2->second->second.Id);
- RankMap.erase(itr2->second);
- itr=RankMap.lower_bound(entry);
+ char const * err_entry=itr2->first;
+ uint32 rank_count=RankErrorMap.count(itr2->first);
+ if (rank_count>1)
+ {
+ error=true;
+ break;
+ }
+ else
+ itr2++;
}
- else
- itr2++;
- }
- //do not proceed for spells with less than 2 ranks
- uint32 spell_max_rank=RankMap.count(entry);
- if (spell_max_rank<2)
+ bool allHaveTalents=true;
+ if (error)
{
- itr=RankMap.upper_bound(entry);
+ std::list<uint32> ConflictedSpells;
+ for (std::multimap<SpellRankEntry, SpellRankValue>::iterator itr2 = RankMap.lower_bound(entry);itr2!=RankMap.upper_bound(entry);itr2=RankMap.lower_bound(entry))
+ {
+ ConflictedSpells.push_back(itr2->second.Id);
+ if (!GetTalentSpellPos(itr2->second.Id))
+ allHaveTalents=false;
+ RankMap.erase(itr2);
+ }
+ SpellRankEntry nextEntry, currEntry;
+ for (;!ConflictedSpells.empty();ConflictedSpells.pop_front())
+ {
+ SpellEntry const *SpellInfo=sSpellStore.LookupEntry(ConflictedSpells.front());
+ currEntry.SkillId=entry.SkillId;
+ currEntry.SpellName=SpellInfo->SpellName[sWorld.GetDefaultDbcLocale()];
+ currEntry.DurationIndex=SpellInfo->DurationIndex;
+ currEntry.RangeIndex=SpellInfo->rangeIndex;
+ currEntry.ProcFlags=SpellInfo->procFlags;
+ currEntry.SpellFamilyFlags=SpellInfo->SpellFamilyFlags;
+ //compare talents only when all spells from chain have entry
+ //to prevent wrong results with spells which have first rank talented and other not
+ if (allHaveTalents)
+ currEntry.TalentID=GetTalentSpellPos(ConflictedSpells.front())->talent_id;
+ else
+ currEntry.TalentID=0;
+ currEntry.TargetAuraState=SpellInfo->TargetAuraState;
+ currEntry.SpellVisual=SpellInfo->SpellVisual[0];
+ currEntry.ManaCost=SpellInfo->manaCost;
+
+ //compare effects and casting time
+ currEntry.CastingTimeIndex=SpellInfo->CastingTimeIndex;
+ currEntry.Effect[0]=SpellInfo->Effect[0];
+ currEntry.Effect[1]=SpellInfo->Effect[1];
+ currEntry.Effect[2]=SpellInfo->Effect[2];
+
+ currEntry.Aura[0]=SpellInfo->EffectApplyAuraName[0];
+ currEntry.Aura[1]=SpellInfo->EffectApplyAuraName[1];
+ currEntry.Aura[2]=SpellInfo->EffectApplyAuraName[2];
+
+ SpellRankValue currValue;
+ currValue.Id=ConflictedSpells.front();
+ currValue.Rank=SpellInfo->Rank[sWorld.GetDefaultDbcLocale()];
+ currValue.strict=true;
+ RankMap.insert(std::pair<SpellRankEntry, SpellRankValue>(currEntry,currValue));
+ }
+ itr=RankMap.begin();
continue;
}
+ else
+ for (std::multimap<char const *, std::multimap<SpellRankEntry, SpellRankValue>::iterator>::iterator itr2 = RankErrorMap.begin();itr2!=RankErrorMap.end();)
+ {
+ char const * err_entry=itr2->first;
+ uint32 rank_count=RankErrorMap.count(itr2->first);
+ if (rank_count>1)
+ for (itr2 = RankErrorMap.lower_bound(err_entry);itr2!=RankErrorMap.upper_bound(err_entry);itr2++)
+ {
+ sLog.outDebug("There is a duplicate rank entry (%s) for spell: %u",itr2->first,itr2->second->second.Id);
+ if (!(itr2->second->second.Id==52375 || itr2->second->second.Id==45902))
+ {
+ sLog.outDebug("Spell %u removed from chain data.",itr2->second->second.Id);
+ RankMap.erase(itr2->second);
+ }
+ }
+ else
+ itr2++;
+ }
- itr=RankMap.upper_bound(entry);
-
- //order spells by spells by spellLevel
+ //order spells by spellLevel
std::list<uint32> RankedSpells;
uint32 min_spell_lvl=0;
- std::multimap<SpellRankEntry, SpellRankValue,SpellRankEntry>::iterator min_itr;
+ std::multimap<SpellRankEntry, SpellRankValue>::iterator min_itr;
for (;RankMap.count(entry);)
{
- for (std::multimap<SpellRankEntry, SpellRankValue,SpellRankEntry>::iterator itr2 = RankMap.lower_bound(entry);itr2!=RankMap.upper_bound(entry);itr2++)
+ for (std::multimap<SpellRankEntry, SpellRankValue>::iterator itr2 = RankMap.lower_bound(entry);itr2!=RankMap.upper_bound(entry);itr2++)
{
SpellEntry const *SpellInfo=sSpellStore.LookupEntry(itr2->second.Id);
if (SpellInfo->spellLevel<min_spell_lvl || itr2==RankMap.lower_bound(entry))
@@ -1707,9 +1762,13 @@ void SpellMgr::LoadSpellChains()
}
}
+ //do not proceed for spells with less than 2 ranks
+ itr=RankMap.begin();
+ if (RankedSpells.size()<2)
+ continue;
+
count++;
- itr=RankMap.upper_bound(entry);
uint32 spell_rank=1;
for(std::list<uint32>::iterator itr2 = RankedSpells.begin();itr2!=RankedSpells.end();spell_rank++)
{
@@ -1733,8 +1792,8 @@ void SpellMgr::LoadSpellChains()
}
//uncomment these two lines to print yourself list of spell_chains on startup
-// for (UNORDERED_MAP<uint32, SpellChainNode>::iterator itr=mSpellChains.begin();itr!=mSpellChains.end();itr++)
-// sLog.outString( "Id: %u, Rank: %d , %s",itr->first,itr->second.rank, sSpellStore.LookupEntry(itr->first)->Rank[sWorld.GetDefaultDbcLocale()]);
+ //for (UNORDERED_MAP<uint32, SpellChainNode>::iterator itr=mSpellChains.begin();itr!=mSpellChains.end();itr++)
+ //sLog.outString( "Id: %u, Rank: %d , %s, %u, %u, %u, %u",itr->first,itr->second.rank, sSpellStore.LookupEntry(itr->first)->Rank[sWorld.GetDefaultDbcLocale()], itr->second.first, itr->second.last,itr->second.next ,itr->second.prev);
sLog.outString();
sLog.outString( ">> Loaded %u spell chains",count);
@@ -1746,8 +1805,10 @@ void SpellMgr::LoadSpellLearnSkills()
// search auto-learned skills and add its to map also for use in unlearn spells/talents
uint32 dbc_count = 0;
+ barGoLink bar( sSpellStore.GetNumRows() );
for(uint32 spell = 0; spell < sSpellStore.GetNumRows(); ++spell)
{
+ bar.step();
SpellEntry const* entry = sSpellStore.LookupEntry(spell);
if(!entry)
@@ -1782,7 +1843,8 @@ void SpellMgr::LoadSpellLearnSpells()
{
mSpellLearnSpells.clear(); // need for reload case
- QueryResult *result = WorldDatabase.Query("SELECT entry, SpellID FROM spell_learn_spell");
+ // 0 1 2
+ QueryResult *result = WorldDatabase.Query("SELECT entry, SpellID, Active FROM spell_learn_spell");
if(!result)
{
barGoLink bar( 1 );
@@ -1806,6 +1868,7 @@ void SpellMgr::LoadSpellLearnSpells()
SpellLearnSpellNode node;
node.spell = fields[1].GetUInt32();
+ node.active = fields[2].GetBool();
node.autoLearned= false;
if(!sSpellStore.LookupEntry(spell_id))
@@ -1842,7 +1905,16 @@ void SpellMgr::LoadSpellLearnSpells()
{
SpellLearnSpellNode dbc_node;
dbc_node.spell = entry->EffectTriggerSpell[i];
- dbc_node.autoLearned = true;
+ dbc_node.active = true; // all dbc based learned spells is active (show in spell book or hide by client itself)
+
+ // ignore learning not existed spells (broken/outdated/or generic learnig spell 483
+ if(!sSpellStore.LookupEntry(dbc_node.spell))
+ continue;
+
+ // talent or passive spells or skill-step spells auto-casted and not need dependent learning,
+ // pet teaching spells don't must be dependent learning (casted)
+ // other required explicit dependent learning
+ dbc_node.autoLearned = entry->EffectImplicitTargetA[i]==TARGET_PET || GetTalentSpellCost(spell) > 0 || IsPassiveSpell(spell) || IsSpellHaveEffect(entry,SPELL_EFFECT_SKILL_STEP);
SpellLearnSpellMap::const_iterator db_node_begin = GetBeginSpellLearnSpell(spell);
SpellLearnSpellMap::const_iterator db_node_end = GetEndSpellLearnSpell(spell);
@@ -2161,7 +2233,7 @@ void SpellMgr::LoadSpellCustomAttr()
}
}
- if(spellInfo->SpellVisual == 3879)
+ if(spellInfo->SpellVisual[0] == 3879)
mSpellCustomAttr[i] |= SPELL_ATTR_CU_CONE_BACK;
switch(i)
@@ -2303,6 +2375,187 @@ void SpellMgr::LoadSpellLinked()
}
/// Some checks for spells, to prevent adding depricated/broken spells for trainers, spell book, etc
+void SpellMgr::LoadPetLevelupSpellMap()
+{
+ CreatureFamilyEntry const *creatureFamily;
+ SpellEntry const *spell;
+ uint32 count = 0;
+
+ for (uint32 i = 0; i < sCreatureFamilyStore.GetNumRows(); ++i)
+ {
+ creatureFamily = sCreatureFamilyStore.LookupEntry(i);
+
+ if(!creatureFamily) // not exist
+ continue;
+
+ if(creatureFamily->petTalentType < 0) // not hunter pet family
+ continue;
+
+ for(uint32 j = 0; j < sSpellStore.GetNumRows(); ++j)
+ {
+ spell = sSpellStore.LookupEntry(j);
+
+ // not exist
+ if(!spell)
+ continue;
+
+ // not hunter spell
+ if(spell->SpellFamilyName != SPELLFAMILY_HUNTER)
+ continue;
+
+ // not pet spell
+ if(!(spell->SpellFamilyFlags[1] & 0x10000000))
+ continue;
+
+ // not Growl or Cower (generics)
+ if(spell->SpellIconID != 201 && spell->SpellIconID != 958)
+ {
+ switch(creatureFamily->ID)
+ {
+ case CREATURE_FAMILY_BAT: // Bite and Sonic Blast
+ if(spell->SpellIconID != 1680 && spell->SpellIconID != 1577)
+ continue;
+ break;
+ case CREATURE_FAMILY_BEAR: // Claw and Swipe
+ if(spell->SpellIconID != 262 && spell->SpellIconID != 1562)
+ continue;
+ break;
+ case CREATURE_FAMILY_BIRD_OF_PREY: // Claw and Snatch
+ if(spell->SpellIconID != 262 && spell->SpellIconID != 168)
+ continue;
+ break;
+ case CREATURE_FAMILY_BOAR: // Bite and Gore
+ if(spell->SpellIconID != 1680 && spell->SpellIconID != 1578)
+ continue;
+ break;
+ case CREATURE_FAMILY_CARRION_BIRD: // Bite and Demoralizing Screech
+ if(spell->SpellIconID != 1680 && spell->SpellIconID != 1579)
+ continue;
+ break;
+ case CREATURE_FAMILY_CAT: // Claw and Prowl and Rake
+ if(spell->SpellIconID != 262 && spell->SpellIconID != 495 && spell->SpellIconID != 494)
+ continue;
+ break;
+ case CREATURE_FAMILY_CHIMAERA: // Bite and Froststorm Breath
+ if(spell->SpellIconID != 1680 && spell->SpellIconID != 62)
+ continue;
+ break;
+ case CREATURE_FAMILY_CORE_HOUND: // Bite and Lava Breath
+ if(spell->SpellIconID != 1680 && spell->SpellIconID != 1197)
+ continue;
+ break;
+ case CREATURE_FAMILY_CRAB: // Claw and Pin
+ if(spell->SpellIconID != 262 && spell->SpellIconID != 2679)
+ continue;
+ break;
+ case CREATURE_FAMILY_CROCOLISK: // Bite and Bad Attitude
+ if(spell->SpellIconID != 1680 && spell->SpellIconID != 1581)
+ continue;
+ break;
+ case CREATURE_FAMILY_DEVILSAUR: // Bite and Monstrous Bite
+ if(spell->SpellIconID != 1680 && spell->SpellIconID != 599)
+ continue;
+ break;
+ case CREATURE_FAMILY_DRAGONHAWK: // Bite and Fire Breath
+ if(spell->SpellIconID != 1680 && spell->SpellIconID != 2128)
+ continue;
+ break;
+ case CREATURE_FAMILY_GORILLA: // Smack and Thunderstomp
+ if(spell->SpellIconID != 473 && spell->SpellIconID != 148)
+ continue;
+ break;
+ case CREATURE_FAMILY_HYENA: // Bite and Tendon Rip
+ if(spell->SpellIconID != 1680 && spell->SpellIconID != 138)
+ continue;
+ break;
+ case CREATURE_FAMILY_MOTH: // Serenity Dust and Smack
+ if(spell->SpellIconID != 1714 && spell->SpellIconID != 473)
+ continue;
+ break;
+ case CREATURE_FAMILY_NETHER_RAY: // Bite and Nether Shock
+ if(spell->SpellIconID != 1680 && spell->SpellIconID != 2027)
+ continue;
+ break;
+ case CREATURE_FAMILY_RAPTOR: // Claw and Savage Rend
+ if(spell->SpellIconID != 262 && spell->SpellIconID != 245)
+ continue;
+ break;
+ case CREATURE_FAMILY_RAVAGER: // Bite and Ravage
+ if(spell->SpellIconID != 1680 && spell->SpellIconID != 2253)
+ continue;
+ break;
+ case CREATURE_FAMILY_RHINO: // Smack and Stampede
+ if(spell->SpellIconID != 473 && spell->SpellIconID != 3066)
+ continue;
+ break;
+ case CREATURE_FAMILY_SCORPID: // Claw and Scorpid Poison
+ if(spell->SpellIconID != 262 && spell->SpellIconID != 163)
+ continue;
+ break;
+ case CREATURE_FAMILY_SERPENT: // Bite and Poison Spit
+ if(spell->SpellIconID != 1680 && spell->SpellIconID != 68)
+ continue;
+ break;
+ case CREATURE_FAMILY_SILITHID: // Claw and Venom Web Spray
+ if(spell->SpellIconID != 262 && (spell->SpellIconID != 272 && spell->SpellVisual[0] != 12013))
+ continue;
+ break;
+ case CREATURE_FAMILY_SPIDER: // Bite and Web
+ if(spell->SpellIconID != 1680 && (spell->SpellIconID != 272 && spell->SpellVisual[0] != 684))
+ continue;
+ break;
+ case CREATURE_FAMILY_SPIRIT_BEAST: // Claw and Prowl and Spirit Strike
+ if(spell->SpellIconID != 262 && spell->SpellIconID != 495 && spell->SpellIconID != 255)
+ continue;
+ break;
+ case CREATURE_FAMILY_SPOREBAT: // Smack and Spore Cloud
+ if(spell->SpellIconID != 473 && spell->SpellIconID != 2681)
+ continue;
+ break;
+ case CREATURE_FAMILY_TALLSTRIDER: // Claw and Dust Cloud
+ if(spell->SpellIconID != 262 && (spell->SpellIconID != 157 && !(spell->Attributes & 0x4000000)))
+ continue;
+ break;
+ case CREATURE_FAMILY_TURTLE: // Bite and Shell Shield
+ if(spell->SpellIconID != 1680 && spell->SpellIconID != 1588)
+ continue;
+ break;
+ case CREATURE_FAMILY_WARP_STALKER: // Bite and Warp
+ if(spell->SpellIconID != 1680 && spell->SpellIconID != 1952)
+ continue;
+ break;
+ case CREATURE_FAMILY_WASP: // Smack and Sting
+ if(spell->SpellIconID != 473 && spell->SpellIconID != 110)
+ continue;
+ break;
+ case CREATURE_FAMILY_WIND_SERPENT: // Bite and Lightning Breath
+ if(spell->SpellIconID != 1680 && spell->SpellIconID != 62)
+ continue;
+ break;
+ case CREATURE_FAMILY_WOLF: // Bite and Furious Howl
+ if(spell->SpellIconID != 1680 && spell->SpellIconID != 1573)
+ continue;
+ break;
+ case CREATURE_FAMILY_WORM: // Acid Spit and Bite
+ if(spell->SpellIconID != 636 && spell->SpellIconID != 1680)
+ continue;
+ break;
+ default:
+ sLog.outError("LoadPetLevelupSpellMap: Unhandled creature family %u", creatureFamily->ID);
+ continue;
+ }
+ }
+
+ mPetLevelupSpellMap[creatureFamily->ID][spell->spellLevel] = spell->Id;
+ count++;
+ }
+ }
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %u pet levelup spells", count );
+}
+
+/// Some checks for spells, to prevent adding deprecated/broken spells for trainers, spell book, etc
bool SpellMgr::IsSpellValid(SpellEntry const* spellInfo, Player* pl, bool msg)
{
// not exist
@@ -2377,11 +2630,24 @@ bool SpellMgr::IsSpellValid(SpellEntry const* spellInfo, Player* pl, bool msg)
return true;
}
-bool IsSpellAllowedInLocation(SpellEntry const *spellInfo,uint32 map_id,uint32 zone_id,uint32 area_id)
+uint8 GetSpellAllowedInLocationError(SpellEntry const *spellInfo,uint32 map_id,uint32 zone_id,uint32 area_id, uint32 bgInstanceId)
{
// normal case
- if( spellInfo->AreaId && spellInfo->AreaId != zone_id && spellInfo->AreaId != area_id )
- return false;
+ if( spellInfo->AreaGroupId > 0)
+ {
+ bool found = false;
+
+ AreaGroupEntry const* groupEntry = sAreaGroupStore.LookupEntry(spellInfo->AreaGroupId);
+ if(groupEntry)
+ {
+ for (uint8 i=0; i<7; i++)
+ if( groupEntry->AreaId[i] == zone_id || groupEntry->AreaId[i] == area_id )
+ found = true;
+ }
+
+ if(!found)
+ return SPELL_FAILED_INCORRECT_AREA;
+ }
// elixirs (all area dependent elixirs have family SPELLFAMILY_POTION, use this for speedup)
if(spellInfo->SpellFamilyName==SPELLFAMILY_POTION)
@@ -2391,28 +2657,28 @@ bool IsSpellAllowedInLocation(SpellEntry const *spellInfo,uint32 map_id,uint32 z
if(mask & ELIXIR_BATTLE_MASK)
{
if(spellInfo->Id==45373) // Bloodberry Elixir
- return zone_id==4075;
+ return zone_id==4075 ? 0 : SPELL_FAILED_REQUIRES_AREA;
}
if(mask & ELIXIR_UNSTABLE_MASK)
{
// in the Blade's Edge Mountains Plateaus and Gruul's Lair.
- return zone_id ==3522 || map_id==565;
+ return zone_id ==3522 || map_id==565 ? 0 : SPELL_FAILED_INCORRECT_AREA;
}
if(mask & ELIXIR_SHATTRATH_MASK)
{
// in Tempest Keep, Serpentshrine Cavern, Caverns of Time: Mount Hyjal, Black Temple, Sunwell Plateau
if(zone_id ==3607 || map_id==534 || map_id==564 || zone_id==4075)
- return true;
+ return 0;
MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
if(!mapEntry)
- return false;
+ return SPELL_FAILED_INCORRECT_AREA;
- return mapEntry->multimap_id==206;
+ return mapEntry->multimap_id==206 ? 0 : SPELL_FAILED_INCORRECT_AREA;
}
// elixirs not have another limitations
- return true;
+ return 0;
}
}
@@ -2424,35 +2690,104 @@ bool IsSpellAllowedInLocation(SpellEntry const *spellInfo,uint32 map_id,uint32 z
{
MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
if(!mapEntry)
- return false;
+ return SPELL_FAILED_INCORRECT_AREA;
- return mapEntry->multimap_id==206;
+ return mapEntry->multimap_id==206 ? 0 : SPELL_FAILED_REQUIRES_AREA;
}
case 41617: // Cenarion Mana Salve
case 41619: // Cenarion Healing Salve
{
MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
if(!mapEntry)
- return false;
+ return SPELL_FAILED_INCORRECT_AREA;
- return mapEntry->multimap_id==207;
+ return mapEntry->multimap_id==207 ? 0 : SPELL_FAILED_REQUIRES_AREA;
}
case 40216: // Dragonmaw Illusion
case 42016: // Dragonmaw Illusion
- return area_id == 3759 || area_id == 3966 || area_id == 3939;
+ return area_id == 3759 || area_id == 3966 || area_id == 3939 ? 0 : SPELL_FAILED_INCORRECT_AREA;
+ case 51721: // Dominion Over Acherus
+ case 54055: // Dominion Over Acherus
+ return area_id == 4281 || area_id == 4342 ? 0 : SPELL_FAILED_INCORRECT_AREA;
+ case 51852: // The Eye of Acherus
+ return map_id == 609 ? 0 : SPELL_FAILED_REQUIRES_AREA;
+ case 54119: // Mist of the Kvaldir
+ return area_id == 4028 || area_id == 4029 || area_id == 4106 || area_id == 4031 ? 0 : SPELL_FAILED_INCORRECT_AREA;
+ case 23333: // Warsong Flag
+ case 23335: // Silverwing Flag
+ return map_id == 489 && bgInstanceId ? 0 : SPELL_FAILED_REQUIRES_AREA;
+ case 34976: // Netherstorm Flag
+ return map_id == 566 && bgInstanceId ? 0 : SPELL_FAILED_REQUIRES_AREA;
+ case 2584: // Waiting to Resurrect
+ case 22011: // Spirit Heal Channel
+ case 22012: // Spirit Heal
+ case 24171: // Resurrection Impact Visual
+ case 42792: // Recently Dropped Flag
+ case 43681: // Inactive
+ case 44535: // Spirit Heal (mana)
+ {
+ MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
+ if(!mapEntry)
+ return SPELL_FAILED_INCORRECT_AREA;
+
+ return mapEntry->IsBattleGround() && bgInstanceId ? 0 : SPELL_FAILED_REQUIRES_AREA;
+ }
+ case 44521: // Preparation
+ {
+ if(!bgInstanceId)
+ return SPELL_FAILED_REQUIRES_AREA;
+
+ MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
+ if(!mapEntry)
+ return SPELL_FAILED_INCORRECT_AREA;
+
+ if(!mapEntry->IsBattleGround())
+ return SPELL_FAILED_REQUIRES_AREA;
+
+ BattleGround* bg = sBattleGroundMgr.GetBattleGround(bgInstanceId);
+ return bg && bg->GetStatus()==STATUS_WAIT_JOIN ? 0 : SPELL_FAILED_REQUIRES_AREA;
+ }
+ case 32724: // Gold Team (Alliance)
+ case 32725: // Green Team (Alliance)
+ case 35774: // Gold Team (Horde)
+ case 35775: // Green Team (Horde)
+ {
+ MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
+ if(!mapEntry)
+ return SPELL_FAILED_INCORRECT_AREA;
+
+ return mapEntry->IsBattleArena() && bgInstanceId ? 0 : SPELL_FAILED_REQUIRES_AREA;
+ }
+ case 32727: // Arena Preparation
+ {
+ if(!bgInstanceId)
+ return SPELL_FAILED_REQUIRES_AREA;
+
+ MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
+ if(!mapEntry)
+ return SPELL_FAILED_INCORRECT_AREA;
+
+ if(!mapEntry->IsBattleArena())
+ return SPELL_FAILED_REQUIRES_AREA;
+
+ BattleGround* bg = sBattleGroundMgr.GetBattleGround(bgInstanceId);
+ return bg && bg->GetStatus()==STATUS_WAIT_JOIN ? 0 : SPELL_FAILED_REQUIRES_AREA;
+ }
}
- return true;
+ return 0;
}
void SpellMgr::LoadSkillLineAbilityMap()
{
mSkillLineAbilityMap.clear();
+ barGoLink bar( sSkillLineAbilityStore.GetNumRows() );
uint32 count = 0;
for (uint32 i = 0; i < sSkillLineAbilityStore.GetNumRows(); i++)
{
+ bar.step();
SkillLineAbilityEntry const *SkillInfo = sSkillLineAbilityStore.LookupEntry(i);
if(!SkillInfo)
continue;
@@ -2462,7 +2797,7 @@ void SpellMgr::LoadSkillLineAbilityMap()
}
sLog.outString();
- sLog.outString(">> Loaded %u SkillLineAbility MultiMap", count);
+ sLog.outString(">> Loaded %u SkillLineAbility MultiMap Data", count);
}
DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto, bool triggered)
@@ -2470,56 +2805,49 @@ DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto
// Explicit Diminishing Groups
switch(spellproto->SpellFamilyName)
{
- case SPELLFAMILY_MAGE:
- {
- // Polymorph
- if ((spellproto->SpellFamilyFlags & 0x00001000000LL) && spellproto->EffectApplyAuraName[0]==SPELL_AURA_MOD_CONFUSE)
- return DIMINISHING_POLYMORPH;
- break;
- }
case SPELLFAMILY_ROGUE:
{
// Kidney Shot
- if (spellproto->SpellFamilyFlags & 0x00000200000LL)
+ if (spellproto->SpellFamilyFlags[0] & 0x200000)
return DIMINISHING_KIDNEYSHOT;
// Sap
- else if (spellproto->SpellFamilyFlags & 0x00000000080LL)
+ else if (spellproto->SpellFamilyFlags[0] & 0x80)
return DIMINISHING_POLYMORPH;
// Gouge
- else if (spellproto->SpellFamilyFlags & 0x00000000008LL)
+ else if (spellproto->SpellFamilyFlags[0] & 0x8)
return DIMINISHING_POLYMORPH;
// Blind
- else if (spellproto->SpellFamilyFlags & 0x00001000000LL)
+ else if (spellproto->SpellFamilyFlags[0] & 0x00001000000)
return DIMINISHING_BLIND_CYCLONE;
break;
}
case SPELLFAMILY_WARLOCK:
{
// Death Coil
- if (spellproto->SpellFamilyFlags & 0x00000080000LL)
+ if (spellproto->SpellFamilyFlags[0] & 0x00000080000)
return DIMINISHING_DEATHCOIL;
// Seduction
- if (spellproto->SpellFamilyFlags & 0x00040000000LL)
+ if (spellproto->SpellFamilyFlags[0] & 0x00040000000)
return DIMINISHING_FEAR;
// Fear
//else if (spellproto->SpellFamilyFlags & 0x40840000000LL)
// return DIMINISHING_WARLOCK_FEAR;
// Curses/etc
- else if (spellproto->SpellFamilyFlags & 0x00080000000LL)
+ else if (spellproto->SpellFamilyFlags[0] & 0x80000000)
return DIMINISHING_LIMITONLY;
break;
}
case SPELLFAMILY_DRUID:
{
// Cyclone
- if (spellproto->SpellFamilyFlags & 0x02000000000LL)
+ if (spellproto->SpellFamilyFlags[1] & 0x020)
return DIMINISHING_BLIND_CYCLONE;
break;
}
case SPELLFAMILY_WARRIOR:
{
// Hamstring - limit duration to 10s in PvP
- if (spellproto->SpellFamilyFlags & 0x00000000002LL)
+ if (spellproto->SpellFamilyFlags[0] & 0x00000000002)
return DIMINISHING_LIMITONLY;
break;
}
@@ -2528,30 +2856,21 @@ DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto
}
// Get by mechanic
- for (uint8 i=0;i<3;++i)
- {
- if (spellproto->Mechanic == MECHANIC_STUN || spellproto->EffectMechanic[i] == MECHANIC_STUN)
- return triggered ? DIMINISHING_TRIGGER_STUN : DIMINISHING_CONTROL_STUN;
- else if (spellproto->Mechanic == MECHANIC_SLEEP || spellproto->EffectMechanic[i] == MECHANIC_SLEEP)
- return DIMINISHING_SLEEP;
- else if (spellproto->Mechanic == MECHANIC_ROOT || spellproto->EffectMechanic[i] == MECHANIC_ROOT)
- return triggered ? DIMINISHING_TRIGGER_ROOT : DIMINISHING_CONTROL_ROOT;
- else if (spellproto->Mechanic == MECHANIC_FEAR || spellproto->EffectMechanic[i] == MECHANIC_FEAR)
- return DIMINISHING_FEAR;
- else if (spellproto->Mechanic == MECHANIC_CHARM || spellproto->EffectMechanic[i] == MECHANIC_CHARM)
- return DIMINISHING_CHARM;
- else if (spellproto->Mechanic == MECHANIC_SILENCE || spellproto->EffectMechanic[i] == MECHANIC_SILENCE)
- return DIMINISHING_SILENCE;
- else if (spellproto->Mechanic == MECHANIC_DISARM || spellproto->EffectMechanic[i] == MECHANIC_DISARM)
- return DIMINISHING_DISARM;
- else if (spellproto->Mechanic == MECHANIC_FREEZE || spellproto->EffectMechanic[i] == MECHANIC_FREEZE)
- return DIMINISHING_FREEZE;
- else if (spellproto->Mechanic == MECHANIC_KNOCKOUT|| spellproto->EffectMechanic[i] == MECHANIC_KNOCKOUT ||
- spellproto->Mechanic == MECHANIC_SAPPED || spellproto->EffectMechanic[i] == MECHANIC_SAPPED)
- return DIMINISHING_KNOCKOUT;
- else if (spellproto->Mechanic == MECHANIC_BANISH || spellproto->EffectMechanic[i] == MECHANIC_BANISH)
- return DIMINISHING_BANISH;
- }
+ uint32 mechanic = GetAllSpellMechanicMask(spellproto);
+ if (mechanic == MECHANIC_NONE) return DIMINISHING_NONE;
+ if (mechanic & (1<<MECHANIC_STUN)) return triggered ? DIMINISHING_TRIGGER_STUN : DIMINISHING_CONTROL_STUN;
+ if (mechanic & (1<<MECHANIC_SLEEP)) return DIMINISHING_SLEEP;
+ if (mechanic & (1<<MECHANIC_POLYMORPH)) return DIMINISHING_POLYMORPH;
+ if (mechanic & (1<<MECHANIC_ROOT)) return triggered ? DIMINISHING_TRIGGER_ROOT : DIMINISHING_CONTROL_ROOT;
+ if (mechanic & (1<<MECHANIC_FEAR)) return DIMINISHING_FEAR;
+ if (mechanic & (1<<MECHANIC_CHARM)) return DIMINISHING_CHARM;
+ if (mechanic & (1<<MECHANIC_SILENCE)) return DIMINISHING_SILENCE;
+ if (mechanic & (1<<DIMINISHING_DISARM)) return DIMINISHING_DISARM;
+ if (mechanic & (1<<MECHANIC_FREEZE)) return DIMINISHING_FREEZE;
+ if (mechanic & ((1<<MECHANIC_KNOCKOUT) | (1<<MECHANIC_SAPPED))) return DIMINISHING_KNOCKOUT;
+ if (mechanic & (1<<MECHANIC_BANISH)) return DIMINISHING_BANISH;
+ if (mechanic & (1<<MECHANIC_HORROR)) return DIMINISHING_DEATHCOIL;
+
return DIMINISHING_NONE;
}
diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h
index 747f40c064f..37a79c6adf6 100644
--- a/src/game/SpellMgr.h
+++ b/src/game/SpellMgr.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -10,12 +10,12 @@
*
* 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
+ * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _SPELLMGR_H
@@ -29,6 +29,9 @@
#include "Database/SQLStorage.h"
#include "Utilities/UnorderedMap.h"
+
+#include "Player.h"
+
#include <map>
class Player;
@@ -38,175 +41,188 @@ extern SQLStorage sSpellThreatStore;
enum SpellFailedReason
{
- SPELL_FAILED_AFFECTING_COMBAT = 0x00,
- SPELL_FAILED_ALREADY_AT_FULL_HEALTH = 0x01,
- SPELL_FAILED_ALREADY_AT_FULL_MANA = 0x02,
- SPELL_FAILED_ALREADY_AT_FULL_POWER = 0x03,
- SPELL_FAILED_ALREADY_BEING_TAMED = 0x04,
- SPELL_FAILED_ALREADY_HAVE_CHARM = 0x05,
- SPELL_FAILED_ALREADY_HAVE_SUMMON = 0x06,
- SPELL_FAILED_ALREADY_OPEN = 0x07,
- SPELL_FAILED_AURA_BOUNCED = 0x08,
- SPELL_FAILED_AUTOTRACK_INTERRUPTED = 0x09,
- SPELL_FAILED_BAD_IMPLICIT_TARGETS = 0x0A,
- SPELL_FAILED_BAD_TARGETS = 0x0B,
- SPELL_FAILED_CANT_BE_CHARMED = 0x0C,
- SPELL_FAILED_CANT_BE_DISENCHANTED = 0x0D,
- SPELL_FAILED_CANT_BE_DISENCHANTED_SKILL = 0x0E,
- SPELL_FAILED_CANT_BE_PROSPECTED = 0x0F,
- SPELL_FAILED_CANT_CAST_ON_TAPPED = 0x10,
- SPELL_FAILED_CANT_DUEL_WHILE_INVISIBLE = 0x11,
- SPELL_FAILED_CANT_DUEL_WHILE_STEALTHED = 0x12,
- SPELL_FAILED_CANT_STEALTH = 0x13,
- SPELL_FAILED_CASTER_AURASTATE = 0x14,
- SPELL_FAILED_CASTER_DEAD = 0x15,
- SPELL_FAILED_CHARMED = 0x16,
- SPELL_FAILED_CHEST_IN_USE = 0x17,
- SPELL_FAILED_CONFUSED = 0x18,
- SPELL_FAILED_DONT_REPORT = 0x19,
- SPELL_FAILED_EQUIPPED_ITEM = 0x1A,
- SPELL_FAILED_EQUIPPED_ITEM_CLASS = 0x1B,
- SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND = 0x1C,
- SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND = 0x1D,
- SPELL_FAILED_ERROR = 0x1E,
- SPELL_FAILED_FIZZLE = 0x1F,
- SPELL_FAILED_FLEEING = 0x20,
- SPELL_FAILED_FOOD_LOWLEVEL = 0x21,
- SPELL_FAILED_HIGHLEVEL = 0x22,
- SPELL_FAILED_HUNGER_SATIATED = 0x23,
- SPELL_FAILED_IMMUNE = 0x24,
- SPELL_FAILED_INTERRUPTED = 0x25,
- SPELL_FAILED_INTERRUPTED_COMBAT = 0x26,
- SPELL_FAILED_ITEM_ALREADY_ENCHANTED = 0x27,
- SPELL_FAILED_ITEM_GONE = 0x28,
- SPELL_FAILED_ITEM_NOT_FOUND = 0x29,
- SPELL_FAILED_ITEM_NOT_READY = 0x2A,
- SPELL_FAILED_LEVEL_REQUIREMENT = 0x2B,
- SPELL_FAILED_LINE_OF_SIGHT = 0x2C,
- SPELL_FAILED_LOWLEVEL = 0x2D,
- SPELL_FAILED_LOW_CASTLEVEL = 0x2E,
- SPELL_FAILED_MAINHAND_EMPTY = 0x2F,
- SPELL_FAILED_MOVING = 0x30,
- SPELL_FAILED_NEED_AMMO = 0x31,
- SPELL_FAILED_NEED_AMMO_POUCH = 0x32,
- SPELL_FAILED_NEED_EXOTIC_AMMO = 0x33,
- SPELL_FAILED_NOPATH = 0x34,
- SPELL_FAILED_NOT_BEHIND = 0x35,
- SPELL_FAILED_NOT_FISHABLE = 0x36,
- SPELL_FAILED_NOT_FLYING = 0x37,
- SPELL_FAILED_NOT_HERE = 0x38,
- SPELL_FAILED_NOT_INFRONT = 0x39,
- SPELL_FAILED_NOT_IN_CONTROL = 0x3A,
- SPELL_FAILED_NOT_KNOWN = 0x3B,
- SPELL_FAILED_NOT_MOUNTED = 0x3C,
- SPELL_FAILED_NOT_ON_TAXI = 0x3D,
- SPELL_FAILED_NOT_ON_TRANSPORT = 0x3E,
- SPELL_FAILED_NOT_READY = 0x3F,
- SPELL_FAILED_NOT_SHAPESHIFT = 0x40,
- SPELL_FAILED_NOT_STANDING = 0x41,
- SPELL_FAILED_NOT_TRADEABLE = 0x42,
- SPELL_FAILED_NOT_TRADING = 0x43,
- SPELL_FAILED_NOT_UNSHEATHED = 0x44,
- SPELL_FAILED_NOT_WHILE_GHOST = 0x45,
- SPELL_FAILED_NO_AMMO = 0x46,
- SPELL_FAILED_NO_CHARGES_REMAIN = 0x47,
- SPELL_FAILED_NO_CHAMPION = 0x48,
- SPELL_FAILED_NO_COMBO_POINTS = 0x49,
- SPELL_FAILED_NO_DUELING = 0x4A,
- SPELL_FAILED_NO_ENDURANCE = 0x4B,
- SPELL_FAILED_NO_FISH = 0x4C,
- SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED = 0x4D,
- SPELL_FAILED_NO_MOUNTS_ALLOWED = 0x4E,
- SPELL_FAILED_NO_PET = 0x4F,
- SPELL_FAILED_NO_POWER = 0x50,
- SPELL_FAILED_NOTHING_TO_DISPEL = 0x51,
- SPELL_FAILED_NOTHING_TO_STEAL = 0x52,
- SPELL_FAILED_ONLY_ABOVEWATER = 0x53,
- SPELL_FAILED_ONLY_DAYTIME = 0x54,
- SPELL_FAILED_ONLY_INDOORS = 0x55,
- SPELL_FAILED_ONLY_MOUNTED = 0x56,
- SPELL_FAILED_ONLY_NIGHTTIME = 0x57,
- SPELL_FAILED_ONLY_OUTDOORS = 0x58,
- SPELL_FAILED_ONLY_SHAPESHIFT = 0x59,
- SPELL_FAILED_ONLY_STEALTHED = 0x5A,
- SPELL_FAILED_ONLY_UNDERWATER = 0x5B,
- SPELL_FAILED_OUT_OF_RANGE = 0x5C,
- SPELL_FAILED_PACIFIED = 0x5D,
- SPELL_FAILED_POSSESSED = 0x5E,
- SPELL_FAILED_REAGENTS = 0x5F,
- SPELL_FAILED_REQUIRES_AREA = 0x60,
- SPELL_FAILED_REQUIRES_SPELL_FOCUS = 0x61,
- SPELL_FAILED_ROOTED = 0x62,
- SPELL_FAILED_SILENCED = 0x63,
- SPELL_FAILED_SPELL_IN_PROGRESS = 0x64,
- SPELL_FAILED_SPELL_LEARNED = 0x65,
- SPELL_FAILED_SPELL_UNAVAILABLE = 0x66,
- SPELL_FAILED_STUNNED = 0x67,
- SPELL_FAILED_TARGETS_DEAD = 0x68,
- SPELL_FAILED_TARGET_AFFECTING_COMBAT = 0x69,
- SPELL_FAILED_TARGET_AURASTATE = 0x6A,
- SPELL_FAILED_TARGET_DUELING = 0x6B,
- SPELL_FAILED_TARGET_ENEMY = 0x6C,
- SPELL_FAILED_TARGET_ENRAGED = 0x6D,
- SPELL_FAILED_TARGET_FRIENDLY = 0x6E,
- SPELL_FAILED_TARGET_IN_COMBAT = 0x6F,
- SPELL_FAILED_TARGET_IS_PLAYER = 0x70,
- SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED = 0x71,
- SPELL_FAILED_TARGET_NOT_DEAD = 0x72,
- SPELL_FAILED_TARGET_NOT_IN_PARTY = 0x73,
- SPELL_FAILED_TARGET_NOT_LOOTED = 0x74,
- SPELL_FAILED_TARGET_NOT_PLAYER = 0x75,
- SPELL_FAILED_TARGET_NO_POCKETS = 0x76,
- SPELL_FAILED_TARGET_NO_WEAPONS = 0x77,
- SPELL_FAILED_TARGET_UNSKINNABLE = 0x78,
- SPELL_FAILED_THIRST_SATIATED = 0x79,
- SPELL_FAILED_TOO_CLOSE = 0x7A,
- SPELL_FAILED_TOO_MANY_OF_ITEM = 0x7B,
- SPELL_FAILED_TOTEM_CATEGORY = 0x7C,
- SPELL_FAILED_TOTEMS = 0x7D,
- SPELL_FAILED_TRAINING_POINTS = 0x7E,
- SPELL_FAILED_TRY_AGAIN = 0x7F,
- SPELL_FAILED_UNIT_NOT_BEHIND = 0x80,
- SPELL_FAILED_UNIT_NOT_INFRONT = 0x81,
- SPELL_FAILED_WRONG_PET_FOOD = 0x82,
- SPELL_FAILED_NOT_WHILE_FATIGUED = 0x83,
- SPELL_FAILED_TARGET_NOT_IN_INSTANCE = 0x84,
- SPELL_FAILED_NOT_WHILE_TRADING = 0x85,
- SPELL_FAILED_TARGET_NOT_IN_RAID = 0x86,
- SPELL_FAILED_DISENCHANT_WHILE_LOOTING = 0x87,
- SPELL_FAILED_PROSPECT_WHILE_LOOTING = 0x88,
- SPELL_FAILED_PROSPECT_NEED_MORE = 0x89,
- SPELL_FAILED_TARGET_FREEFORALL = 0x8A,
- SPELL_FAILED_NO_EDIBLE_CORPSES = 0x8B,
- SPELL_FAILED_ONLY_BATTLEGROUNDS = 0x8C,
- SPELL_FAILED_TARGET_NOT_GHOST = 0x8D,
- SPELL_FAILED_TOO_MANY_SKILLS = 0x8E,
- SPELL_FAILED_TRANSFORM_UNUSABLE = 0x8F,
- SPELL_FAILED_WRONG_WEATHER = 0x90,
- SPELL_FAILED_DAMAGE_IMMUNE = 0x91,
- SPELL_FAILED_PREVENTED_BY_MECHANIC = 0x92,
- SPELL_FAILED_PLAY_TIME = 0x93,
- SPELL_FAILED_REPUTATION = 0x94,
- SPELL_FAILED_MIN_SKILL = 0x95,
- SPELL_FAILED_NOT_IN_ARENA = 0x96,
- SPELL_FAILED_NOT_ON_SHAPESHIFT = 0x97,
- SPELL_FAILED_NOT_ON_STEALTHED = 0x98,
- SPELL_FAILED_NOT_ON_DAMAGE_IMMUNE = 0x99,
- SPELL_FAILED_NOT_ON_MOUNTED = 0x9A,
- SPELL_FAILED_TOO_SHALLOW = 0x9B,
- SPELL_FAILED_TARGET_NOT_IN_SANCTUARY = 0x9C,
- SPELL_FAILED_TARGET_IS_TRIVIAL = 0x9D,
- SPELL_FAILED_BM_OR_INVISGOD = 0x9E,
- SPELL_FAILED_EXPERT_RIDING_REQUIREMENT = 0x9F,
- SPELL_FAILED_ARTISAN_RIDING_REQUIREMENT = 0xA0,
- SPELL_FAILED_NOT_IDLE = 0xA1,
- SPELL_FAILED_NOT_INACTIVE = 0xA2,
- SPELL_FAILED_PARTIAL_PLAYTIME = 0xA3,
- SPELL_FAILED_NO_PLAYTIME = 0xA4,
- SPELL_FAILED_NOT_IN_BATTLEGROUND = 0xA5,
- SPELL_FAILED_ONLY_IN_ARENA = 0xA6,
- SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE = 0xA7,
- SPELL_FAILED_UNKNOWN = 0xA8,
+ SPELL_FAILED_AFFECTING_COMBAT = 0,
+ SPELL_FAILED_ALREADY_AT_FULL_HEALTH = 1,
+ SPELL_FAILED_ALREADY_AT_FULL_MANA = 2,
+ SPELL_FAILED_ALREADY_AT_FULL_POWER = 3,
+ SPELL_FAILED_ALREADY_BEING_TAMED = 4,
+ SPELL_FAILED_ALREADY_HAVE_CHARM = 5,
+ SPELL_FAILED_ALREADY_HAVE_SUMMON = 6,
+ SPELL_FAILED_ALREADY_OPEN = 7,
+ SPELL_FAILED_AURA_BOUNCED = 8,
+ SPELL_FAILED_AUTOTRACK_INTERRUPTED = 9,
+ SPELL_FAILED_BAD_IMPLICIT_TARGETS = 10,
+ SPELL_FAILED_BAD_TARGETS = 11,
+ SPELL_FAILED_CANT_BE_CHARMED = 12,
+ SPELL_FAILED_CANT_BE_DISENCHANTED = 13,
+ SPELL_FAILED_CANT_BE_DISENCHANTED_SKILL = 14,
+ SPELL_FAILED_CANT_BE_MILLED = 15,
+ SPELL_FAILED_CANT_BE_PROSPECTED = 16,
+ SPELL_FAILED_CANT_CAST_ON_TAPPED = 17,
+ SPELL_FAILED_CANT_DUEL_WHILE_INVISIBLE = 18,
+ SPELL_FAILED_CANT_DUEL_WHILE_STEALTHED = 19,
+ SPELL_FAILED_CANT_STEALTH = 20,
+ SPELL_FAILED_CASTER_AURASTATE = 21,
+ SPELL_FAILED_CASTER_DEAD = 22,
+ SPELL_FAILED_CHARMED = 23,
+ SPELL_FAILED_CHEST_IN_USE = 24,
+ SPELL_FAILED_CONFUSED = 25,
+ SPELL_FAILED_DONT_REPORT = 26,
+ SPELL_FAILED_EQUIPPED_ITEM = 27,
+ SPELL_FAILED_EQUIPPED_ITEM_CLASS = 28,
+ SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND = 29,
+ SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND = 30,
+ SPELL_FAILED_ERROR = 31,
+ SPELL_FAILED_FIZZLE = 32,
+ SPELL_FAILED_FLEEING = 33,
+ SPELL_FAILED_FOOD_LOWLEVEL = 34,
+ SPELL_FAILED_HIGHLEVEL = 35,
+ SPELL_FAILED_HUNGER_SATIATED = 36,
+ SPELL_FAILED_IMMUNE = 37,
+ SPELL_FAILED_INCORRECT_AREA = 38,
+ SPELL_FAILED_INTERRUPTED = 39,
+ SPELL_FAILED_INTERRUPTED_COMBAT = 40,
+ SPELL_FAILED_ITEM_ALREADY_ENCHANTED = 41,
+ SPELL_FAILED_ITEM_GONE = 42,
+ SPELL_FAILED_ITEM_NOT_FOUND = 43,
+ SPELL_FAILED_ITEM_NOT_READY = 44,
+ SPELL_FAILED_LEVEL_REQUIREMENT = 45,
+ SPELL_FAILED_LINE_OF_SIGHT = 46,
+ SPELL_FAILED_LOWLEVEL = 47,
+ SPELL_FAILED_LOW_CASTLEVEL = 48,
+ SPELL_FAILED_MAINHAND_EMPTY = 49,
+ SPELL_FAILED_MOVING = 50,
+ SPELL_FAILED_NEED_AMMO = 51,
+ SPELL_FAILED_NEED_AMMO_POUCH = 52,
+ SPELL_FAILED_NEED_EXOTIC_AMMO = 53,
+ SPELL_FAILED_NEED_MORE_ITEMS = 54,
+ SPELL_FAILED_NOPATH = 55,
+ SPELL_FAILED_NOT_BEHIND = 56,
+ SPELL_FAILED_NOT_FISHABLE = 57,
+ SPELL_FAILED_NOT_FLYING = 58,
+ SPELL_FAILED_NOT_HERE = 59,
+ SPELL_FAILED_NOT_INFRONT = 60,
+ SPELL_FAILED_NOT_IN_CONTROL = 61,
+ SPELL_FAILED_NOT_KNOWN = 62,
+ SPELL_FAILED_NOT_MOUNTED = 63,
+ SPELL_FAILED_NOT_ON_TAXI = 64,
+ SPELL_FAILED_NOT_ON_TRANSPORT = 65,
+ SPELL_FAILED_NOT_READY = 66,
+ SPELL_FAILED_NOT_SHAPESHIFT = 67,
+ SPELL_FAILED_NOT_STANDING = 68,
+ SPELL_FAILED_NOT_TRADEABLE = 69,
+ SPELL_FAILED_NOT_TRADING = 70,
+ SPELL_FAILED_NOT_UNSHEATHED = 71,
+ SPELL_FAILED_NOT_WHILE_GHOST = 72,
+ SPELL_FAILED_NOT_WHILE_LOOTING = 73,
+ SPELL_FAILED_NO_AMMO = 74,
+ SPELL_FAILED_NO_CHARGES_REMAIN = 75,
+ SPELL_FAILED_NO_CHAMPION = 76,
+ SPELL_FAILED_NO_COMBO_POINTS = 77,
+ SPELL_FAILED_NO_DUELING = 78,
+ SPELL_FAILED_NO_ENDURANCE = 79,
+ SPELL_FAILED_NO_FISH = 80,
+ SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED = 81,
+ SPELL_FAILED_NO_MOUNTS_ALLOWED = 82,
+ SPELL_FAILED_NO_PET = 83,
+ SPELL_FAILED_NO_POWER = 84,
+ SPELL_FAILED_NOTHING_TO_DISPEL = 85,
+ SPELL_FAILED_NOTHING_TO_STEAL = 86,
+ SPELL_FAILED_ONLY_ABOVEWATER = 87,
+ SPELL_FAILED_ONLY_DAYTIME = 88,
+ SPELL_FAILED_ONLY_INDOORS = 89,
+ SPELL_FAILED_ONLY_MOUNTED = 90,
+ SPELL_FAILED_ONLY_NIGHTTIME = 91,
+ SPELL_FAILED_ONLY_OUTDOORS = 92,
+ SPELL_FAILED_ONLY_SHAPESHIFT = 93,
+ SPELL_FAILED_ONLY_STEALTHED = 94,
+ SPELL_FAILED_ONLY_UNDERWATER = 95,
+ SPELL_FAILED_OUT_OF_RANGE = 96,
+ SPELL_FAILED_PACIFIED = 97,
+ SPELL_FAILED_POSSESSED = 98,
+ SPELL_FAILED_REAGENTS = 99,
+ SPELL_FAILED_REQUIRES_AREA = 100,
+ SPELL_FAILED_REQUIRES_SPELL_FOCUS = 101,
+ SPELL_FAILED_ROOTED = 102,
+ SPELL_FAILED_SILENCED = 103,
+ SPELL_FAILED_SPELL_IN_PROGRESS = 104,
+ SPELL_FAILED_SPELL_LEARNED = 105,
+ SPELL_FAILED_SPELL_UNAVAILABLE = 106,
+ SPELL_FAILED_STUNNED = 107,
+ SPELL_FAILED_TARGETS_DEAD = 108,
+ SPELL_FAILED_TARGET_AFFECTING_COMBAT = 109,
+ SPELL_FAILED_TARGET_AURASTATE = 110,
+ SPELL_FAILED_TARGET_DUELING = 111,
+ SPELL_FAILED_TARGET_ENEMY = 112,
+ SPELL_FAILED_TARGET_ENRAGED = 113,
+ SPELL_FAILED_TARGET_FRIENDLY = 114,
+ SPELL_FAILED_TARGET_IN_COMBAT = 115,
+ SPELL_FAILED_TARGET_IS_PLAYER = 116,
+ SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED = 117,
+ SPELL_FAILED_TARGET_NOT_DEAD = 118,
+ SPELL_FAILED_TARGET_NOT_IN_PARTY = 119,
+ SPELL_FAILED_TARGET_NOT_LOOTED = 120,
+ SPELL_FAILED_TARGET_NOT_PLAYER = 121,
+ SPELL_FAILED_TARGET_NO_POCKETS = 122,
+ SPELL_FAILED_TARGET_NO_WEAPONS = 123,
+ SPELL_FAILED_TARGET_NO_RANGED_WEAPONS = 124,
+ SPELL_FAILED_TARGET_UNSKINNABLE = 125,
+ SPELL_FAILED_THIRST_SATIATED = 126,
+ SPELL_FAILED_TOO_CLOSE = 127,
+ SPELL_FAILED_TOO_MANY_OF_ITEM = 128,
+ SPELL_FAILED_TOTEM_CATEGORY = 129,
+ SPELL_FAILED_TOTEMS = 130,
+ SPELL_FAILED_TRY_AGAIN = 131,
+ SPELL_FAILED_UNIT_NOT_BEHIND = 132,
+ SPELL_FAILED_UNIT_NOT_INFRONT = 133,
+ SPELL_FAILED_WRONG_PET_FOOD = 134,
+ SPELL_FAILED_NOT_WHILE_FATIGUED = 135,
+ SPELL_FAILED_TARGET_NOT_IN_INSTANCE = 136,
+ SPELL_FAILED_NOT_WHILE_TRADING = 137,
+ SPELL_FAILED_TARGET_NOT_IN_RAID = 138,
+ SPELL_FAILED_TARGET_FREEFORALL = 139,
+ SPELL_FAILED_NO_EDIBLE_CORPSES = 140,
+ SPELL_FAILED_ONLY_BATTLEGROUNDS = 141,
+ SPELL_FAILED_TARGET_NOT_GHOST = 142,
+ SPELL_FAILED_TRANSFORM_UNUSABLE = 143,
+ SPELL_FAILED_WRONG_WEATHER = 144,
+ SPELL_FAILED_DAMAGE_IMMUNE = 145,
+ SPELL_FAILED_PREVENTED_BY_MECHANIC = 146,
+ SPELL_FAILED_PLAY_TIME = 147,
+ SPELL_FAILED_REPUTATION = 148,
+ SPELL_FAILED_MIN_SKILL = 149,
+ SPELL_FAILED_NOT_IN_ARENA = 150,
+ SPELL_FAILED_NOT_ON_SHAPESHIFT = 151,
+ SPELL_FAILED_NOT_ON_STEALTHED = 152,
+ SPELL_FAILED_NOT_ON_DAMAGE_IMMUNE = 153,
+ SPELL_FAILED_NOT_ON_MOUNTED = 154,
+ SPELL_FAILED_TOO_SHALLOW = 155,
+ SPELL_FAILED_TARGET_NOT_IN_SANCTUARY = 156,
+ SPELL_FAILED_TARGET_IS_TRIVIAL = 157,
+ SPELL_FAILED_BM_OR_INVISGOD = 158,
+ SPELL_FAILED_EXPERT_RIDING_REQUIREMENT = 159,
+ SPELL_FAILED_ARTISAN_RIDING_REQUIREMENT = 160,
+ SPELL_FAILED_NOT_IDLE = 161,
+ SPELL_FAILED_NOT_INACTIVE = 162,
+ SPELL_FAILED_PARTIAL_PLAYTIME = 163,
+ SPELL_FAILED_NO_PLAYTIME = 164,
+ SPELL_FAILED_NOT_IN_BATTLEGROUND = 165,
+ SPELL_FAILED_NOT_IN_RAID_INSTANCE = 166,
+ SPELL_FAILED_ONLY_IN_ARENA = 167,
+ SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE = 168,
+ SPELL_FAILED_ON_USE_ENCHANT = 169,
+ SPELL_FAILED_NOT_ON_GROUND = 170,
+ SPELL_FAILED_CUSTOM_ERROR = 171,
+ SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW = 172,
+ SPELL_FAILED_TOO_MANY_SOCKETS = 173,
+ SPELL_FAILED_INVALID_GLYPH = 174,
+ SPELL_FAILED_UNIQUE_GLYPH = 175,
+ SPELL_FAILED_GLYPH_SOCKET_LOCKED = 176,
+ SPELL_FAILED_NO_VALID_TARGETS = 177,
+ SPELL_FAILED_ITEM_AT_MAX_CHARGES = 178,
+ SPELL_FAILED_NOT_IN_BARBERSHOP = 179,
+ SPELL_FAILED_FISHING_TOO_LOW = 180,
+ SPELL_FAILED_UNKNOWN = 181
};
enum SpellFamilyNames
@@ -223,8 +239,12 @@ enum SpellFamilyNames
SPELLFAMILY_HUNTER = 9,
SPELLFAMILY_PALADIN = 10,
SPELLFAMILY_SHAMAN = 11,
- SPELLFAMILY_UNK2 = 12,
- SPELLFAMILY_POTION = 13
+ SPELLFAMILY_UNK2 = 12, // 2 spells (silence resistance)
+ SPELLFAMILY_POTION = 13,
+ // 14 - unused
+ SPELLFAMILY_DEATHKNIGHT = 15,
+ // 16 - unused
+ SPELLFAMILY_PET = 17
};
enum SpellDisableTypes
@@ -255,15 +275,15 @@ enum SpellSelectTargetTypes
};
//Some SpellFamilyFlags
-#define SPELLFAMILYFLAG_ROGUE_VANISH 0x000000800LL
-#define SPELLFAMILYFLAG_ROGUE_STEALTH 0x000400000LL
-#define SPELLFAMILYFLAG_ROGUE_BACKSTAB 0x000800004LL
-#define SPELLFAMILYFLAG_ROGUE_SAP 0x000000080LL
-#define SPELLFAMILYFLAG_ROGUE_FEINT 0x008000000LL
-#define SPELLFAMILYFLAG_ROGUE_KIDNEYSHOT 0x000200000LL
-#define SPELLFAMILYFLAG_ROGUE__FINISHING_MOVE 0x9003E0000LL
-#define SPELLFAMILYFLAG_WARRIOR_SUNDERARMOR 0x000004000LL
-#define SPELLFAMILYFLAG_SHAMAN_FROST_SHOCK 0x080000000LL
+#define SPELLFAMILYFLAG_ROGUE_VANISH 0x00000800
+#define SPELLFAMILYFLAG_ROGUE_STEALTH 0x00400000
+#define SPELLFAMILYFLAG_ROGUE_BACKSTAB 0x00800004
+#define SPELLFAMILYFLAG_ROGUE_SAP 0x00000080
+#define SPELLFAMILYFLAG_ROGUE_FEINT 0x08000000
+#define SPELLFAMILYFLAG_ROGUE_KIDNEYSHOT 0x00200000
+//#define SPELLFAMILYFLAG_ROGUE__FINISHING_MOVE 0x9003E0000LL
+#define SPELLFAMILYFLAG_WARRIOR_SUNDERARMOR 0x00004000
+#define SPELLFAMILYFLAG_SHAMAN_FROST_SHOCK 0x80000000
// Spell clasification
enum SpellSpecific
@@ -288,7 +308,8 @@ enum SpellSpecific
SPELL_WARLOCK_CORRUPTION= 17,
SPELL_WELL_FED = 18,
SPELL_DRINK = 19,
- SPELL_FOOD = 20
+ SPELL_FOOD = 20,
+ SPELL_PRESENCE = 21,
};
#define SPELL_LINKED_MAX_SPELLS 200000
@@ -327,13 +348,27 @@ inline bool IsSealSpell(SpellEntry const *spellInfo)
{
//Collection of all the seal family flags. No other paladin spell has any of those.
return spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN &&
- ( spellInfo->SpellFamilyFlags & 0x4000A000200LL );
+ ( spellInfo->SpellFamilyFlags[1] & 0x26000C00
+ || spellInfo->SpellFamilyFlags[0] & 0x0A000000 );
}
inline bool IsElementalShield(SpellEntry const *spellInfo)
{
// family flags 10 (Lightning), 42 (Earth), 37 (Water), proc shield from T2 8 pieces bonus
- return (spellInfo->SpellFamilyFlags & 0x42000000400LL) || spellInfo->Id == 23552;
+ return (spellInfo->SpellFamilyFlags[1] & 0x420
+ || spellInfo->SpellFamilyFlags[0] & 0x00000400)
+ || spellInfo->Id == 23552;
+}
+
+inline bool IsExplicitDiscoverySpell(SpellEntry const *spellInfo)
+{
+ return spellInfo->Effect[0]==SPELL_EFFECT_CREATE_ITEM_2 && spellInfo->Effect[1]==SPELL_EFFECT_SCRIPT_EFFECT;
+}
+
+inline bool IsLootCraftingSpell(SpellEntry const *spellInfo)
+{
+ return spellInfo->Effect[0]==SPELL_EFFECT_CREATE_ITEM_2 &&
+ (spellInfo->Effect[1]==SPELL_EFFECT_SCRIPT_EFFECT || !spellInfo->EffectItemType[0]);
}
int32 CompareAuraRanks(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2);
@@ -341,6 +376,15 @@ bool IsSingleFromSpellSpecificPerCaster(uint32 spellSpec1, uint32 spellSpec2);
bool IsSingleFromSpellSpecificPerTarget(uint32 spellSpec1, uint32 spellSpec2);
bool IsPassiveSpell(uint32 spellId);
+inline bool IsPassiveSpellStackableWithRanks(SpellEntry const* spellProto)
+{
+ if(!IsPassiveSpell(spellProto->Id))
+ return false;
+
+ return !IsSpellHaveEffect(spellProto,SPELL_EFFECT_APPLY_AURA);
+}
+
+
inline bool IsDeathPersistentSpell(SpellEntry const *spellInfo)
{
switch(spellInfo->Id)
@@ -368,9 +412,10 @@ bool IsSingleTargetSpells(SpellEntry const *spellInfo1, SpellEntry const *spellI
bool IsAuraAddedBySpell(uint32 auraType, uint32 spellId);
-bool IsSpellAllowedInLocation(SpellEntry const *spellInfo,uint32 map_id,uint32 zone_id,uint32 area_id);
+uint8 GetSpellAllowedInLocationError(SpellEntry const *spellInfo,uint32 map_id,uint32 zone_id,uint32 area_id,uint32 bgInstanceId);
extern bool IsAreaEffectTarget[TOTAL_SPELL_TARGETS];
+
inline bool IsAreaOfEffectSpell(SpellEntry const *spellInfo)
{
if(IsAreaEffectTarget[spellInfo->EffectImplicitTargetA[0]] || IsAreaEffectTarget[spellInfo->EffectImplicitTargetB[0]])
@@ -385,6 +430,7 @@ inline bool IsAreaOfEffectSpell(SpellEntry const *spellInfo)
inline bool IsAreaAuraEffect(uint32 effect)
{
if( effect == SPELL_EFFECT_APPLY_AREA_AURA_PARTY ||
+ effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID ||
effect == SPELL_EFFECT_APPLY_AREA_AURA_FRIEND ||
effect == SPELL_EFFECT_APPLY_AREA_AURA_ENEMY ||
effect == SPELL_EFFECT_APPLY_AREA_AURA_PET ||
@@ -417,6 +463,11 @@ inline bool isSpellBreakStealth(SpellEntry const* spellInfo)
return !(spellInfo->AttributesEx & SPELL_ATTR_EX_NOT_BREAK_STEALTH);
}
+inline bool IsAutoRepeatRangedSpell(SpellEntry const* spellInfo)
+{
+ return (spellInfo->Attributes & SPELL_ATTR_RANGED) && (spellInfo->AttributesEx2 & SPELL_ATTR_EX2_AUTOREPEAT_FLAG);
+}
+
uint8 GetErrorAtShapeshiftedCast (SpellEntry const *spellInfo, uint32 form);
inline bool IsChanneledSpell(SpellEntry const* spellInfo)
@@ -444,6 +495,17 @@ inline uint32 GetSpellMechanicMask(SpellEntry const* spellInfo, int32 effect)
return mask;
}
+inline uint32 GetAllSpellMechanicMask(SpellEntry const* spellInfo)
+{
+ uint32 mask = 0;
+ if (spellInfo->Mechanic)
+ mask |= 1<<spellInfo->Mechanic;
+ for (int i=0; i< 3; ++i)
+ if (spellInfo->EffectMechanic[i])
+ mask |= 1<<spellInfo->EffectMechanic[i];
+ return mask;
+}
+
inline Mechanics GetEffectMechanic(SpellEntry const* spellInfo, int32 effect)
{
if (spellInfo->EffectMechanic[effect])
@@ -468,7 +530,7 @@ bool IsDiminishingReturnsGroupDurationLimited(DiminishingGroup group);
DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group);
// Spell affects related declarations (accessed using SpellMgr functions)
-typedef std::map<uint32, uint64> SpellAffectMap;
+typedef UNORDERED_MAP<uint32, flag96> SpellAffectMap;
// Spell proc event related declarations (accessed using SpellMgr functions)
enum ProcFlags
@@ -476,16 +538,16 @@ enum ProcFlags
PROC_FLAG_NONE = 0x00000000,
PROC_FLAG_KILLED = 0x00000001, // 00 Killed by agressor
- PROC_FLAG_KILL_AND_GET_XP = 0x00000002, // 01 Kill that yields experience or honor
+ PROC_FLAG_KILL = 0x00000002, // 01 Kill target (in most cases need XP/Honor reward)
- PROC_FLAG_SUCCESSFUL_MILEE_HIT = 0x00000004, // 02 Successful melee attack
- PROC_FLAG_TAKEN_MELEE_HIT = 0x00000008, // 03 Taken damage from melee strike hit
+ PROC_FLAG_SUCCESSFUL_MILEE_HIT = 0x00000004, // 02 Successful melee auto attack
+ PROC_FLAG_TAKEN_MELEE_HIT = 0x00000008, // 03 Taken damage from melee auto attack hit
PROC_FLAG_SUCCESSFUL_MELEE_SPELL_HIT = 0x00000010, // 04 Successful attack by Spell that use melee weapon
PROC_FLAG_TAKEN_MELEE_SPELL_HIT = 0x00000020, // 05 Taken damage by Spell that use melee weapon
- PROC_FLAG_SUCCESSFUL_RANGED_HIT = 0x00000040, // 06 Successful Ranged attack (all ranged attack deal as spell so newer set :( )
- PROC_FLAG_TAKEN_RANGED_HIT = 0x00000080, // 07 Taken damage from ranged attack (all ranged attack deal as spell so newer set :( )
+ PROC_FLAG_SUCCESSFUL_RANGED_HIT = 0x00000040, // 06 Successful Ranged auto attack
+ PROC_FLAG_TAKEN_RANGED_HIT = 0x00000080, // 07 Taken damage from ranged auto attack
PROC_FLAG_SUCCESSFUL_RANGED_SPELL_HIT = 0x00000100, // 08 Successful Ranged attack by Spell that use ranged weapon
PROC_FLAG_TAKEN_RANGED_SPELL_HIT = 0x00000200, // 09 Taken damage by Spell that use ranged weapon
@@ -536,19 +598,20 @@ enum ProcFlagsEx
PROC_EX_DEFLECT = 0x0000200,
PROC_EX_ABSORB = 0x0000400,
PROC_EX_REFLECT = 0x0000800,
- PROC_EX_INTERRUPT = 0x0001000, // Melle hit result can be Interrupt (not used)
+ PROC_EX_INTERRUPT = 0x0001000, // Melee hit result can be Interrupt (not used)
PROC_EX_RESERVED1 = 0x0002000,
PROC_EX_RESERVED2 = 0x0004000,
PROC_EX_RESERVED3 = 0x0008000,
PROC_EX_EX_TRIGGER_ALWAYS = 0x0010000, // If set trigger always ( no matter another flags) used for drop charges
- PROC_EX_EX_ONE_TIME_TRIGGER = 0x0020000 // If set trigger always but only one time
+ PROC_EX_EX_ONE_TIME_TRIGGER = 0x0020000 // If set trigger always but only one time (not used)
};
struct SpellProcEventEntry
{
uint32 schoolMask; // if nonzero - bit mask for matching proc condition based on spell candidate's school: Fire=2, Mask=1<<(2-1)=2
uint32 spellFamilyName; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyNamer value
- uint64 spellFamilyMask; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyFlags (like auras 107 and 108 do)
+ flag96 spellFamilyMask; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyFlags (like auras 107 and 108 do)
+ uint32 spellFamilyMask2; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyFlags2 (like auras 107 and 108 do)
uint32 procFlags; // bitmask for matching proc event
uint32 procEx; // proc Extend info (see ProcFlagsEx)
float ppmRate; // for melee (ranged?) damage spells - proc rate per minute. if zero, falls back to flat chance from Spell.dbc
@@ -556,7 +619,15 @@ struct SpellProcEventEntry
uint32 cooldown; // hidden cooldown used for some spell proc events, applied to _triggered_spell_
};
+struct SpellBonusEntry
+{
+ float direct_damage;
+ float dot_damage;
+ float ap_bonus;
+};
+
typedef UNORDERED_MAP<uint32, SpellProcEventEntry> SpellProcEventMap;
+typedef UNORDERED_MAP<uint32, SpellBonusEntry> SpellBonusMap;
#define ELIXIR_BATTLE_MASK 0x1
#define ELIXIR_GUARDIAN_MASK 0x2
@@ -679,6 +750,7 @@ typedef std::map<uint32, SpellLearnSkillNode> SpellLearnSkillMap;
struct SpellLearnSpellNode
{
uint32 spell;
+ bool active; // show in spellbook or not
bool autoLearned;
};
@@ -686,6 +758,9 @@ typedef std::multimap<uint32, SpellLearnSpellNode> SpellLearnSpellMap;
typedef std::multimap<uint32, SkillLineAbilityEntry const*> SkillLineAbilityMap;
+typedef std::map<uint32, uint32> PetLevelupSpellSet;
+typedef std::map<uint32, PetLevelupSpellSet> PetLevelupSpellMap;
+
inline bool IsPrimaryProfessionSkill(uint32 skill)
{
SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(skill);
@@ -723,6 +798,11 @@ typedef std::vector<uint32> SpellCustomAttribute;
typedef std::map<int32, std::vector<int32> > SpellLinkedMap;
+inline bool IsProfessionOrRidingSkill(uint32 skill)
+{
+ return IsProfessionSkill(skill) || skill == SKILL_RIDING;
+}
+
class SpellMgr
{
// Constructors
@@ -733,15 +813,15 @@ class SpellMgr
// Accessors (const or static functions)
public:
// Spell affects
- uint64 GetSpellAffectMask(uint16 spellId, uint8 effectId) const
+ flag96 const*GetSpellAffect(uint16 spellId, uint8 effectId) const
{
SpellAffectMap::const_iterator itr = mSpellAffectMap.find((spellId<<8) + effectId);
if( itr != mSpellAffectMap.end( ) )
- return itr->second;
+ return &itr->second;
return 0;
}
- bool IsAffectedBySpell(SpellEntry const *spellInfo, uint32 spellId, uint8 effectId, uint64 familyFlags) const;
+ bool IsAffectedByMod(SpellEntry const *spellInfo, SpellModifier *mod) const;
SpellElixirMap const& GetSpellElixirMap() const { return mSpellElixirs; }
@@ -778,6 +858,23 @@ class SpellMgr
static bool IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra, bool active);
+ // Spell bonus data
+ SpellBonusEntry const* GetSpellBonusData(uint32 spellId) const
+ {
+ // Lookup data
+ SpellBonusMap::const_iterator itr = mSpellBonusMap.find(spellId);
+ if( itr != mSpellBonusMap.end( ) )
+ return &itr->second;
+ // Not found, try lookup for 1 spell rank if exist
+ if (uint32 rank_1 = GetFirstSpellInChain(spellId))
+ {
+ SpellBonusMap::const_iterator itr = mSpellBonusMap.find(rank_1);
+ if( itr != mSpellBonusMap.end( ) )
+ return &itr->second;
+ }
+ return NULL;
+ }
+
// Spell target coordinates
SpellTargetPosition const* GetSpellTargetPosition(uint32 spell_id) const
{
@@ -822,6 +919,14 @@ class SpellMgr
return 0;
}
+ uint32 GetNextSpellInChain(uint32 spell_id) const
+ {
+ if(SpellChainNode const* node = GetSpellChainNode(spell_id))
+ return node->next;
+
+ return 0;
+ }
+
SpellsRequiringSpellMap const& GetSpellsRequiringSpell() const { return mSpellsReqSpell; }
// Note: not use rank for compare to spell ranks: spell chains isn't linear order
@@ -901,10 +1006,14 @@ class SpellMgr
return false;
}
+ static bool IsProfessionOrRidingSpell(uint32 spellId);
static bool IsProfessionSpell(uint32 spellId);
static bool IsPrimaryProfessionSpell(uint32 spellId);
bool IsPrimaryProfessionFirstRankSpell(uint32 spellId) const;
+ bool IsSkillBonusSpell(uint32 spellId) const;
+
+
// Spell script targets
SpellScriptTarget::const_iterator GetBeginSpellScriptTarget(uint32 spell_id) const
{
@@ -944,11 +1053,6 @@ class SpellMgr
return 0;
else
return mSpellCustomAttr[spell_id];
- /*SpellCustomAttrMap::const_iterator itr = mSpellCustomAttrMap.find(spell_id);
- if(itr != mSpellCustomAttrMap.end())
- return itr->second;
- else
- return 0;*/
}
const std::vector<int32> *GetSpellLinked(int32 spell_id) const
@@ -960,6 +1064,15 @@ class SpellMgr
SpellEffectTargetTypes EffectTargetType[TOTAL_SPELL_EFFECTS];
SpellSelectTargetTypes SpellTargetType[TOTAL_SPELL_TARGETS];
+ PetLevelupSpellSet const* GetPetLevelupSpellList(uint32 petFamily) const
+ {
+ PetLevelupSpellMap::const_iterator itr = mPetLevelupSpellMap.find(petFamily);
+ if(itr != mPetLevelupSpellMap.end())
+ return &itr->second;
+ else
+ return NULL;
+ }
+
// Modifiers
public:
static SpellMgr& Instance();
@@ -973,12 +1086,14 @@ class SpellMgr
void LoadSpellAffects();
void LoadSpellElixirs();
void LoadSpellProcEvents();
+ void LoadSpellBonusess();
void LoadSpellTargetPositions();
void LoadSpellThreats();
void LoadSkillLineAbilityMap();
void LoadSpellPetAuras();
void LoadSpellCustomAttr();
void LoadSpellLinked();
+ void LoadPetLevelupSpellMap();
private:
SpellScriptTarget mSpellScriptTarget;
@@ -991,10 +1106,12 @@ class SpellMgr
SpellAffectMap mSpellAffectMap;
SpellElixirMap mSpellElixirs;
SpellProcEventMap mSpellProcEventMap;
+ SpellBonusMap mSpellBonusMap;
SkillLineAbilityMap mSkillLineAbilityMap;
SpellPetAuraMap mSpellPetAuraMap;
SpellCustomAttribute mSpellCustomAttr;
SpellLinkedMap mSpellLinkedMap;
+ PetLevelupSpellMap mPetLevelupSpellMap;
};
#define spellmgr SpellMgr::Instance()
diff --git a/src/game/StatSystem.cpp b/src/game/StatSystem.cpp
index bd5ab61eeff..8be79c3cfd8 100644
--- a/src/game/StatSystem.cpp
+++ b/src/game/StatSystem.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -51,24 +51,17 @@ bool Player::UpdateStats(Stats stat)
switch(stat)
{
case STAT_STRENGTH:
- UpdateAttackPowerAndDamage();
UpdateShieldBlockValue();
break;
case STAT_AGILITY:
UpdateArmor();
- UpdateAttackPowerAndDamage(true);
- if(getClass() == CLASS_ROGUE || getClass() == CLASS_HUNTER || getClass() == CLASS_DRUID && m_form==FORM_CAT)
- UpdateAttackPowerAndDamage();
-
UpdateAllCritPercentages();
UpdateDodgePercentage();
break;
-
case STAT_STAMINA: UpdateMaxHealth(); break;
case STAT_INTELLECT:
UpdateMaxPower(POWER_MANA);
UpdateAllSpellCritChances();
- UpdateAttackPowerAndDamage(true); //SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT, only intellect currently
UpdateArmor(); //SPELL_AURA_MOD_RESISTANCE_OF_INTELLECT_PERCENT, only armor currently
break;
@@ -78,11 +71,60 @@ bool Player::UpdateStats(Stats stat)
default:
break;
}
+
+ 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();
+
+ // Update ratings in exist SPELL_AURA_MOD_RATING_FROM_STAT and only depends from stat
+ uint32 mask = 0;
+ AuraList const& modRatingFromStat = GetAurasByType(SPELL_AURA_MOD_RATING_FROM_STAT);
+ for(AuraList::const_iterator i = modRatingFromStat.begin();i != modRatingFromStat.end(); ++i)
+ if (Stats((*i)->GetMiscBValue()) == stat)
+ mask |= (*i)->GetMiscValue();
+ if (mask)
+ {
+ for (uint32 rating = 0; rating < MAX_COMBAT_RATING; ++rating)
+ if (mask & (1 << rating))
+ ApplyRatingMod(CombatRating(rating), 0, true);
+ }
return true;
}
+void Player::ApplySpellDamageBonus(int32 amount, bool apply)
+{
+ m_baseSpellDamage+=apply?amount:-amount;
+ // For speed just update for client
+ ApplyModUInt32Value(PLAYER_FIELD_MOD_HEALING_DONE_POS, amount, apply);
+}
+
+void Player::ApplySpellHealingBonus(int32 amount, bool apply)
+{
+ m_baseSpellHealing+=apply?amount:-amount;
+ // For speed just update for client
+ for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++)
+ ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i, amount, apply);;
+}
+
void Player::UpdateSpellDamageAndHealingBonus()
{
// Magic damage modifiers implemented in Unit::SpellDamageBonus
@@ -155,7 +197,7 @@ void Player::UpdateArmor()
{
Modifier* mod = (*i)->GetModifier();
if(mod->m_miscvalue & SPELL_SCHOOL_MASK_NORMAL)
- value += int32(GetStat(Stats((*i)->GetMiscBValue())) * (*i)->GetModifierValue() / 100.0f);
+ value += int32(GetStat(Stats((*i)->GetMiscBValue())) * mod->m_amount / 100.0f);
}
value *= GetModifierValue(unitMod, TOTAL_PCT);
@@ -213,6 +255,12 @@ void Player::UpdateMaxPower(Powers power)
SetMaxPower(power, uint32(value));
}
+void Player::ApplyFeralAPBonus(int32 amount, bool apply)
+{
+ m_baseFeralAP+= apply ? amount:-amount;
+ UpdateAttackPowerAndDamage();
+}
+
void Player::UpdateAttackPowerAndDamage(bool ranged )
{
float val2 = 0.0f;
@@ -253,11 +301,12 @@ void Player::UpdateAttackPowerAndDamage(bool ranged )
{
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_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)*2.0f - 20.0f; break;
+ 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
@@ -286,12 +335,12 @@ void Player::UpdateAttackPowerAndDamage(bool ranged )
switch(m_form)
{
case FORM_CAT:
- val2 = getLevel()*(mLevelMult+2.0f) + GetStat(STAT_STRENGTH)*2.0f + GetStat(STAT_AGILITY) - 20.0f; break;
+ val2 = getLevel()*(mLevelMult+2.0f) + GetStat(STAT_STRENGTH)*2.0f + GetStat(STAT_AGILITY) - 20.0f + m_baseFeralAP; break;
case FORM_BEAR:
case FORM_DIREBEAR:
- val2 = getLevel()*(mLevelMult+3.0f) + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break;
+ val2 = getLevel()*(mLevelMult+3.0f) + GetStat(STAT_STRENGTH)*2.0f - 20.0f + m_baseFeralAP; break;
case FORM_MOONKIN:
- val2 = getLevel()*(mLevelMult+1.5f) + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break;
+ 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;
}
@@ -309,17 +358,26 @@ void Player::UpdateAttackPowerAndDamage(bool ranged )
float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE);
//add dynamic flat mods
- if( ranged && (getClassMask() & CLASSMASK_WAND_USERS)==0)
+ if( ranged )
+ {
+ if ((getClassMask() & CLASSMASK_WAND_USERS)==0)
+ {
+ AuraList const& mRAPbyStat = GetAurasByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT);
+ for(AuraList::const_iterator i = mRAPbyStat.begin();i != mRAPbyStat.end(); ++i)
+ attPowerMod += int32(GetStat(Stats((*i)->GetModifier()->m_miscvalue)) * (*i)->GetModifier()->m_amount / 100.0f);
+ }
+ }
+ else
{
- AuraList const& mRAPbyIntellect = GetAurasByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT);
- for(AuraList::const_iterator i = mRAPbyIntellect.begin();i != mRAPbyIntellect.end(); ++i)
- attPowerMod += int32(GetStat(Stats((*i)->GetModifier()->m_miscvalue)) * (*i)->GetModifierValue() / 100.0f);
+ AuraList const& mAPbyStat = GetAurasByType(SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT);
+ for(AuraList::const_iterator i = mAPbyStat.begin();i != mAPbyStat.end(); ++i)
+ attPowerMod += int32(GetStat(Stats((*i)->GetModifier()->m_miscvalue)) * (*i)->GetModifier()->m_amount / 100.0f);
}
float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f;
- SetUInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field
- SetUInt32Value(index_mod, (uint32)attPowerMod); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field
+ 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
//automatically update weapon damage after attack power modification
@@ -386,8 +444,15 @@ void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, fl
weapon_mindamage = lvl*0.85*att_speed;
weapon_maxdamage = lvl*1.25*att_speed;
}
- else if(!IsUseEquipedWeapon(attType==BASE_ATTACK)) //check if player not in form but still can't use weapon (broken/etc)
+ else if(!CanUseAttackType(attType)) //check if player not in form but still can't use (disarm case)
{
+ //cannot use ranged/off attack, set values to 0
+ if (attType != BASE_ATTACK)
+ {
+ min_damage=0;
+ max_damage=0;
+ return;
+ }
weapon_mindamage = BASE_MINDAMAGE;
weapon_maxdamage = BASE_MAXDAMAGE;
}
@@ -554,6 +619,24 @@ void Player::UpdateSpellCritChance(uint32 school)
SetFloatValue(PLAYER_SPELL_CRIT_PERCENTAGE1 + school, crit);
}
+void Player::UpdateMeleeHitChances()
+{
+ m_modMeleeHitChance = GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE);
+ m_modMeleeHitChance+= GetRatingBonusValue(CR_HIT_MELEE);
+}
+
+void Player::UpdateRangedHitChances()
+{
+ m_modRangedHitChance = GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE);
+ m_modRangedHitChance+= GetRatingBonusValue(CR_HIT_RANGED);
+}
+
+void Player::UpdateSpellHitChances()
+{
+ m_modSpellHitChance = GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ m_modSpellHitChance+= GetRatingBonusValue(CR_HIT_SPELL);
+}
+
void Player::UpdateAllSpellCritChances()
{
for (int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++)
@@ -574,10 +657,10 @@ void Player::UpdateExpertise(WeaponAttackType attack)
{
// item neutral spell
if((*itr)->GetSpellProto()->EquippedItemClass == -1)
- expertise += (*itr)->GetModifierValue();
+ expertise += (*itr)->GetModifier()->m_amount;
// item dependent spell
else if(weapon && weapon->IsFitToSpellRequirements((*itr)->GetSpellProto()))
- expertise += (*itr)->GetModifierValue();
+ expertise += (*itr)->GetModifier()->m_amount;
}
if(expertise < 0)
@@ -591,6 +674,12 @@ void Player::UpdateExpertise(WeaponAttackType attack)
}
}
+void Player::ApplyManaRegenBonus(int32 amount, bool apply)
+{
+ m_baseManaRegen+= apply ? amount : -amount;
+ UpdateManaRegen();
+}
+
void Player::UpdateManaRegen()
{
float Intellect = GetStat(STAT_INTELLECT);
@@ -600,14 +689,14 @@ void Player::UpdateManaRegen()
power_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) / 5.0f;
+ float power_regen_mp5 = (GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, POWER_MANA) + m_baseManaRegen) / 5.0f;
// Get bonus from SPELL_AURA_MOD_MANA_REGEN_FROM_STAT aura
AuraList const& regenAura = GetAurasByType(SPELL_AURA_MOD_MANA_REGEN_FROM_STAT);
for(AuraList::const_iterator i = regenAura.begin();i != regenAura.end(); ++i)
{
Modifier* mod = (*i)->GetModifier();
- power_regen_mp5 += GetStat(Stats(mod->m_miscvalue)) * (*i)->GetModifierValue() / 500.0f;
+ power_regen_mp5 += GetStat(Stats(mod->m_miscvalue)) * mod->m_amount / 500.0f;
}
// Bonus from some dummy auras
@@ -624,9 +713,9 @@ void Player::UpdateManaRegen()
int32 modManaRegenInterrupt = GetTotalAuraModifier(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT);
if (modManaRegenInterrupt > 100)
modManaRegenInterrupt = 100;
- SetStatFloatValue(PLAYER_FIELD_MOD_MANA_REGEN_INTERRUPT, power_regen_mp5 + power_regen * modManaRegenInterrupt / 100.0f);
+ SetStatFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER, power_regen_mp5 + power_regen * modManaRegenInterrupt / 100.0f);
- SetStatFloatValue(PLAYER_FIELD_MOD_MANA_REGEN, power_regen_mp5 + power_regen);
+ SetStatFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER, power_regen_mp5 + power_regen);
}
void Player::_ApplyAllStatBonuses()
@@ -712,6 +801,27 @@ void Creature::UpdateMaxPower(Powers power)
void Creature::UpdateAttackPowerAndDamage(bool ranged)
{
+ 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;
+ }
+
+ 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;
+
+ 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
+
//automatically update weapon damage after attack power modification
if(ranged)
UpdateDamagePhysical(RANGED_ATTACK);
@@ -755,7 +865,7 @@ void Creature::UpdateDamagePhysical(WeaponAttackType attType)
float total_value = GetModifierValue(unitMod, TOTAL_VALUE);
float total_pct = GetModifierValue(unitMod, TOTAL_PCT);
- if(attType == BASE_ATTACK && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED))
+ if(!CanUseAttackType(attType))
{
weapon_mindamage = 0;
weapon_maxdamage = 0;
@@ -923,7 +1033,7 @@ void Pet::UpdateAttackPowerAndDamage(bool ranged)
if(getPetType() == HUNTER_PET) //hunter pets benefit from owner's attack power
{
bonusAP = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.22f;
- SetBonusDamage( int32(owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.125f));
+ SetBonusDamage( int32(owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.1287f));
}
//demons benefit from warlocks shadow or fire damage
else if(getPetType() == SUMMON_PET && owner->getClass() == CLASS_WARLOCK)
@@ -954,9 +1064,9 @@ void Pet::UpdateAttackPowerAndDamage(bool ranged)
float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f;
//UNIT_FIELD_(RANGED)_ATTACK_POWER field
- SetUInt32Value(UNIT_FIELD_ATTACK_POWER, (uint32)base_attPower);
+ SetInt32Value(UNIT_FIELD_ATTACK_POWER, (int32)base_attPower);
//UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field
- SetUInt32Value(UNIT_FIELD_ATTACK_POWER_MODS, (uint32)attPowerMod);
+ SetInt32Value(UNIT_FIELD_ATTACK_POWER_MODS, (int32)attPowerMod);
//UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field
SetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER, attPowerMultiplier);
diff --git a/src/game/TargetedMovementGenerator.cpp b/src/game/TargetedMovementGenerator.cpp
index 88558861257..d39c2c68071 100644
--- a/src/game/TargetedMovementGenerator.cpp
+++ b/src/game/TargetedMovementGenerator.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/TargetedMovementGenerator.h b/src/game/TargetedMovementGenerator.h
index 75e60728ea3..e6579c0b1de 100644
--- a/src/game/TargetedMovementGenerator.h
+++ b/src/game/TargetedMovementGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/TaxiHandler.cpp b/src/game/TaxiHandler.cpp
index 640618eaebb..743f09f94fc 100644
--- a/src/game/TaxiHandler.cpp
+++ b/src/game/TaxiHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -56,7 +56,7 @@ void WorldSession::SendTaxiStatus( uint64 guid )
return;
}
- uint32 curloc = objmgr.GetNearestTaxiNode(unit->GetPositionX(),unit->GetPositionY(),unit->GetPositionZ(),unit->GetMapId());
+ uint32 curloc = objmgr.GetNearestTaxiNode(unit->GetPositionX(),unit->GetPositionY(),unit->GetPositionZ(),unit->GetMapId(),GetPlayer( )->GetTeam());
// not found nearest
if(curloc == 0)
@@ -71,7 +71,7 @@ void WorldSession::SendTaxiStatus( uint64 guid )
sLog.outDebug( "WORLD: Sent SMSG_TAXINODE_STATUS" );
}
-void WorldSession::HandleTaxiQueryAvailableNodesOpcode( WorldPacket & recv_data )
+void WorldSession::HandleTaxiQueryAvailableNodes( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE(recv_data,8);
@@ -103,7 +103,7 @@ void WorldSession::HandleTaxiQueryAvailableNodesOpcode( WorldPacket & recv_data
void WorldSession::SendTaxiMenu( Creature* unit )
{
// find current node
- uint32 curloc = objmgr.GetNearestTaxiNode(unit->GetPositionX(),unit->GetPositionY(),unit->GetPositionZ(),unit->GetMapId());
+ uint32 curloc = objmgr.GetNearestTaxiNode(unit->GetPositionX(),unit->GetPositionY(),unit->GetPositionZ(),unit->GetMapId(),GetPlayer( )->GetTeam());
if ( curloc == 0 )
return;
@@ -136,7 +136,7 @@ void WorldSession::SendDoFlight( uint16 MountId, uint32 path, uint32 pathNode )
bool WorldSession::SendLearnNewTaxiNode( Creature* unit )
{
// find current node
- uint32 curloc = objmgr.GetNearestTaxiNode(unit->GetPositionX(),unit->GetPositionY(),unit->GetPositionZ(),unit->GetMapId());
+ uint32 curloc = objmgr.GetNearestTaxiNode(unit->GetPositionX(),unit->GetPositionY(),unit->GetPositionZ(),unit->GetMapId(),GetPlayer( )->GetTeam());
if ( curloc == 0 )
return true; // `true` send to avoid WorldSession::SendTaxiMenu call with one more curlock seartch with same false result.
diff --git a/src/game/TemporarySummon.cpp b/src/game/TemporarySummon.cpp
index 553f7644b64..788fe4d2b7d 100644
--- a/src/game/TemporarySummon.cpp
+++ b/src/game/TemporarySummon.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/TemporarySummon.h b/src/game/TemporarySummon.h
index 7f20ee9c5a9..c3441704438 100644
--- a/src/game/TemporarySummon.h
+++ b/src/game/TemporarySummon.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/ThreatManager.cpp b/src/game/ThreatManager.cpp
index 3b4491b943e..8807dff64f8 100644
--- a/src/game/ThreatManager.cpp
+++ b/src/game/ThreatManager.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -267,26 +267,36 @@ HostilReference* ThreatContainer::selectNextVictim(Creature* pAttacker, HostilRe
{
HostilReference* currentRef = NULL;
bool found = false;
+ bool noPriorityTargetFound = false;
std::list<HostilReference*>::iterator lastRef = iThreatList.end();
lastRef--;
- for(std::list<HostilReference*>::iterator iter = iThreatList.begin(); iter != iThreatList.end() && !found; ++iter)
+ for(std::list<HostilReference*>::iterator iter = iThreatList.begin(); iter != iThreatList.end() && !found;)
{
currentRef = (*iter);
Unit* target = currentRef->getTarget();
assert(target); // if the ref has status online the target must be there !
- // some units are preferred in comparison to others
- if(iter != lastRef && (target->IsImmunedToDamage(pAttacker->GetMeleeDamageSchoolMask(), false) ||
- target->hasUnitState(UNIT_STAT_CONFUSED)
- ) )
+ // some units are prefered in comparison to others
+ if(!noPriorityTargetFound && (target->IsImmunedToDamage(pAttacker->GetMeleeDamageSchoolMask()) || target->hasNegativeAuraWithInterruptFlag(AURA_INTERRUPT_FLAG_DAMAGE)) )
{
- // current victim is a second choice target, so don't compare threat with it below
- if(currentRef == pCurrentVictim)
- pCurrentVictim = NULL;
- continue;
+ if(iter != lastRef)
+ {
+ // current victim is a second choice target, so don't compare threat with it below
+ if(currentRef == pCurrentVictim)
+ pCurrentVictim = NULL;
+ ++iter;
+ continue;
+ }
+ else
+ {
+ // if we reached to this point, everyone in the threatlist is a second choice target. In such a situation the target with the highest threat should be attacked.
+ noPriorityTargetFound = true;
+ iter = iThreatList.begin();
+ continue;
+ }
}
if(!pAttacker->IsOutOfThreatArea(target)) // skip non attackable currently targets
@@ -314,6 +324,7 @@ HostilReference* ThreatContainer::selectNextVictim(Creature* pAttacker, HostilRe
break;
}
}
+ ++iter;
}
if(!found)
currentRef = NULL;
diff --git a/src/game/ThreatManager.h b/src/game/ThreatManager.h
index d4a3910e91e..2d81f411e78 100644
--- a/src/game/ThreatManager.h
+++ b/src/game/ThreatManager.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -208,10 +208,10 @@ class TRINITY_DLL_SPEC ThreatManager
// methods to access the lists from the outside to do sume dirty manipulation (scriping and such)
// I hope they are used as little as possible.
- inline std::list<HostilReference*>& getThreatList() { return iThreatContainer.getThreatList(); }
- inline std::list<HostilReference*>& getOfflieThreatList() { return iThreatOfflineContainer.getThreatList(); }
- inline ThreatContainer& getOnlineContainer() { return iThreatContainer; }
- inline ThreatContainer& getOfflineContainer() { return iThreatOfflineContainer; }
+ std::list<HostilReference*>& getThreatList() { return iThreatContainer.getThreatList(); }
+ std::list<HostilReference*>& getOfflieThreatList() { return iThreatOfflineContainer.getThreatList(); }
+ ThreatContainer& getOnlineContainer() { return iThreatContainer; }
+ ThreatContainer& getOfflineContainer() { return iThreatOfflineContainer; }
};
//=================================================
diff --git a/src/game/TicketHandler.cpp b/src/game/TicketHandler.cpp
index 5d6b1e095fa..8d6ed30687e 100644
--- a/src/game/TicketHandler.cpp
+++ b/src/game/TicketHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS
+ * Copyright (C) 2005-2009 MaNGOS
*
- * Copyright (C) 2008 Trinity
+ * Copyright (C) 2008-2009 Trinity
*
* 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
diff --git a/src/game/TicketMgr.cpp b/src/game/TicketMgr.cpp
index 09d975ccf21..a622a41aedc 100644
--- a/src/game/TicketMgr.cpp
+++ b/src/game/TicketMgr.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS
+ * Copyright (C) 2005-2009 MaNGOS
*
- * Copyright (C) 2008 Trinity
+ * Copyright (C) 2008-2009 Trinity
*
* 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
diff --git a/src/game/TicketMgr.h b/src/game/TicketMgr.h
index f8a0632c0ca..25d62462dc2 100644
--- a/src/game/TicketMgr.h
+++ b/src/game/TicketMgr.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS
+ * Copyright (C) 2005-2009 MaNGOS
*
- * Copyright (C) 2008 Trinity
+ * Copyright (C) 2008-2009 Trinity
*
* 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
diff --git a/src/game/Tools.cpp b/src/game/Tools.cpp
index 7abc016df48..f8663a4b4e4 100644
--- a/src/game/Tools.cpp
+++ b/src/game/Tools.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/Tools.h b/src/game/Tools.h
index 03b48a7e9a3..887fe03045a 100644
--- a/src/game/Tools.h
+++ b/src/game/Tools.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/Totem.cpp b/src/game/Totem.cpp
index 2ac26f823d6..0178ed07fdf 100644
--- a/src/game/Totem.cpp
+++ b/src/game/Totem.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -178,18 +178,18 @@ void Totem::SetTypeBySummonSpell(SpellEntry const * spellProto)
m_type = TOTEM_STATUE; //Jewelery statue
}
-bool Totem::IsImmunedToSpell(SpellEntry const* spellInfo, bool useCharges)
+bool Totem::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const
{
-/* for (int i=0;i<3;i++)
+ // TODO: possibly all negative auras immuned?
+ switch(spellInfo->EffectApplyAuraName[index])
{
- switch(spellInfo->EffectApplyAuraName[i])
- {
- case SPELL_AURA_PERIODIC_DAMAGE:
- case SPELL_AURA_PERIODIC_LEECH:
- return true;
- default:
- continue;
- }
- }*/
- return Creature::IsImmunedToSpell(spellInfo, useCharges);
+ case SPELL_AURA_PERIODIC_DAMAGE:
+ case SPELL_AURA_PERIODIC_LEECH:
+ case SPELL_AURA_MOD_FEAR:
+ case SPELL_AURA_TRANSFORM:
+ return true;
+ default:
+ break;
+ }
+ return Creature::IsImmunedToSpellEffect(spellInfo, index);
}
diff --git a/src/game/Totem.h b/src/game/Totem.h
index 43ae4f4912c..572cfa6d315 100644
--- a/src/game/Totem.h
+++ b/src/game/Totem.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -57,7 +57,7 @@ class Totem : public Creature
void UpdateAttackPowerAndDamage(bool /*ranged*/ ) {}
void UpdateDamagePhysical(WeaponAttackType /*attType*/) {}
- bool IsImmunedToSpell(SpellEntry const* spellInfo, bool useCharges = false);
+ bool IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const;
protected:
TotemType m_type;
diff --git a/src/game/TotemAI.cpp b/src/game/TotemAI.cpp
index 4d7b45eba8e..81113a3a9f8 100644
--- a/src/game/TotemAI.cpp
+++ b/src/game/TotemAI.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -82,21 +82,10 @@ TotemAI::UpdateAI(const uint32 /*diff*/)
!victim->isTargetableForAttack() || !i_totem.IsWithinDistInMap(victim, max_range) ||
i_totem.IsFriendlyTo(victim) || !victim->isVisibleForOrDetect(&i_totem,false) )
{
- CellPair p(Trinity::ComputeCellPair(i_totem.GetPositionX(),i_totem.GetPositionY()));
- Cell cell(p);
- cell.data.Part.reserved = ALL_DISTRICT;
-
victim = NULL;
-
Trinity::NearestAttackableUnitInObjectRangeCheck u_check(&i_totem, &i_totem, max_range);
- Trinity::UnitLastSearcher<Trinity::NearestAttackableUnitInObjectRangeCheck> checker(victim, u_check);
-
- TypeContainerVisitor<Trinity::UnitLastSearcher<Trinity::NearestAttackableUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker);
- TypeContainerVisitor<Trinity::UnitLastSearcher<Trinity::NearestAttackableUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker);
-
- CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, grid_object_checker, *MapManager::Instance().GetMap(i_totem.GetMapId(), &i_totem));
- cell_lock->Visit(cell_lock, world_object_checker, *MapManager::Instance().GetMap(i_totem.GetMapId(), &i_totem));
+ Trinity::UnitLastSearcher<Trinity::NearestAttackableUnitInObjectRangeCheck> checker(&i_totem, victim, u_check);
+ i_totem.VisitNearbyObject(max_range, checker);
}
// If have target
diff --git a/src/game/TotemAI.h b/src/game/TotemAI.h
index 8ce40e60c81..64675cd11e3 100644
--- a/src/game/TotemAI.h
+++ b/src/game/TotemAI.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/TradeHandler.cpp b/src/game/TradeHandler.cpp
index dc3bd020ccf..f444866e8aa 100644
--- a/src/game/TradeHandler.cpp
+++ b/src/game/TradeHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/Transports.cpp b/src/game/Transports.cpp
index b2ed69fe251..f1d1ff412bf 100644
--- a/src/game/Transports.cpp
+++ b/src/game/Transports.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -139,7 +139,7 @@ void MapManager::LoadTransports()
Transport::Transport() : GameObject()
{
// 2.3.2 - 0x5A
- m_updateFlag = (UPDATEFLAG_TRANSPORT | UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION);
+ m_updateFlag = (UPDATEFLAG_TRANSPORT | UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION);
}
bool Transport::Create(uint32 guidlow, uint32 mapid, float x, float y, float z, float ang, uint32 animprogress, uint32 dynflags)
@@ -147,6 +147,7 @@ bool Transport::Create(uint32 guidlow, uint32 mapid, float x, float y, float z,
Relocate(x,y,z,ang);
SetMapId(mapid);
+ // instance id and phaseMask isn't set to values different from std.
if(!IsPositionValid())
{
@@ -170,9 +171,10 @@ bool Transport::Create(uint32 guidlow, uint32 mapid, float x, float y, float z,
SetFloatValue(OBJECT_FIELD_SCALE_X, goinfo->size);
SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction);
- SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags);
-
- SetUInt32Value(OBJECT_FIELD_ENTRY, goinfo->id);
+ //SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags);
+ SetUInt32Value(GAMEOBJECT_FLAGS, MAKE_PAIR32(0x28, 0x64));
+ SetUInt32Value(GAMEOBJECT_LEVEL, m_period);
+ SetEntry(goinfo->id);
SetUInt32Value(GAMEOBJECT_DISPLAYID, goinfo->displayId);
@@ -181,7 +183,7 @@ bool Transport::Create(uint32 guidlow, uint32 mapid, float x, float y, float z,
SetGoAnimProgress(animprogress);
if(dynflags)
- SetUInt32Value(GAMEOBJECT_DYN_FLAGS, dynflags);
+ SetUInt32Value(GAMEOBJECT_DYNAMIC, MAKE_PAIR32(0, dynflags));
return true;
}
@@ -479,11 +481,8 @@ bool Transport::AddPassenger(Player* passenger)
bool Transport::RemovePassenger(Player* passenger)
{
- if (m_passengers.find(passenger) != m_passengers.end())
- {
- sLog.outDetail("Player %s removed from transport %s.", passenger->GetName(), this->m_name.c_str());
- m_passengers.erase(passenger);
- }
+ if (m_passengers.erase(passenger))
+ sLog.outDetail("Player %s removed from transport %s.", passenger->GetName(), m_name.c_str());
return true;
}
diff --git a/src/game/Transports.h b/src/game/Transports.h
index e49383ad1de..0cb6a6e7503 100644
--- a/src/game/Transports.h
+++ b/src/game/Transports.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -38,16 +38,16 @@ class TransportPath
uint32 delay;
};
- inline void SetLength(const unsigned int sz)
+ void SetLength(const unsigned int sz)
{
i_nodes.resize( sz );
}
- inline unsigned int Size(void) const { return i_nodes.size(); }
- inline bool Empty(void) const { return i_nodes.empty(); }
- inline void Resize(unsigned int sz) { i_nodes.resize(sz); }
- inline void Clear(void) { i_nodes.clear(); }
- inline PathNode* GetNodes(void) { return static_cast<PathNode *>(&i_nodes[0]); }
+ unsigned int Size(void) const { return i_nodes.size(); }
+ bool Empty(void) const { return i_nodes.empty(); }
+ void Resize(unsigned int sz) { i_nodes.resize(sz); }
+ void Clear(void) { i_nodes.clear(); }
+ PathNode* GetNodes(void) { return static_cast<PathNode *>(&i_nodes[0]); }
PathNode& operator[](const unsigned int idx) { return i_nodes[idx]; }
const PathNode& operator()(const unsigned int idx) const { return i_nodes[idx]; }
diff --git a/src/game/Traveller.h b/src/game/Traveller.h
index 64b9d1c310d..6e7757d9bbf 100644
--- a/src/game/Traveller.h
+++ b/src/game/Traveller.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -47,10 +47,10 @@ struct TRINITY_DLL_DECL Traveller
operator T&(void) { return i_traveller; }
operator const T&(void) { return i_traveller; }
- inline float GetPositionX() const { return i_traveller.GetPositionX(); }
- inline float GetPositionY() const { return i_traveller.GetPositionY(); }
- inline float GetPositionZ() const { return i_traveller.GetPositionZ(); }
- inline T& GetTraveller(void) { return i_traveller; }
+ float GetPositionX() const { return i_traveller.GetPositionX(); }
+ float GetPositionY() const { return i_traveller.GetPositionY(); }
+ float GetPositionZ() const { return i_traveller.GetPositionZ(); }
+ T& GetTraveller(void) { return i_traveller; }
float Speed(void) { assert(false); return 0.0f; }
void Relocation(float x, float y, float z, float orientation) {}
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 234922f040e..6996df9ed97 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -60,92 +60,17 @@ float baseMoveSpeed[MAX_MOVE_TYPE] =
3.141594f, // MOVE_TURN_RATE
7.0f, // MOVE_FLIGHT
4.5f, // MOVE_FLIGHT_BACK
+ 3.14f // MOVE_PITCH_RATE
};
-void InitTriggerAuraData();
-
-// auraTypes contains attacker auras capable of proc'ing cast auras
-static Unit::AuraTypeSet GenerateAttakerProcCastAuraTypes()
-{
- static Unit::AuraTypeSet auraTypes;
- auraTypes.insert(SPELL_AURA_DUMMY);
- auraTypes.insert(SPELL_AURA_PROC_TRIGGER_SPELL);
- auraTypes.insert(SPELL_AURA_MOD_HASTE);
- auraTypes.insert(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
- return auraTypes;
-}
-
-// auraTypes contains victim auras capable of proc'ing cast auras
-static Unit::AuraTypeSet GenerateVictimProcCastAuraTypes()
-{
- static Unit::AuraTypeSet auraTypes;
- auraTypes.insert(SPELL_AURA_DUMMY);
- auraTypes.insert(SPELL_AURA_PRAYER_OF_MENDING);
- auraTypes.insert(SPELL_AURA_PROC_TRIGGER_SPELL);
- return auraTypes;
-}
-
-// auraTypes contains auras capable of proc effect/damage (but not cast) for attacker
-static Unit::AuraTypeSet GenerateAttakerProcEffectAuraTypes()
-{
- static Unit::AuraTypeSet auraTypes;
- auraTypes.insert(SPELL_AURA_MOD_DAMAGE_DONE);
- auraTypes.insert(SPELL_AURA_PROC_TRIGGER_DAMAGE);
- auraTypes.insert(SPELL_AURA_MOD_CASTING_SPEED);
- auraTypes.insert(SPELL_AURA_MOD_RATING);
- return auraTypes;
-}
-
-// auraTypes contains auras capable of proc effect/damage (but not cast) for victim
-static Unit::AuraTypeSet GenerateVictimProcEffectAuraTypes()
-{
- static Unit::AuraTypeSet auraTypes;
- auraTypes.insert(SPELL_AURA_MOD_RESISTANCE);
- auraTypes.insert(SPELL_AURA_PROC_TRIGGER_DAMAGE);
- auraTypes.insert(SPELL_AURA_MOD_PARRY_PERCENT);
- auraTypes.insert(SPELL_AURA_MOD_BLOCK_PERCENT);
- auraTypes.insert(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN);
- return auraTypes;
-}
-
-static Unit::AuraTypeSet attackerProcCastAuraTypes = GenerateAttakerProcCastAuraTypes();
-static Unit::AuraTypeSet attackerProcEffectAuraTypes = GenerateAttakerProcEffectAuraTypes();
-
-static Unit::AuraTypeSet victimProcCastAuraTypes = GenerateVictimProcCastAuraTypes();
-static Unit::AuraTypeSet victimProcEffectAuraTypes = GenerateVictimProcEffectAuraTypes();
-
-// auraTypes contains auras capable of proc'ing for attacker and victim
-static Unit::AuraTypeSet GenerateProcAuraTypes()
-{
- InitTriggerAuraData();
-
- Unit::AuraTypeSet auraTypes;
- auraTypes.insert(attackerProcCastAuraTypes.begin(),attackerProcCastAuraTypes.end());
- auraTypes.insert(attackerProcEffectAuraTypes.begin(),attackerProcEffectAuraTypes.end());
- auraTypes.insert(victimProcCastAuraTypes.begin(),victimProcCastAuraTypes.end());
- auraTypes.insert(victimProcEffectAuraTypes.begin(),victimProcEffectAuraTypes.end());
- return auraTypes;
-}
-
-static Unit::AuraTypeSet procAuraTypes = GenerateProcAuraTypes();
-
-bool IsPassiveStackableSpell( uint32 spellId )
-{
- if(!IsPassiveSpell(spellId))
- return false;
-
- SpellEntry const* spellProto = sSpellStore.LookupEntry(spellId);
- if(!spellProto)
- return false;
-
- for(int j = 0; j < 3; ++j)
- {
- if(std::find(procAuraTypes.begin(),procAuraTypes.end(),spellProto->EffectApplyAuraName[j])!=procAuraTypes.end())
- return false;
- }
-
- return true;
-}
+// Used for prepare can/can`t triggr aura
+static bool InitTriggerAuraData();
+// Define can trigger auras
+static bool isTriggerAura[TOTAL_AURAS];
+// Define can`t trigger auras (need for disable second trigger)
+static bool isNonTriggerAura[TOTAL_AURAS];
+// Prepare lists
+static bool procPrepared = InitTriggerAuraData();
Unit::Unit()
: WorldObject(), i_motionMaster(this), m_ThreatManager(this), m_HostilRefManager(this)
@@ -154,7 +79,7 @@ Unit::Unit()
m_objectType |= TYPEMASK_UNIT;
m_objectTypeId = TYPEID_UNIT;
// 2.3.2 - 0x70
- m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_LIVING | UPDATEFLAG_HASPOSITION);
+ m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_LIVING | UPDATEFLAG_HAS_POSITION);
m_attackTimer[BASE_ATTACK] = 0;
m_attackTimer[OFF_ATTACK] = 0;
@@ -169,6 +94,7 @@ Unit::Unit()
m_state = 0;
m_form = FORM_NONE;
m_deathState = ALIVE;
+ m_auraUpdateMask = 0;
for (uint32 i = 0; i < CURRENT_MAX_SPELL; i++)
m_currentSpells[i] = NULL;
@@ -183,7 +109,6 @@ Unit::Unit()
//m_AurasCheck = 2000;
//m_removeAuraTimer = 4;
//tmpAura = NULL;
- waterbreath = false;
m_Visibility = VISIBILITY_ON;
@@ -283,6 +208,18 @@ void Unit::Update( uint32 p_time )
_UpdateAura();
}else
m_AurasCheck -= p_time;*/
+ const uint64& auramask = GetAuraUpdateMask();
+ if (auramask)
+ {
+ for(uint32 i = 0; i < MAX_AURAS; ++i)
+ {
+ if(auramask & (uint64(1) << i))
+ {
+ SendAuraUpdate(i);
+ }
+ }
+ ResetAuraUpdateMask();
+ }
// WARNING! Order of execution here is important, do not change.
// Spells must be processed with event system BEFORE they go to _UpdateSpells.
@@ -322,6 +259,7 @@ void Unit::Update( uint32 p_time )
ModifyAuraState(AURA_STATE_HEALTHLESS_20_PERCENT, GetHealth() < GetMaxHealth()*0.20f);
ModifyAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, GetHealth() < GetMaxHealth()*0.35f);
+ ModifyAuraState(AURA_STATE_HEALTH_ABOVE_75_PERCENT, GetHealth() > GetMaxHealth()*0.75f);
i_motionMaster.UpdateMotion(p_time);
}
@@ -385,6 +323,11 @@ void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 ty
case 1: // stop packet
SendMessageToSet( &data, true );
return;
+ case 2: // not used currently
+ data << float(0); // orientation
+ data << float(0);
+ data << float(0);
+ break;
case 3: // not used currently
data << uint64(0); // probably target guid
break;
@@ -738,6 +681,167 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
{
DEBUG_LOG("DealDamage: victim just died");
Kill(pVictim, durabilityLoss);
+
+ /*// find player: owner of controlled `this` or `this` itself maybe
+ Player *player = GetCharmerOrOwnerPlayerOrPlayerItself();
+
+ if(pVictim->GetTypeId() == TYPEID_UNIT && ((Creature*)pVictim)->GetLootRecipient())
+ player = ((Creature*)pVictim)->GetLootRecipient();
+ // Reward player, his pets, and group/raid members
+ // call kill spell proc event (before real die and combat stop to triggering auras removed at death/combat stop)
+ if(player && player!=pVictim)
+ {
+ player->RewardPlayerAndGroupAtKill(pVictim);
+ player->ProcDamageAndSpell(pVictim, PROC_FLAG_KILL, PROC_FLAG_KILLED, PROC_EX_NONE, 0);
+ }
+
+ DEBUG_LOG("DealDamageAttackStop");
+
+ // stop combat
+ pVictim->CombatStop();
+ pVictim->getHostilRefManager().deleteReferences();
+
+ bool damageFromSpiritOfRedemtionTalent = spellProto && spellProto->Id == 27795;
+
+ // if talent known but not triggered (check priest class for speedup check)
+ Aura* spiritOfRedemtionTalentReady = NULL;
+ if( !damageFromSpiritOfRedemtionTalent && // not called from SPELL_AURA_SPIRIT_OF_REDEMPTION
+ pVictim->GetTypeId()==TYPEID_PLAYER && pVictim->getClass()==CLASS_PRIEST )
+ {
+ AuraList const& vDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY);
+ for(AuraList::const_iterator itr = vDummyAuras.begin(); itr != vDummyAuras.end(); ++itr)
+ {
+ if((*itr)->GetSpellProto()->SpellIconID==1654)
+ {
+ spiritOfRedemtionTalentReady = *itr;
+ break;
+ }
+ }
+ }
+
+ DEBUG_LOG("SET JUST_DIED");
+ if(!spiritOfRedemtionTalentReady)
+ pVictim->setDeathState(JUST_DIED);
+
+ DEBUG_LOG("DealDamageHealth1");
+
+ if(spiritOfRedemtionTalentReady)
+ {
+ // save value before aura remove
+ uint32 ressSpellId = pVictim->GetUInt32Value(PLAYER_SELF_RES_SPELL);
+ if(!ressSpellId)
+ ressSpellId = ((Player*)pVictim)->GetResurrectionSpellId();
+
+ //Remove all expected to remove at death auras (most important negative case like DoT or periodic triggers)
+ pVictim->RemoveAllAurasOnDeath();
+
+ // restore for use at real death
+ pVictim->SetUInt32Value(PLAYER_SELF_RES_SPELL,ressSpellId);
+
+ // FORM_SPIRITOFREDEMPTION and related auras
+ pVictim->CastSpell(pVictim,27827,true,NULL,spiritOfRedemtionTalentReady);
+ }
+ else
+ pVictim->SetHealth(0);
+
+ // remember victim PvP death for corpse type and corpse reclaim delay
+ // at original death (not at SpiritOfRedemtionTalent timeout)
+ if( pVictim->GetTypeId()==TYPEID_PLAYER && !damageFromSpiritOfRedemtionTalent )
+ ((Player*)pVictim)->SetPvPDeath(player!=NULL);
+
+ // Call KilledUnit for creatures
+ if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->AI())
+ ((Creature*)this)->AI()->KilledUnit(pVictim);
+
+ // achievement stuff
+ if ( pVictim->GetTypeId() == TYPEID_PLAYER)
+ {
+ if(GetTypeId() == TYPEID_UNIT)
+ ((Player*)pVictim)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE, GetEntry());
+ else if(GetTypeId() == TYPEID_PLAYER)
+ ((Player*)pVictim)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER, 1);
+ }
+
+ // 10% durability loss on death
+ // clean InHateListOf
+ if (pVictim->GetTypeId() == TYPEID_PLAYER)
+ {
+ // only if not player and not controlled by player pet. And not at BG
+ if (durabilityLoss && !player && !((Player*)pVictim)->InBattleGround())
+ {
+ DEBUG_LOG("We are dead, loosing 10 percents durability");
+ ((Player*)pVictim)->DurabilityLossAll(0.10f,false);
+ // durability lost message
+ WorldPacket data(SMSG_DURABILITY_DAMAGE_DEATH, 0);
+ ((Player*)pVictim)->GetSession()->SendPacket(&data);
+ }
+ }
+ else // creature died
+ {
+ DEBUG_LOG("DealDamageNotPlayer");
+ Creature *cVictim = (Creature*)pVictim;
+
+ if(!cVictim->isPet())
+ {
+ cVictim->DeleteThreatList();
+ cVictim->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ }
+ // Call creature just died function
+ if (cVictim->AI())
+ cVictim->AI()->JustDied(this);
+
+ // Dungeon specific stuff, only applies to players killing creatures
+ if(cVictim->GetInstanceId())
+ {
+ Map *m = cVictim->GetMap();
+ Player *creditedPlayer = GetCharmerOrOwnerPlayerOrPlayerItself();
+ // TODO: do instance binding anyway if the charmer/owner is offline
+
+ if(m->IsDungeon() && creditedPlayer)
+ {
+ if(m->IsRaid() || m->IsHeroic())
+ {
+ if(cVictim->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_INSTANCE_BIND)
+ ((InstanceMap *)m)->PermBindAllPlayers(creditedPlayer);
+ }
+ else
+ {
+ // the reset time is set but not added to the scheduler
+ // until the players leave the instance
+ time_t resettime = cVictim->GetRespawnTimeEx() + 2 * HOUR;
+ if(InstanceSave *save = sInstanceSaveManager.GetInstanceSave(cVictim->GetInstanceId()))
+ if(save->GetResetTime() < resettime) save->SetResetTime(resettime);
+ }
+ }
+ }
+ }
+
+ // last damage from non duel opponent or opponent controlled creature
+ if(duel_hasEnded)
+ {
+ assert(pVictim->GetTypeId()==TYPEID_PLAYER);
+ Player *he = (Player*)pVictim;
+
+ assert(he->duel);
+
+ he->duel->opponent->CombatStopWithPets(true);
+ he->CombatStopWithPets(true);
+
+ he->DuelComplete(DUEL_INTERUPTED);
+ }
+
+ // battleground things (do this at the end, so the death state flag will be properly set to handle in the bg->handlekill)
+ if(pVictim->GetTypeId() == TYPEID_PLAYER && ((Player*)pVictim)->InBattleGround())
+ {
+ Player *killed = ((Player*)pVictim);
+ if(BattleGround *bg = killed->GetBattleGround())
+ if(player)
+ bg->HandleKillPlayer(killed, player);
+ //later we can add support for creature->player kills here i'm
+ //not sure, but i guess those kills also get counted in av
+ //else if(GetTypeId() == TYPEID_UNIT)
+ // bg->HandleKillPlayer(killed,(Creature*)this);
+ }*/
}
else // if (health <= damage)
{
@@ -768,7 +872,6 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
//if (!spellProto || !(spellProto->AuraInterruptFlags&AURA_INTERRUPT_FLAG_DIRECT_DAMAGE))
pVictim->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_DIRECT_DAMAGE, spellProto ? spellProto->Id : 0);
}
-
if (pVictim->GetTypeId() != TYPEID_PLAYER)
{
if(spellProto && IsDamageToThreatSpell(spellProto))
@@ -835,7 +938,7 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
if(spell->getState() == SPELL_STATE_PREPARING)
{
uint32 interruptFlags = spell->m_spellInfo->InterruptFlags;
- if(interruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE)
+ if(interruptFlags & SPELL_INTERRUPT_FLAG_ABORT_ON_DMG)
pVictim->InterruptNonMeleeSpells(false);
else if(interruptFlags & SPELL_INTERRUPT_FLAG_PUSH_BACK)
spell->Delayed();
@@ -1074,419 +1177,6 @@ void Unit::CastSpell(GameObject *go, uint32 spellId, bool triggered, Item *castI
spell->prepare(&targets, triggeredByAura);
}
-/*
-void Unit::DealFlatDamage(Unit *pVictim, SpellEntry const *spellInfo, uint32 *damage, CleanDamage *cleanDamage, bool *crit, bool isTriggeredSpell)
-{
- // TODO this in only generic way, check for exceptions
- DEBUG_LOG("DealFlatDamage (BEFORE) >> DMG:%u", *damage);
-
- // Per-damage class calculation
- switch (spellInfo->DmgClass)
- {
- // Melee and Ranged Spells
- case SPELL_DAMAGE_CLASS_RANGED:
- case SPELL_DAMAGE_CLASS_MELEE:
- {
- // Calculate physical outcome
- MeleeHitOutcome outcome = RollPhysicalOutcomeAgainst(pVictim, BASE_ATTACK, spellInfo);
-
- //Used to store the Hit Outcome
- cleanDamage->hitOutCome = outcome;
-
- // Return miss/evade first (sends miss message)
- switch(outcome)
- {
- case MELEE_HIT_EVADE:
- {
- SendAttackStateUpdate(HITINFO_MISS, pVictim, 1, GetSpellSchoolMask(spellInfo), 0, 0,0,VICTIMSTATE_EVADES,0);
- *damage = 0;
- return;
- }
- case MELEE_HIT_MISS:
- {
- SendAttackStateUpdate(HITINFO_MISS, pVictim, 1, GetSpellSchoolMask(spellInfo), 0, 0,0,VICTIMSTATE_NORMAL,0);
- *damage = 0;
-
- if(GetTypeId()== TYPEID_PLAYER)
- ((Player*)this)->UpdateWeaponSkill(BASE_ATTACK);
-
- CastMeleeProcDamageAndSpell(pVictim,0,GetSpellSchoolMask(spellInfo),BASE_ATTACK,MELEE_HIT_MISS,spellInfo,isTriggeredSpell);
- return;
- }
- }
-
- // Hitinfo, Victimstate
- uint32 hitInfo = HITINFO_NORMALSWING;
- VictimState victimState = VICTIMSTATE_NORMAL;
-
- // Physical Damage
- if ( GetSpellSchoolMask(spellInfo) & SPELL_SCHOOL_MASK_NORMAL )
- {
- // apply spellmod to Done damage
- if(Player* modOwner = GetSpellModOwner())
- modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_DAMAGE, *damage);
-
- //Calculate armor mitigation
- uint32 damageAfterArmor = CalcArmorReducedDamage(pVictim, *damage);
-
- // random durability for main hand weapon (ABSORB)
- if(damageAfterArmor < *damage)
- if(pVictim->GetTypeId() == TYPEID_PLAYER)
- if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_ABSORB)))
- ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EquipmentSlots(urand(EQUIPMENT_SLOT_START,EQUIPMENT_SLOT_BACK)));
-
- cleanDamage->damage += *damage - damageAfterArmor;
- *damage = damageAfterArmor;
- }
- // Magical Damage
- else
- {
- // Calculate damage bonus
- *damage = SpellDamageBonus(pVictim, spellInfo, *damage, SPELL_DIRECT_DAMAGE);
- }
-
- // Classify outcome
- switch (outcome)
- {
- case MELEE_HIT_BLOCK_CRIT:
- case MELEE_HIT_CRIT:
- {
- uint32 bonusDmg = *damage;
-
- // Apply crit_damage bonus
- if(Player* modOwner = GetSpellModOwner())
- modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CRIT_DAMAGE_BONUS, bonusDmg);
-
- uint32 creatureTypeMask = pVictim->GetCreatureTypeMask();
- AuraList const& mDamageDoneVersus = GetAurasByType(SPELL_AURA_MOD_CRIT_PERCENT_VERSUS);
- for(AuraList::const_iterator i = mDamageDoneVersus.begin();i != mDamageDoneVersus.end(); ++i)
- if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue))
- bonusDmg = uint32(bonusDmg * ((*i)->GetModifierValue()+100.0f)/100.0f);
-
- *damage += bonusDmg;
-
- // Resilience - reduce crit damage
- if (pVictim->GetTypeId()==TYPEID_PLAYER)
- {
- uint32 resilienceReduction = ((Player*)pVictim)->GetMeleeCritDamageReduction(*damage);
- cleanDamage->damage += resilienceReduction;
- *damage -= resilienceReduction;
- }
-
- *crit = true;
- hitInfo |= HITINFO_CRITICALHIT;
-
- ModifyAuraState(AURA_STATE_CRIT, true);
- StartReactiveTimer( REACTIVE_CRIT );
-
- if(getClass()==CLASS_HUNTER)
- {
- ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE, true);
- StartReactiveTimer( REACTIVE_HUNTER_CRIT );
- }
-
- if ( outcome == MELEE_HIT_BLOCK_CRIT )
- {
- uint32 blocked_amount = uint32(pVictim->GetShieldBlockValue());
- if (blocked_amount >= *damage)
- {
- hitInfo |= HITINFO_SWINGNOHITSOUND;
- victimState = VICTIMSTATE_BLOCKS;
- cleanDamage->damage += *damage; // To Help Calculate Rage
- *damage = 0;
- }
- else
- {
- // To Help Calculate Rage
- cleanDamage->damage += blocked_amount;
- *damage = *damage - blocked_amount;
- }
-
- pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true);
- pVictim->StartReactiveTimer( REACTIVE_DEFENSE );
-
- if(pVictim->GetTypeId() == TYPEID_PLAYER)
- {
- // Update defense
- ((Player*)pVictim)->UpdateDefense();
-
- // random durability for main hand weapon (BLOCK)
- if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_BLOCK)))
- ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_OFFHAND);
- }
- }
- break;
- }
- case MELEE_HIT_PARRY:
- {
- cleanDamage->damage += *damage; // To Help Calculate Rage
- *damage = 0;
- victimState = VICTIMSTATE_PARRY;
-
- // Counter-attack ( explained in Unit::DoAttackDamage() )
- if(pVictim->GetTypeId()==TYPEID_PLAYER || !(((Creature*)pVictim)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_PARRY_HASTEN) )
- {
- // Get attack timers
- float offtime = float(pVictim->getAttackTimer(OFF_ATTACK));
- float basetime = float(pVictim->getAttackTimer(BASE_ATTACK));
-
- // Reduce attack time
- if (pVictim->haveOffhandWeapon() && offtime < basetime)
- {
- float percent20 = pVictim->GetAttackTime(OFF_ATTACK) * 0.20;
- float percent60 = 3 * percent20;
- if(offtime > percent20 && offtime <= percent60)
- {
- pVictim->setAttackTimer(OFF_ATTACK, uint32(percent20));
- }
- else if(offtime > percent60)
- {
- offtime -= 2 * percent20;
- pVictim->setAttackTimer(OFF_ATTACK, uint32(offtime));
- }
- }
- else
- {
- float percent20 = pVictim->GetAttackTime(BASE_ATTACK) * 0.20;
- float percent60 = 3 * percent20;
- if(basetime > percent20 && basetime <= percent60)
- {
- pVictim->setAttackTimer(BASE_ATTACK, uint32(percent20));
- }
- else if(basetime > percent60)
- {
- basetime -= 2 * percent20;
- pVictim->setAttackTimer(BASE_ATTACK, uint32(basetime));
- }
- }
- }
-
- if(pVictim->GetTypeId() == TYPEID_PLAYER)
- {
- // Update victim defense ?
- ((Player*)pVictim)->UpdateDefense();
-
- // random durability for main hand weapon (PARRY)
- if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_PARRY)))
- ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_MAINHAND);
- }
-
- // Set parry flags
- pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED);
-
- // Mongoose bite - set only Counterattack here
- if (pVictim->getClass() == CLASS_HUNTER)
- {
- pVictim->ModifyAuraState(AURA_STATE_HUNTER_PARRY,true);
- pVictim->StartReactiveTimer( REACTIVE_HUNTER_PARRY );
- }
- else
- {
- pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true);
- pVictim->StartReactiveTimer( REACTIVE_DEFENSE );
- }
- break;
- }
- case MELEE_HIT_DODGE:
- {
- if(pVictim->GetTypeId() == TYPEID_PLAYER)
- ((Player*)pVictim)->UpdateDefense();
-
- cleanDamage->damage += *damage; // To Help Calculate Rage
- *damage = 0;
- hitInfo |= HITINFO_SWINGNOHITSOUND;
- victimState = VICTIMSTATE_DODGE;
-
- // Set dodge flags
- pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED);
-
- // Overpower
- if (GetTypeId() == TYPEID_PLAYER && getClass() == CLASS_WARRIOR)
- {
- ((Player*)this)->AddComboPoints(pVictim, 1);
- StartReactiveTimer( REACTIVE_OVERPOWER );
- }
-
- // Riposte
- if (pVictim->getClass() != CLASS_ROGUE)
- {
- pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true);
- pVictim->StartReactiveTimer( REACTIVE_DEFENSE );
- }
- break;
- }
- case MELEE_HIT_BLOCK:
- {
- uint32 blocked_amount = uint32(pVictim->GetShieldBlockValue());
- if (blocked_amount >= *damage)
- {
- hitInfo |= HITINFO_SWINGNOHITSOUND;
- victimState = VICTIMSTATE_BLOCKS;
- cleanDamage->damage += *damage; // To Help Calculate Rage
- *damage = 0;
- }
- else
- {
- // To Help Calculate Rage
- cleanDamage->damage += blocked_amount;
- *damage = *damage - blocked_amount;
- }
-
- pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true);
- pVictim->StartReactiveTimer( REACTIVE_DEFENSE );
-
- if(pVictim->GetTypeId() == TYPEID_PLAYER)
- {
- // Update defense
- ((Player*)pVictim)->UpdateDefense();
-
- // random durability for main hand weapon (BLOCK)
- if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_BLOCK)))
- ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_OFFHAND);
- }
- break;
- }
- case MELEE_HIT_EVADE: // already processed early
- case MELEE_HIT_MISS: // already processed early
- case MELEE_HIT_GLANCING:
- case MELEE_HIT_CRUSHING:
- case MELEE_HIT_NORMAL:
- break;
- }
-
- // do all damage=0 cases here
- if(*damage == 0)
- CastMeleeProcDamageAndSpell(pVictim,0,GetSpellSchoolMask(spellInfo),BASE_ATTACK,outcome,spellInfo,isTriggeredSpell);
-
- break;
- }
- // Magical Attacks
- case SPELL_DAMAGE_CLASS_NONE:
- case SPELL_DAMAGE_CLASS_MAGIC:
- {
- // Calculate damage bonus
- *damage = SpellDamageBonus(pVictim, spellInfo, *damage, SPELL_DIRECT_DAMAGE);
-
- *crit = isSpellCrit(pVictim, spellInfo, GetSpellSchoolMask(spellInfo), BASE_ATTACK);
- if (*crit)
- {
- *damage = SpellCriticalBonus(spellInfo, *damage, pVictim);
-
- // Resilience - reduce crit damage
- if (pVictim && pVictim->GetTypeId()==TYPEID_PLAYER)
- {
- uint32 damage_reduction = ((Player *)pVictim)->GetSpellCritDamageReduction(*damage);
- if(*damage > damage_reduction)
- *damage -= damage_reduction;
- else
- *damage = 0;
- }
-
- cleanDamage->hitOutCome = MELEE_HIT_CRIT;
- }
- // spell proc all magic damage==0 case in this function
- if(*damage == 0)
- {
- // Procflags
- uint32 procAttacker = PROC_FLAG_HIT_SPELL;
- uint32 procVictim = (PROC_FLAG_STRUCK_SPELL|PROC_FLAG_TAKE_DAMAGE);
-
- ProcDamageAndSpell(pVictim, procAttacker, procVictim, 0, GetSpellSchoolMask(spellInfo), spellInfo, isTriggeredSpell);
- }
-
- break;
- }
- }
-
- // TODO this in only generic way, check for exceptions
- DEBUG_LOG("DealFlatDamage (AFTER) >> DMG:%u", *damage);
-}
-
-uint32 Unit::SpellNonMeleeDamageLog(Unit *pVictim, uint32 spellID, uint32 damage, bool isTriggeredSpell, bool useSpellDamage)
-{
- if(!this || !pVictim)
- return 0;
- if(!isAlive() || !pVictim->isAlive())
- return 0;
-
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellID);
- if(!spellInfo)
- return 0;
-
- CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL);
- bool crit = false;
-
- if (useSpellDamage)
- DealFlatDamage(pVictim, spellInfo, &damage, &cleanDamage, &crit, isTriggeredSpell);
-
- // If we actually dealt some damage (spell proc's for 0 damage (normal and magic) called in DealFlatDamage)
- if(damage > 0)
- {
- // Calculate absorb & resists
- uint32 absorb = 0;
- uint32 resist = 0;
-
- CalcAbsorbResist(pVictim,GetSpellSchoolMask(spellInfo), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
-
- //No more damage left, target absorbed and/or resisted all damage
- if (damage > absorb + resist)
- damage -= absorb + resist; //Remove Absorbed and Resisted from damage actually dealt
- else
- {
- uint32 HitInfo = HITINFO_SWINGNOHITSOUND;
-
- if (absorb)
- HitInfo |= HITINFO_ABSORB;
- if (resist)
- {
- HitInfo |= HITINFO_RESIST;
- ProcDamageAndSpell(pVictim, PROC_FLAG_TARGET_RESISTS, PROC_FLAG_RESIST_SPELL, 0, GetSpellSchoolMask(spellInfo), spellInfo,isTriggeredSpell);
- }
-
- //Send resist
- SendAttackStateUpdate(HitInfo, pVictim, 1, GetSpellSchoolMask(spellInfo), damage, absorb,resist,VICTIMSTATE_NORMAL,0);
- return 0;
- }
-
- // Deal damage done
- damage = DealDamage(pVictim, damage, &cleanDamage, SPELL_DIRECT_DAMAGE, GetSpellSchoolMask(spellInfo), spellInfo, true);
-
- // Send damage log
- sLog.outDetail("SpellNonMeleeDamageLog: %u (TypeId: %u) attacked %u (TypeId: %u) for %u dmg inflicted by %u,absorb is %u,resist is %u",
- GetGUIDLow(), GetTypeId(), pVictim->GetGUIDLow(), pVictim->GetTypeId(), damage, spellID, absorb,resist);
-
- // Actual log sent to client
- SendSpellNonMeleeDamageLog(pVictim, spellID, damage + resist, GetSpellSchoolMask(spellInfo), absorb, resist, false, 0, crit);
-
- // Procflags
- uint32 procAttacker = PROC_FLAG_HIT_SPELL;
- uint32 procVictim = (PROC_FLAG_STRUCK_SPELL|PROC_FLAG_TAKE_DAMAGE);
-
- if (crit)
- {
- procAttacker |= PROC_FLAG_CRIT_SPELL;
- procVictim |= PROC_FLAG_STRUCK_CRIT_SPELL;
- }
-
- ProcDamageAndSpell(pVictim, procAttacker, procVictim, damage, GetSpellSchoolMask(spellInfo), spellInfo, isTriggeredSpell);
-
- return damage;
- }
- else
- {
- // all spell proc for 0 normal and magic damage called in DealFlatDamage
-
- //Check for rage
- if(cleanDamage.damage)
- // Rage from damage received.
- if(pVictim->GetTypeId() == TYPEID_PLAYER && (pVictim->getPowerType() == POWER_RAGE))
- ((Player*)pVictim)->RewardRage(cleanDamage.damage, 0, false);
-
- return 0;
- }
-}
-*/
-
// Obsolete func need remove, here only for comotability vs another patches
uint32 Unit::SpellNonMeleeDamageLog(Unit *pVictim, uint32 spellID, uint32 damage, bool isTriggeredSpell, bool useSpellDamage)
{
@@ -1561,6 +1251,9 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 dama
if (blocked)
{
damageInfo->blocked = uint32(pVictim->GetShieldBlockValue());
+ //double blocked amount if block is critical
+ if (isBlockCritical())
+ damageInfo->blocked+=damageInfo->blocked;
if (damage < damageInfo->blocked)
damageInfo->blocked = damage;
damage-=damageInfo->blocked;
@@ -1575,7 +1268,7 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 dama
if (crit)
{
damageInfo->HitInfo|= SPELL_HIT_TYPE_CRIT;
- damage = SpellCriticalBonus(spellInfo, damage, pVictim);
+ damage = SpellCriticalDamageBonus(spellInfo, damage, pVictim);
// Resilience - reduce crit damage
if (pVictim->GetTypeId()==TYPEID_PLAYER)
damage -= ((Player*)pVictim)->GetSpellCritDamageReduction(damage);
@@ -1585,12 +1278,12 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 dama
}
if( damageSchoolMask & SPELL_SCHOOL_MASK_NORMAL )
- damage = CalcArmorReducedDamage(pVictim, damage);
+ damage = CalcArmorReducedDamage(pVictim, damage, spellInfo, attackType);
// Calculate absorb resist
if(damage > 0)
{
- CalcAbsorbResist(pVictim, damageSchoolMask, SPELL_DIRECT_DAMAGE, damage, &damageInfo->absorb, &damageInfo->resist);
+ CalcAbsorbResist(pVictim, damageSchoolMask, SPELL_DIRECT_DAMAGE, damage, &damageInfo->absorb, &damageInfo->resist, spellInfo);
damage-= damageInfo->absorb + damageInfo->resist;
}
else
@@ -1598,6 +1291,37 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 dama
damageInfo->damage = damage;
}
+int32 Unit::GetIgnoredArmorMultiplier(SpellEntry const *spellInfo, WeaponAttackType attackType)
+{
+ if (GetTypeId() != TYPEID_PLAYER)
+ return 0;
+ //check if spell uses weapon
+ if (!spellInfo || spellInfo->EquippedItemClass!=ITEM_CLASS_WEAPON)
+ return 0;
+ Item *item = NULL;
+ if(attackType == BASE_ATTACK)
+ item = ((Player*)this)->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
+ else if (attackType == OFF_ATTACK)
+ item = ((Player*)this)->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
+ else if (attackType == RANGED_ATTACK)
+ item = ((Player*)this)->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED);
+ if (!item)
+ return 0;
+
+ AuraList const& armAuras = GetAurasByType(SPELL_AURA_MOD_WEAPONTYPE_IGNORE_TARGET_RESISTANCE);
+ int32 armorIgnored = 0;
+ for(AuraList::const_iterator i = armAuras.begin();i != armAuras.end(); ++i)
+ {
+ if (!((*i)->GetSpellProto()->EquippedItemClass==item->GetProto()->Class
+ && (*i)->GetSpellProto()->EquippedItemSubClassMask & (1<<item->GetProto()->SubClass)))
+ continue;
+
+ if((*i)->GetModifier()->m_amount)
+ armorIgnored += (*i)->GetModifier()->m_amount;
+ }
+ return (-armorIgnored);
+}
+
void Unit::DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss)
{
if (damageInfo==0)
@@ -1627,20 +1351,6 @@ void Unit::DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss)
return;
}
- // update at damage Judgement aura duration that applied by attacker at victim
- if(damageInfo->damage && spellProto->Id == 35395)
- {
- AuraMap& vAuras = pVictim->GetAuras();
- for(AuraMap::iterator itr = vAuras.begin(); itr != vAuras.end(); ++itr)
- {
- SpellEntry const *spellInfo = (*itr).second->GetSpellProto();
- if( spellInfo->AttributesEx3 & 0x40000 && spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && ((*itr).second->GetCasterGUID() == GetGUID()))
- {
- (*itr).second->SetAuraDuration((*itr).second->GetAuraMaxDuration());
- (*itr).second->UpdateAuraDuration();
- }
- }
- }
// Call default DealDamage
CleanDamage cleanDamage(damageInfo->cleanDamage, BASE_ATTACK, MELEE_HIT_NORMAL);
DealDamage(pVictim, damageInfo->damage, &cleanDamage, SPELL_DIRECT_DAMAGE, SpellSchoolMask(damageInfo->schoolMask), spellProto, durabilityLoss);
@@ -1694,7 +1404,7 @@ void Unit::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *da
}
// Physical Immune check
- if(damageInfo->target->IsImmunedToDamage(SpellSchoolMask(damageInfo->damageSchoolMask),true))
+ if(damageInfo->target->IsImmunedToDamage(SpellSchoolMask(damageInfo->damageSchoolMask)))
{
damageInfo->HitInfo |= HITINFO_NORMALSWING;
damageInfo->TargetState = VICTIMSTATE_IS_IMMUNE;
@@ -1708,7 +1418,7 @@ void Unit::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *da
// Add melee damage bonus
MeleeDamageBonus(damageInfo->target, &damage, damageInfo->attackType);
// Calculate armor reduction
- damageInfo->damage = CalcArmorReducedDamage(damageInfo->target, damage);
+ damageInfo->damage = CalcArmorReducedDamage(damageInfo->target, damage, NULL , damageInfo->attackType);
damageInfo->cleanDamage += damage - damageInfo->damage;
damageInfo->hitOutCome = RollMeleeOutcomeAgainst(damageInfo->target, damageInfo->attackType);
@@ -1796,8 +1506,12 @@ void Unit::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *da
case MELEE_HIT_BLOCK:
{
damageInfo->TargetState = VICTIMSTATE_NORMAL;
+ damageInfo->HitInfo |= HITINFO_BLOCK;
damageInfo->procEx|=PROC_EX_BLOCK;
damageInfo->blocked_amount = damageInfo->target->GetShieldBlockValue();
+ //double blocked amount if block is critical
+ if (isBlockCritical())
+ damageInfo->blocked_amount+=damageInfo->blocked_amount;
if (damageInfo->blocked_amount >= damageInfo->damage)
{
damageInfo->TargetState = VICTIMSTATE_BLOCKS;
@@ -1943,28 +1657,13 @@ void Unit::DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss)
CastSpell(pVictim, 1604, true);
}
- // update at damage Judgement aura duration that applied by attacker at victim
- if(damageInfo->damage)
- {
- AuraMap& vAuras = pVictim->GetAuras();
- for(AuraMap::iterator itr = vAuras.begin(); itr != vAuras.end(); ++itr)
- {
- SpellEntry const *spellInfo = (*itr).second->GetSpellProto();
- if( spellInfo->AttributesEx3 & 0x40000 && spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && ((*itr).second->GetCasterGUID() == GetGUID()))
- {
- (*itr).second->SetAuraDuration((*itr).second->GetAuraMaxDuration());
- (*itr).second->UpdateAuraDuration();
- }
- }
- }
-
// If not miss
if (!(damageInfo->HitInfo & HITINFO_MISS))
{
if(GetTypeId() == TYPEID_PLAYER && pVictim->isAlive())
{
for(int i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; i++)
- ((Player*)this)->CastItemCombatSpell(((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0,i), pVictim, damageInfo->attackType);
+ ((Player*)this)->CastItemCombatSpell(((Player*)this)->GetUseableItemByPos(INVENTORY_SLOT_BAG_0,i), pVictim, damageInfo->attackType);
}
// victim's damage shield
@@ -1987,11 +1686,13 @@ void Unit::DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss)
//CalcAbsorbResist(pVictim, SpellSchools(spellProto->School), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
//damage-=absorb + resist;
- WorldPacket data(SMSG_SPELLDAMAGESHIELD,(8+8+4+4));
+ WorldPacket data(SMSG_SPELLDAMAGESHIELD,(8+8+4+4+4+4));
data << uint64(pVictim->GetGUID());
data << uint64(GetGUID());
+ data << uint32(spellProto->Id);
+ data << uint32(damage); // Damage
+ data << uint32(0); // Overkill
data << uint32(spellProto->SchoolMask);
- data << uint32(damage);
pVictim->SendMessageToSet(&data, true );
pVictim->DealDamage(this, damage, 0, SPELL_DIRECT_DAMAGE, GetSpellSchoolMask(spellProto), spellProto, true);
@@ -2010,28 +1711,50 @@ void Unit::DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss)
void Unit::HandleEmoteCommand(uint32 anim_id)
{
WorldPacket data( SMSG_EMOTE, 12 );
- data << anim_id << GetGUID();
- WPAssert(data.size() == 12);
-
+ data << uint32(anim_id);
+ data << uint64(GetGUID());
SendMessageToSet(&data, true);
}
-uint32 Unit::CalcArmorReducedDamage(Unit* pVictim, const uint32 damage)
+uint32 Unit::CalcArmorReducedDamage(Unit* pVictim, const uint32 damage, SpellEntry const *spellInfo, WeaponAttackType attackType)
{
uint32 newdamage = 0;
float armor = pVictim->GetArmor();
// Ignore enemy armor by SPELL_AURA_MOD_TARGET_RESISTANCE aura
armor += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, SPELL_SCHOOL_MASK_NORMAL);
- if (armor<0.0f) armor=0.0f;
+ armor *= float((GetIgnoredArmorMultiplier(spellInfo, attackType)+100.0f)/100.0f);
+ if(spellInfo)
+ if(Player *modOwner = GetSpellModOwner())
+ modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_IGNORE_ARMOR, armor);
- float tmpvalue = 0.0f;
- if(getLevel() <= 59) //Level 1-59
- tmpvalue = armor / (armor + 400.0f + 85.0f * getLevel());
- else if(getLevel() < 70) //Level 60-69
- tmpvalue = armor / (armor - 22167.5f + 467.5f * getLevel());
- else //Level 70+
- tmpvalue = armor / (armor + 10557.5f);
+ AuraList const& ResIgnoreAurasAb = GetAurasByType(SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST);
+ for(AuraList::const_iterator j = ResIgnoreAurasAb.begin();j != ResIgnoreAurasAb.end(); ++j)
+ {
+ if( (*j)->GetModifier()->m_miscvalue & SPELL_SCHOOL_MASK_NORMAL
+ && (*j)->isAffectedOnSpell(spellInfo))
+ armor= int32(float(armor) * (float(100-(*j)->GetModifier()->m_amount)/100.0f));
+ }
+
+ AuraList const& ResIgnoreAuras = GetAurasByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST);
+ for(AuraList::const_iterator j = ResIgnoreAuras.begin();j != ResIgnoreAuras.end(); ++j)
+ {
+ if( (*j)->GetModifier()->m_miscvalue & SPELL_SCHOOL_MASK_NORMAL)
+ armor= int32(float(armor) * (float(100-(*j)->GetModifier()->m_amount)/100.0f));
+ }
+
+ // Apply Player CR_ARMOR_PENETRATION rating
+ if (GetTypeId()==TYPEID_PLAYER)
+ armor *= 1.0f - ((Player*)this)->GetRatingBonusValue(CR_ARMOR_PENETRATION) / 100.0f;
+
+ if (armor < 0.0f) armor=0.0f;
+
+ float levelModifier = getLevel();
+ if ( levelModifier > 59 )
+ levelModifier = levelModifier + (4.5f * (levelModifier-59));
+
+ float tmpvalue = 0.1f * armor / (8.5f * levelModifier + 40);
+ tmpvalue = tmpvalue/(1.0f + tmpvalue);
if(tmpvalue < 0.0f)
tmpvalue = 0.0f;
@@ -2042,7 +1765,7 @@ uint32 Unit::CalcArmorReducedDamage(Unit* pVictim, const uint32 damage)
return (newdamage > 1) ? newdamage : 1;
}
-void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist)
+void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist, SpellEntry const *spellInfo)
{
if(!pVictim || !pVictim->isAlive() || !damage)
return;
@@ -2078,95 +1801,272 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
*resist += uint32(damage * m / 4);
if(*resist > damage)
*resist = damage;
+
+ AuraList const& ResIgnoreAurasAb = GetAurasByType(SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST);
+ for(AuraList::const_iterator j = ResIgnoreAurasAb.begin();j != ResIgnoreAurasAb.end(); ++j)
+ {
+ if( (*j)->GetModifier()->m_miscvalue & schoolMask
+ && (*j)->isAffectedOnSpell(spellInfo))
+ *resist= int32(float(*resist) * (float(100-(*j)->GetModifier()->m_amount)/100.0f));
+ }
+
+ AuraList const& ResIgnoreAuras = GetAurasByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST);
+ for(AuraList::const_iterator j = ResIgnoreAuras.begin();j != ResIgnoreAuras.end(); ++j)
+ {
+ if( (*j)->GetModifier()->m_miscvalue & schoolMask)
+ *resist= int32(float(*resist) * (float(100-(*j)->GetModifier()->m_amount)/100.0f));
+ }
}
else
*resist = 0;
int32 RemainingDamage = damage - *resist;
+ // Get unit state (need for some absorb check)
+ uint32 unitflag = pVictim->GetUInt32Value(UNIT_FIELD_FLAGS);
+ // Reflect damage spells (not cast any damage spell in aura lookup)
+ uint32 reflectSpell = 0;
+ int32 reflectDamage = 0;
+ // Need remove expired auras after
+ bool existExpired = false;
// absorb without mana cost
- int32 reflectDamage = 0;
- Aura* reflectAura = NULL;
AuraList const& vSchoolAbsorb = pVictim->GetAurasByType(SPELL_AURA_SCHOOL_ABSORB);
- for(AuraList::const_iterator i = vSchoolAbsorb.begin(), next; i != vSchoolAbsorb.end() && RemainingDamage > 0; i = next)
+ for(AuraList::const_iterator i = vSchoolAbsorb.begin(); i != vSchoolAbsorb.end() && RemainingDamage > 0; ++i)
{
- next = i; ++next;
-
- if (((*i)->GetModifier()->m_miscvalue & schoolMask)==0)
+ Modifier* mod = (*i)->GetModifier();
+ if (!(mod->m_miscvalue & schoolMask))
continue;
- // Cheat Death
- if((*i)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_ROGUE && (*i)->GetSpellProto()->SpellIconID == 2109)
+ SpellEntry const* spellProto = (*i)->GetSpellProto();
+
+ // Max Amount can be absorbed by this aura
+ int32 currentAbsorb = mod->m_amount;
+
+ // Found empty aura (umpossible but..)
+ if (currentAbsorb <=0)
{
- if (((Player*)pVictim)->HasSpellCooldown(31231))
- continue;
- if (pVictim->GetHealth() <= RemainingDamage)
+ existExpired = true;
+ continue;
+ }
+ // Handle custom absorb auras
+ // TODO: try find better way
+ switch(spellProto->SpellFamilyName)
+ {
+ case SPELLFAMILY_GENERIC:
{
- int32 chance = (*i)->GetModifier()->m_amount;
- if (roll_chance_i(chance))
+ // Astral Shift
+ if (spellProto->SpellIconID == 3066)
{
- pVictim->CastSpell(pVictim,31231,true);
- ((Player*)pVictim)->AddSpellCooldown(31231,0,time(NULL)+60);
-
- // with health > 10% lost health until health==10%, in other case no losses
- uint32 health10 = pVictim->GetMaxHealth()/10;
- RemainingDamage = pVictim->GetHealth() > health10 ? pVictim->GetHealth() - health10 : 0;
+ //reduces all damage taken while stun, fear or silence
+ if (unitflag & (UNIT_FLAG_STUNNED|UNIT_FLAG_FLEEING|UNIT_FLAG_SILENCED))
+ RemainingDamage -= RemainingDamage * currentAbsorb / 100;
+ continue;
}
+ // Nerves of Steel
+ if (spellProto->SpellIconID == 2115)
+ {
+ // while affected by Stun and Fear
+ if (unitflag&(UNIT_FLAG_STUNNED|UNIT_FLAG_FLEEING))
+ RemainingDamage -= RemainingDamage * currentAbsorb / 100;
+ continue;
+ }
+ // Spell Deflection
+ if (spellProto->SpellIconID == 3006)
+ {
+ // You have a chance equal to your Parry chance
+ if (damagetype == DIRECT_DAMAGE && // Only for direct damage
+ roll_chance_f(pVictim->GetUnitParryChance())) // Roll chance
+ RemainingDamage -= RemainingDamage * currentAbsorb / 100;
+ continue;
+ }
+ // Reflective Shield (Lady Malande boss)
+ if (spellProto->Id == 41475)
+ {
+ if(RemainingDamage < currentAbsorb)
+ reflectDamage = RemainingDamage / 2;
+ else
+ reflectDamage = currentAbsorb / 2;
+ reflectSpell = 33619;
+ break;
+ }
+ if (spellProto->Id == 39228 || // Argussian Compass
+ spellProto->Id == 60218) // Essence of Gossamer
+ {
+ // Max absorb stored in 1 dummy effect
+ if (spellProto->EffectBasePoints[1] < currentAbsorb)
+ currentAbsorb = spellProto->EffectBasePoints[1];
+ break;
+ }
+ break;
}
- continue;
- }
-
- int32 currentAbsorb;
-
- //Reflective Shield
- if ((pVictim != this) && (*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_PRIEST && (*i)->GetSpellProto()->SpellFamilyFlags == 0x1)
- {
- if(Unit* caster = (*i)->GetCaster())
+ case SPELLFAMILY_DRUID:
+ {
+ // Primal Tenacity
+ if (spellProto->SpellIconID == 2253)
+ {
+ //reduces all damage taken while Stunned
+ if (unitflag & UNIT_FLAG_STUNNED)
+ RemainingDamage -= RemainingDamage * currentAbsorb / 100;
+ continue;
+ }
+ break;
+ }
+ case SPELLFAMILY_ROGUE:
{
- AuraList const& vOverRideCS = caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
- for(AuraList::const_iterator k = vOverRideCS.begin(); k != vOverRideCS.end(); ++k)
+ // Cheat Death
+ if(spellProto->SpellIconID == 2109)
{
- switch((*k)->GetModifier()->m_miscvalue)
+ if (pVictim->GetTypeId()==TYPEID_PLAYER && // Only players
+ pVictim->GetHealth() <= RemainingDamage && // Only if damage kill
+ !((Player*)pVictim)->HasSpellCooldown(31231) && // Only if no cooldown
+ roll_chance_i(currentAbsorb)) // Only if roll
{
- case 5065: // Rank 1
- case 5064: // Rank 2
- case 5063: // Rank 3
- case 5062: // Rank 4
- case 5061: // Rank 5
- {
- if(RemainingDamage >= (*i)->GetModifier()->m_amount)
- reflectDamage = (*i)->GetModifier()->m_amount * (*k)->GetModifier()->m_amount/100;
- else
- reflectDamage = (*k)->GetModifier()->m_amount * RemainingDamage/100;
- reflectAura = *i;
-
- } break;
- default: break;
+ pVictim->CastSpell(pVictim,31231,true);
+ ((Player*)pVictim)->AddSpellCooldown(31231,0,time(NULL)+60);
+ // with health > 10% lost health until health==10%, in other case no losses
+ uint32 health10 = pVictim->GetMaxHealth()/10;
+ RemainingDamage = pVictim->GetHealth() > health10 ? pVictim->GetHealth() - health10 : 0;
}
-
- if(reflectDamage)
+ continue;
+ }
+ break;
+ }
+ case SPELLFAMILY_PRIEST:
+ {
+ // Reflective Shield
+ if (spellProto->SpellFamilyFlags == 0x1)
+ {
+ if (pVictim == this)
break;
+ Unit* caster = (*i)->GetCaster();
+ if (!caster)
+ break;
+ int32 reflectDamage = 0;
+ AuraList const& vOverRideCS = caster->GetAurasByType(SPELL_AURA_DUMMY);
+ for(AuraList::const_iterator k = vOverRideCS.begin(); k != vOverRideCS.end(); ++k)
+ {
+ switch((*k)->GetModifier()->m_miscvalue)
+ {
+ case 5065: // Rank 1
+ case 5064: // Rank 2
+ case 5063: // Rank 3
+ {
+ if(RemainingDamage >= currentAbsorb)
+ reflectDamage = (*k)->GetModifier()->m_amount * currentAbsorb/100;
+ else
+ reflectDamage = (*k)->GetModifier()->m_amount * RemainingDamage/100;
+ reflectSpell = 33619;
+ } break;
+ default: break;
+ }
+ }
+ break;
+ }
+ break;
+ }
+ case SPELLFAMILY_SHAMAN:
+ {
+ // Astral Shift
+ if (spellProto->SpellIconID == 3066)
+ {
+ //reduces all damage taken while stun, fear or silence
+ if (unitflag & (UNIT_FLAG_STUNNED|UNIT_FLAG_FLEEING|UNIT_FLAG_SILENCED))
+ RemainingDamage -= RemainingDamage * currentAbsorb / 100;
+ continue;
+ }
+ break;
+ }
+ case SPELLFAMILY_DEATHKNIGHT:
+ {
+ // Shadow of Death
+ if (spellProto->SpellIconID == 1958)
+ {
+ // TODO: absorb only while transform
+ continue;
+ }
+ // Anti-Magic Shell (on self)
+ if (spellProto->Id == 48707)
+ {
+ // damage absorbed by Anti-Magic Shell energizes the DK with additional runic power.
+ // This, if I'm not mistaken, shows that we get back ~2% of the absorbed damage as runic power.
+ int32 absorbed = RemainingDamage * currentAbsorb / 100;
+ int32 regen = absorbed * 2 / 10;
+ pVictim->CastCustomSpell(pVictim, 49088, &regen, 0, 0, true, 0, *i);
+ RemainingDamage -= absorbed;
+ continue;
+ }
+ // Anti-Magic Shell (on single party/raid member)
+ if (spellProto->Id == 50462)
+ {
+ RemainingDamage -= RemainingDamage * currentAbsorb / 100;
+ continue;
+ }
+ // Anti-Magic Zone
+ if (spellProto->Id == 50461)
+ {
+ Unit* caster = (*i)->GetCaster();
+ if (!caster)
+ continue;
+ int32 absorbed = RemainingDamage * currentAbsorb / 100;
+ int32 canabsorb = caster->GetHealth();
+ if (canabsorb < absorbed)
+ absorbed = canabsorb;
+ DealDamage(caster, absorbed, NULL, damagetype, schoolMask, 0, false);
+ RemainingDamage -= absorbed;
+ continue;
}
+ break;
}
+ default:
+ break;
}
- if (RemainingDamage >= (*i)->GetModifier()->m_amount)
+ // currentAbsorb - damage can be absorbed by shield
+ // If need absorb less damage
+ if (RemainingDamage < currentAbsorb)
+ currentAbsorb = RemainingDamage;
+
+ AuraList const& AbsIgnoreAurasAb = GetAurasByType(SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL);
+ for(AuraList::const_iterator j = AbsIgnoreAurasAb.begin();j != AbsIgnoreAurasAb.end(); ++j)
{
- currentAbsorb = (*i)->GetModifier()->m_amount;
- pVictim->RemoveAurasDueToSpell((*i)->GetId());
- next = vSchoolAbsorb.begin();
+ if( (*j)->GetModifier()->m_miscvalue & (*i)->GetModifier()->m_miscvalue
+ && (*j)->isAffectedOnSpell(spellInfo))
+ currentAbsorb= int32(float(currentAbsorb) * (float(100-(*j)->GetModifier()->m_amount)/100.0f));
}
- else
+
+ AuraList const& AbsIgnoreAuras = GetAurasByType(SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL);
+ for(AuraList::const_iterator j = AbsIgnoreAuras.begin();j != AbsIgnoreAuras.end(); ++j)
{
- currentAbsorb = RemainingDamage;
- (*i)->GetModifier()->m_amount -= RemainingDamage;
+ if( (*j)->GetModifier()->m_miscvalue & (*i)->GetModifier()->m_miscvalue)
+ currentAbsorb= int32(float(currentAbsorb) * (float(100-(*j)->GetModifier()->m_amount)/100.0f));
}
RemainingDamage -= currentAbsorb;
+
+ // Reduce shield amount
+ mod->m_amount-=currentAbsorb;
+ // Need remove it later
+ if (mod->m_amount<=0)
+ existExpired = true;
+ }
+
+ // Remove all expired absorb auras
+ if (existExpired)
+ {
+ for(AuraList::const_iterator i = vSchoolAbsorb.begin(); i != vSchoolAbsorb.end();)
+ {
+ if ((*i)->GetModifier()->m_amount<=0)
+ {
+ pVictim->RemoveAurasDueToSpell((*i)->GetId());
+ i = vSchoolAbsorb.begin();
+ }
+ else
+ ++i;
+ }
}
- // do not cast spells while looping auras; auras can get invalid otherwise
- if (reflectDamage)
- pVictim->CastCustomSpell(this, 33619, &reflectDamage, NULL, NULL, true, NULL, reflectAura);
+ // Cast back reflect damage spell
+ if (reflectSpell)
+ pVictim->CastCustomSpell(this, reflectSpell, &reflectDamage, NULL, NULL, true);
// absorb by mana cost
AuraList const& vManaShield = pVictim->GetAurasByType(SPELL_AURA_MANA_SHIELD);
@@ -2185,7 +2085,7 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
currentAbsorb = RemainingDamage;
float manaMultiplier = (*i)->GetSpellProto()->EffectMultipleValue[(*i)->GetEffIndex()];
- if(Player *modOwner = GetSpellModOwner())
+ if(Player *modOwner = pVictim->GetSpellModOwner())
modOwner->ApplySpellMod((*i)->GetId(), SPELLMOD_MULTIPLE_VALUE, manaMultiplier);
int32 maxAbsorb = int32(pVictim->GetPower(POWER_MANA) / manaMultiplier);
@@ -2264,407 +2164,6 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
*absorb = damage - RemainingDamage - *resist;
}
-/*
-void Unit::DoAttackDamage (Unit *pVictim, uint32 *damage, CleanDamage *cleanDamage, uint32 *blocked_amount, SpellSchoolMask damageSchoolMask, uint32 *hitInfo, VictimState *victimState, uint32 *absorbDamage, uint32 *resistDamage, WeaponAttackType attType, SpellEntry const *spellCasted, bool isTriggeredSpell)
-{
- MeleeHitOutcome outcome;
-
- // If is casted Melee spell, calculate like physical
- if(!spellCasted)
- outcome = RollMeleeOutcomeAgainst (pVictim, attType);
- else
- outcome = RollPhysicalOutcomeAgainst (pVictim, attType, spellCasted);
-
- if(outcome == MELEE_HIT_MISS ||outcome == MELEE_HIT_DODGE ||outcome == MELEE_HIT_BLOCK ||outcome == MELEE_HIT_PARRY)
- pVictim->AddThreat(this, 0.0f);
- switch(outcome)
- {
- case MELEE_HIT_EVADE:
- {
- *hitInfo |= HITINFO_MISS;
- *damage = 0;
- cleanDamage->damage = 0;
- return;
- }
- case MELEE_HIT_MISS:
- {
- *hitInfo |= HITINFO_MISS;
- *damage = 0;
- cleanDamage->damage = 0;
- if(GetTypeId()== TYPEID_PLAYER)
- ((Player*)this)->UpdateWeaponSkill(attType);
- return;
- }
- }
-
- /// If this is a creature and it attacks from behind it has a probability to daze it's victim
- if( (outcome==MELEE_HIT_CRIT || outcome==MELEE_HIT_CRUSHING || outcome==MELEE_HIT_NORMAL || outcome==MELEE_HIT_GLANCING) &&
- GetTypeId() != TYPEID_PLAYER && !((Creature*)this)->GetCharmerOrOwnerGUID() && !pVictim->HasInArc(M_PI, this)
- && pVictim->GetTypeId() == TYPEID_PLAYER)
- {
- // -probability is between 0% and 40%
- // 20% base chance
- float Probability = 20;
-
- //there is a newbie protection, at level 10 just 7% base chance; assuming linear function
- if( pVictim->getLevel() < 30 )
- Probability = 0.65f*pVictim->getLevel()+0.5;
-
- uint32 VictimDefense=pVictim->GetDefenseSkillValue(this);
- uint32 AttackerMeleeSkill=GetUnitMeleeSkill(pVictim);
-
- Probability *= AttackerMeleeSkill/(float)VictimDefense;
-
- if(Probability > 40.0f)
- Probability = 40.0f;
-
- if(roll_chance_f(Probability))
- CastSpell(pVictim, 1604, true);
- }
-
- //Calculate the damage after armor mitigation if SPELL_SCHOOL_NORMAL
- if (damageSchoolMask & SPELL_SCHOOL_MASK_NORMAL)
- {
- uint32 damageAfterArmor = CalcArmorReducedDamage(pVictim, *damage);
-
- // random durability for main hand weapon (ABSORB)
- if(damageAfterArmor < *damage)
- if(pVictim->GetTypeId() == TYPEID_PLAYER)
- if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_ABSORB)))
- ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EquipmentSlots(urand(EQUIPMENT_SLOT_START,EQUIPMENT_SLOT_BACK)));
-
- cleanDamage->damage += *damage - damageAfterArmor;
- *damage = damageAfterArmor;
- }
-
- if(GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() != TYPEID_PLAYER && pVictim->GetCreatureType() != CREATURE_TYPE_CRITTER )
- ((Player*)this)->UpdateCombatSkills(pVictim, attType, outcome, false);
-
- if(GetTypeId() != TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER)
- ((Player*)pVictim)->UpdateCombatSkills(this, attType, outcome, true);
-
- switch (outcome)
- {
- case MELEE_HIT_BLOCK_CRIT:
- case MELEE_HIT_CRIT:
- {
- //*hitInfo = 0xEA;
- // 0xEA
- *hitInfo = HITINFO_CRITICALHIT | HITINFO_NORMALSWING2 | 0x8;
-
- // Crit bonus calc
- uint32 crit_bonus;
- crit_bonus = *damage;
-
- // Apply crit_damage bonus for melee spells
- if (spellCasted)
- {
- if(Player* modOwner = GetSpellModOwner())
- modOwner->ApplySpellMod(spellCasted->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus);
-
- uint32 creatureTypeMask = pVictim->GetCreatureTypeMask();
- AuraList const& mDamageDoneVersus = GetAurasByType(SPELL_AURA_MOD_CRIT_PERCENT_VERSUS);
- for(AuraList::const_iterator i = mDamageDoneVersus.begin();i != mDamageDoneVersus.end(); ++i)
- if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue))
- crit_bonus = uint32(crit_bonus * ((*i)->GetModifierValue()+100.0f)/100.0f);
- }
-
- *damage += crit_bonus;
-
- uint32 resilienceReduction = 0;
-
- if(attType == RANGED_ATTACK)
- {
- int32 mod = pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE);
- *damage = int32((*damage) * float((100.0f + mod)/100.0f));
- // Resilience - reduce crit damage
- if (pVictim->GetTypeId()==TYPEID_PLAYER)
- resilienceReduction = ((Player*)pVictim)->GetRangedCritDamageReduction(*damage);
- }
- else
- {
- int32 mod = pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE);
- mod += GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_DAMAGE_BONUS_MELEE);
- *damage = int32((*damage) * float((100.0f + mod)/100.0f));
- // Resilience - reduce crit damage
- if (pVictim->GetTypeId()==TYPEID_PLAYER)
- resilienceReduction = ((Player*)pVictim)->GetMeleeCritDamageReduction(*damage);
- }
-
- *damage -= resilienceReduction;
- cleanDamage->damage += resilienceReduction;
-
- if(GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() != TYPEID_PLAYER && pVictim->GetCreatureType() != CREATURE_TYPE_CRITTER )
- ((Player*)this)->UpdateWeaponSkill(attType);
-
- ModifyAuraState(AURA_STATE_CRIT, true);
- StartReactiveTimer( REACTIVE_CRIT );
-
- if(getClass()==CLASS_HUNTER)
- {
- ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE, true);
- StartReactiveTimer( REACTIVE_HUNTER_CRIT );
- }
-
- if ( outcome == MELEE_HIT_BLOCK_CRIT )
- {
- *blocked_amount = pVictim->GetShieldBlockValue();
-
- if (pVictim->GetUnitBlockChance())
- pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYSHIELD);
- else
- pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED);
-
- //Only set VICTIMSTATE_BLOCK on a full block
- if (*blocked_amount >= uint32(*damage))
- {
- *victimState = VICTIMSTATE_BLOCKS;
- *blocked_amount = uint32(*damage);
- }
-
- if(pVictim->GetTypeId() == TYPEID_PLAYER)
- {
- // Update defense
- ((Player*)pVictim)->UpdateDefense();
-
- // random durability for main hand weapon (BLOCK)
- if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_BLOCK)))
- ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_OFFHAND);
- }
-
- pVictim->ModifyAuraState(AURA_STATE_DEFENSE,true);
- pVictim->StartReactiveTimer( REACTIVE_DEFENSE );
- break;
- }
-
- pVictim->HandleEmoteCommand(EMOTE_ONESHOT_WOUNDCRITICAL);
- break;
- }
- case MELEE_HIT_PARRY:
- {
- if(attType == RANGED_ATTACK) //range attack - no parry
- {
- outcome = MELEE_HIT_NORMAL;
- break;
- }
-
- cleanDamage->damage += *damage;
- *damage = 0;
- *victimState = VICTIMSTATE_PARRY;
-
- // instant (maybe with small delay) counter attack
- {
- float offtime = float(pVictim->getAttackTimer(OFF_ATTACK));
- float basetime = float(pVictim->getAttackTimer(BASE_ATTACK));
-
- // after parry nearest next attack time will reduced at %40 from full attack time.
- // The delay cannot be reduced to less than 20% of your weapon base swing delay.
- if (pVictim->haveOffhandWeapon() && offtime < basetime)
- {
- float percent20 = pVictim->GetAttackTime(OFF_ATTACK)*0.20;
- float percent60 = 3*percent20;
- // set to 20% if in range 20%...20+40% of full time
- if(offtime > percent20 && offtime <= percent60)
- {
- pVictim->setAttackTimer(OFF_ATTACK,uint32(percent20));
- }
- // decrease at %40 from full time
- else if(offtime > percent60)
- {
- offtime -= 2*percent20;
- pVictim->setAttackTimer(OFF_ATTACK,uint32(offtime));
- }
- // ELSE not changed
- }
- else
- {
- float percent20 = pVictim->GetAttackTime(BASE_ATTACK)*0.20;
- float percent60 = 3*percent20;
- // set to 20% if in range 20%...20+40% of full time
- if(basetime > percent20 && basetime <= percent60)
- {
- pVictim->setAttackTimer(BASE_ATTACK,uint32(percent20));
- }
- // decrease at %40 from full time
- else if(basetime > percent60)
- {
- basetime -= 2*percent20;
- pVictim->setAttackTimer(BASE_ATTACK,uint32(basetime));
- }
- // ELSE not changed
- }
- }
-
- if(pVictim->GetTypeId() == TYPEID_PLAYER)
- {
- // Update victim defense ?
- ((Player*)pVictim)->UpdateDefense();
-
- // random durability for main hand weapon (PARRY)
- if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_PARRY)))
- ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_MAINHAND);
- }
-
- pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED);
-
- if (pVictim->getClass() == CLASS_HUNTER)
- {
- pVictim->ModifyAuraState(AURA_STATE_HUNTER_PARRY,true);
- pVictim->StartReactiveTimer( REACTIVE_HUNTER_PARRY );
- }
- else
- {
- pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true);
- pVictim->StartReactiveTimer( REACTIVE_DEFENSE );
- }
-
- CastMeleeProcDamageAndSpell(pVictim, 0, damageSchoolMask, attType, outcome, spellCasted, isTriggeredSpell);
- return;
- }
- case MELEE_HIT_DODGE:
- {
- if(attType == RANGED_ATTACK) //range attack - no dodge
- {
- outcome = MELEE_HIT_NORMAL;
- break;
- }
-
- cleanDamage->damage += *damage;
- *damage = 0;
- *victimState = VICTIMSTATE_DODGE;
-
- if(pVictim->GetTypeId() == TYPEID_PLAYER)
- ((Player*)pVictim)->UpdateDefense();
-
- pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED);
-
- if (pVictim->getClass() != CLASS_ROGUE) // Riposte
- {
- pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true);
- pVictim->StartReactiveTimer( REACTIVE_DEFENSE );
- }
-
- // Overpower
- if (GetTypeId() == TYPEID_PLAYER && getClass() == CLASS_WARRIOR)
- {
- ((Player*)this)->AddComboPoints(pVictim, 1);
- StartReactiveTimer( REACTIVE_OVERPOWER );
- }
-
- CastMeleeProcDamageAndSpell(pVictim, 0, damageSchoolMask, attType, outcome, spellCasted, isTriggeredSpell);
- return;
- }
- case MELEE_HIT_BLOCK:
- {
- *blocked_amount = pVictim->GetShieldBlockValue();
-
- if (pVictim->GetUnitBlockChance())
- pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYSHIELD);
- else
- pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED);
-
- //Only set VICTIMSTATE_BLOCK on a full block
- if (*blocked_amount >= uint32(*damage))
- {
- *victimState = VICTIMSTATE_BLOCKS;
- *blocked_amount = uint32(*damage);
- }
-
- if(pVictim->GetTypeId() == TYPEID_PLAYER)
- {
- // Update defense
- ((Player*)pVictim)->UpdateDefense();
-
- // random durability for main hand weapon (BLOCK)
- if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_BLOCK)))
- ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_OFFHAND);
- }
-
- pVictim->ModifyAuraState(AURA_STATE_DEFENSE,true);
- pVictim->StartReactiveTimer( REACTIVE_DEFENSE );
-
- break;
- }
- case MELEE_HIT_GLANCING:
- {
- int32 leveldif = int32(pVictim->getLevel()) - int32(getLevel());
- if (leveldif > 3) leveldif = 3;
- *damage *= (1 - leveldif * 0.1f);
- cleanDamage->damage = *damage;
- *hitInfo |= HITINFO_GLANCING;
- break;
- }
- case MELEE_HIT_CRUSHING:
- {
- // 150% normal damage
- *damage += (*damage / 2);
- cleanDamage->damage = *damage;
- *hitInfo |= HITINFO_CRUSHING;
- // TODO: victimState, victim animation?
- break;
- }
- default:
- break;
- }
-
- // apply melee damage bonus and absorb only if base damage not fully blocked to prevent negative damage or damage with full block
- if(*victimState != VICTIMSTATE_BLOCKS)
- {
- MeleeDamageBonus(pVictim, damage,attType,spellCasted);
- CalcAbsorbResist(pVictim, damageSchoolMask, DIRECT_DAMAGE, *damage-*blocked_amount, absorbDamage, resistDamage);
- }
-
- if (*absorbDamage) *hitInfo |= HITINFO_ABSORB;
- if (*resistDamage) *hitInfo |= HITINFO_RESIST;
-
- cleanDamage->damage += *blocked_amount;
-
- if (*damage <= *absorbDamage + *resistDamage + *blocked_amount)
- {
- //*hitInfo = 0x00010020;
- //*hitInfo |= HITINFO_SWINGNOHITSOUND;
- //*damageType = 0;
- CastMeleeProcDamageAndSpell(pVictim, 0, damageSchoolMask, attType, outcome, spellCasted, isTriggeredSpell);
- return;
- }
-
- // update at damage Judgement aura duration that applied by attacker at victim
- if(*damage)
- {
- AuraMap const& vAuras = pVictim->GetAuras();
- for(AuraMap::const_iterator itr = vAuras.begin(); itr != vAuras.end(); ++itr)
- {
- SpellEntry const *spellInfo = (*itr).second->GetSpellProto();
- if( (spellInfo->AttributesEx3 & 0x40000) && spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN &&
- ((*itr).second->GetCasterGUID() == GetGUID() && (!spellCasted || spellCasted->Id == 35395)) )
- {
- (*itr).second->SetAuraDuration((*itr).second->GetAuraMaxDuration());
- (*itr).second->UpdateAuraDuration();
- }
- }
- }
-
- CastMeleeProcDamageAndSpell(pVictim, (*damage - *absorbDamage pVictim->SpellNonMeleeDamageLog(this, (*i)->GetId(), (*i)->GetModifier()->m_amount, false, false);eld
- // yet another hack to fix crashes related to the aura getting removed during iteration
- std::set<Aura*> alreadyDone;
- uint32 removedAuras = pVictim->m_removedAuras;
- AuraList const& vDamageShields = pVictim->GetAurasByType(SPELL_AURA_DAMAGE_SHIELD);
- for(AuraList::const_iterator i = vDamageShields.begin(), next = vDamageShields.begin(); i != vDamageShields.end(); i = next)
- {
- ++next;
- if (alreadyDone.find(*i) == alreadyDone.end())
- {
- alreadyDone.insert(*i);
- pVictim->SpellNonMeleeDamageLog(this, (*i)->GetId(), (*i)->GetModifierValue(), false, false);
- if (pVictim->m_removedAuras > removedAuras)
- {
- removedAuras = pVictim->m_removedAuras;
- next = vDamageShields.begin();
- }
- }
- }
-}*/
-
void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool extra )
{
if(hasUnitState(UNIT_STAT_CANNOT_AUTOATTACK) || HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED) )
@@ -2731,67 +2230,6 @@ void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool ex
}
}
-/*
-MeleeHitOutcome Unit::RollPhysicalOutcomeAgainst (Unit const *pVictim, WeaponAttackType attType, SpellEntry const *spellInfo)
-{
- // Miss chance based on melee
- float miss_chance = MeleeMissChanceCalc(pVictim, attType);
-
- // Critical hit chance
- float crit_chance = GetUnitCriticalChance(attType, pVictim);
- // this is to avoid compiler issue when declaring variables inside if
- float block_chance, parry_chance, dodge_chance;
-
- // cannot be dodged/parried/blocked
- if(spellInfo->Attributes & SPELL_ATTR_IMPOSSIBLE_DODGE_PARRY_BLOCK)
- {
- block_chance = 0.0f;
- parry_chance = 0.0f;
- dodge_chance = 0.0f;
- }
- else
- {
- // parry can be avoided only by some abilities
- parry_chance = pVictim->GetUnitParryChance();
- // block might be bypassed by it as well
- block_chance = pVictim->GetUnitBlockChance();
- // stunned target cannot dodge and this is check in GetUnitDodgeChance()
- dodge_chance = pVictim->GetUnitDodgeChance();
- }
-
- // Only players can have Talent&Spell bonuses
- if (GetTypeId() == TYPEID_PLAYER)
- {
- // Increase from SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL aura
- crit_chance += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL, spellInfo->SchoolMask);
-
- if( dodge_chance != 0.0f ) // if dodge chance is already 0, ignore talents for speed
- {
- AuraList const& mCanNotBeDodge = GetAurasByType(SPELL_AURA_IGNORE_COMBAT_RESULT);
- for(AuraList::const_iterator i = mCanNotBeDodge.begin(); i != mCanNotBeDodge.end(); ++i)
- {
- // can't be dodged rogue finishing move
- if((*i)->GetModifier()->m_miscvalue == VICTIMSTATE_DODGE)
- {
- if(spellInfo->SpellFamilyName==SPELLFAMILY_ROGUE && (spellInfo->SpellFamilyFlags & SPELLFAMILYFLAG_ROGUE__FINISHING_MOVE))
- {
- dodge_chance = 0.0f;
- break;
- }
- }
- }
- }
- }
-
- // Spellmods
- if(Player* modOwner = GetSpellModOwner())
- modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CRITICAL_CHANCE, crit_chance);
-
- DEBUG_LOG("PHYSICAL OUTCOME: miss %f crit %f dodge %f parry %f block %f",miss_chance,crit_chance,dodge_chance,parry_chance, block_chance);
-
- return RollMeleeOutcomeAgainst(pVictim, attType, int32(crit_chance*100), int32(miss_chance*100),int32(dodge_chance*100),int32(parry_chance*100),int32(block_chance*100), true);
-}*/
-
MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(const Unit *pVictim, WeaponAttackType attType) const
{
// This is only wrapper
@@ -2811,10 +2249,10 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(const Unit *pVictim, WeaponAttackT
// Useful if want to specify crit & miss chances for melee, else it could be removed
DEBUG_LOG("MELEE OUTCOME: miss %f crit %f dodge %f parry %f block %f", miss_chance,crit_chance,dodge_chance,parry_chance,block_chance);
- return RollMeleeOutcomeAgainst(pVictim, attType, int32(crit_chance*100), int32(miss_chance*100), int32(dodge_chance*100),int32(parry_chance*100),int32(block_chance*100), false);
+ return RollMeleeOutcomeAgainst(pVictim, attType, int32(crit_chance*100), int32(miss_chance*100), int32(dodge_chance*100),int32(parry_chance*100),int32(block_chance*100));
}
-MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType, int32 crit_chance, int32 miss_chance, int32 dodge_chance, int32 parry_chance, int32 block_chance, bool SpellCasted ) const
+MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType, int32 crit_chance, int32 miss_chance, int32 dodge_chance, int32 parry_chance, int32 block_chance) const
{
if(pVictim->GetTypeId()==TYPEID_UNIT && ((Creature*)pVictim)->IsInEvadeMode())
return MELEE_HIT_EVADE;
@@ -2827,7 +2265,6 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttack
// bonus from skills is 0.04%
int32 skillBonus = 4 * ( attackerWeaponSkill - victimMaxSkillValueForLevel );
- int32 skillBonus2 = 4 * ( attackerMaxSkillValueForLevel - victimDefenseSkill );
int32 sum = 0, tmp = 0;
int32 roll = urand (0, 10000);
@@ -2865,6 +2302,7 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttack
// Modify dodge chance by attacker SPELL_AURA_MOD_COMBAT_RESULT_CHANCE
dodge_chance+= GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_COMBAT_RESULT_CHANCE, VICTIMSTATE_DODGE);
+ dodge_chance = int32 (float (dodge_chance) * GetTotalAuraMultiplier(SPELL_AURA_MOD_ENEMY_DODGE));
tmp = dodge_chance;
if ( (tmp > 0) // check if unit _can_ dodge
@@ -2908,16 +2346,6 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttack
&& ((tmp -= skillBonus) > 0)
&& (roll < (sum += tmp)))
{
- // Critical chance
- tmp = crit_chance + skillBonus2;
- if ( GetTypeId() == TYPEID_PLAYER && SpellCasted && tmp > 0 )
- {
- if ( roll_chance_i(tmp/100))
- {
- DEBUG_LOG ("RollMeleeOutcomeAgainst: BLOCKED CRIT");
- return MELEE_HIT_BLOCK_CRIT;
- }
- }
DEBUG_LOG ("RollMeleeOutcomeAgainst: BLOCK <%d, %d)", sum-tmp, sum);
return MELEE_HIT_BLOCK;
}
@@ -2925,7 +2353,7 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttack
}
// Critical chance
- tmp = crit_chance + skillBonus2;
+ tmp = crit_chance;
if (tmp > 0 && roll < (sum += tmp))
{
@@ -2934,7 +2362,7 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttack
}
// Max 40% chance to score a glancing blow against mobs that are higher level (can do only players and pets and not with ranged weapon)
- if( attType != RANGED_ATTACK && !SpellCasted &&
+ if( attType != RANGED_ATTACK &&
(GetTypeId() == TYPEID_PLAYER || ((Creature*)this)->isPet()) &&
pVictim->GetTypeId() != TYPEID_PLAYER && !((Creature*)pVictim)->isPet() &&
getLevel() < pVictim->getLevelForTarget(this) )
@@ -2953,10 +2381,14 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttack
}
}
- if(GetTypeId()!=TYPEID_PLAYER && !(((Creature*)this)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_CRUSH) && !((Creature*)this)->isPet() && !SpellCasted /*Only autoattack can be crushing blow*/ )
+ // mobs can score crushing blows if they're 4 or more levels above victim
+ if (getLevelForTarget(pVictim) >= pVictim->getLevelForTarget(this) + 4 &&
+ // can be from by creature (if can) or from controlled player that considered as creature
+ (GetTypeId()!=TYPEID_PLAYER && !((Creature*)this)->isPet() &&
+ !(((Creature*)this)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_CRUSH) ||
+ GetTypeId()==TYPEID_PLAYER && GetCharmerOrOwnerGUID()))
{
- // mobs can score crushing blows if they're 3 or more levels above victim
- // or when their weapon skill is 15 or more above victim's defense skill
+ // 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
@@ -3066,6 +2498,23 @@ bool Unit::isSpellBlocked(Unit *pVictim, SpellEntry const *spellProto, WeaponAtt
{
if (pVictim->HasInArc(M_PI,this))
{
+ /* Currently not exist spells with ignore block
+ // Ignore combat result aura (parry/dodge check on prepare)
+ AuraList const& ignore = GetAurasByType(SPELL_AURA_IGNORE_COMBAT_RESULT);
+ for(AuraList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
+ {
+ if (!(*i)->isAffectedOnSpell(spellProto))
+ continue;
+ if ((*i)->GetModifier()->m_miscvalue == )
+ return false;
+ }
+ */
+
+ // Check creatures flags_extra for disable block
+ if(pVictim->GetTypeId()==TYPEID_UNIT &&
+ ((Creature*)pVictim)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_BLOCK )
+ return false;
+
float blockChance = GetUnitBlockChance();
blockChance += (GetWeaponSkillValue(attackType) - pVictim->GetMaxSkillValueForLevel() )*0.04;
if (roll_chance_f(blockChance))
@@ -3074,24 +2523,27 @@ bool Unit::isSpellBlocked(Unit *pVictim, SpellEntry const *spellProto, WeaponAtt
return false;
}
+bool Unit::isBlockCritical()
+{
+ if (roll_chance_i(GetTotalAuraModifier(SPELL_AURA_MOD_BLOCK_CRIT_CHANCE)))
+ return true;
+ return false;
+}
+
// 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 *pVictim, WeaponAttackType attType, int32 skillDiff, uint32 spellId) const
+/*float Unit::MeleeSpellMissChance(Unit *pVictim, WeaponAttackType attType, int32 skillDiff, SpellEntry const *spell)
{
// Calculate hit chance (more correct for chance mod)
int32 HitChance;
// PvP - PvE melee chances
- /*int32 lchance = pVictim->GetTypeId() == TYPEID_PLAYER ? 5 : 7;
+ int32 lchance = pVictim->GetTypeId() == TYPEID_PLAYER ? 5 : 7;
int32 leveldif = pVictim->getLevelForTarget(this) - getLevelForTarget(pVictim);
if(leveldif < 3)
HitChance = 95 - leveldif;
else
- HitChance = 93 - (leveldif - 2) * lchance;*/
- if (spellId || attType == RANGED_ATTACK || !haveOffhandWeapon())
- HitChance = 95.0f;
- else
- HitChance = 76.0f;
+ HitChance = 93 - (leveldif - 2) * lchance;
// Hit chance depends from victim auras
if(attType == RANGED_ATTACK)
@@ -3100,11 +2552,8 @@ float Unit::MeleeSpellMissChance(const Unit *pVictim, WeaponAttackType attType,
HitChance += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE);
// Spellmod from SPELLMOD_RESIST_MISS_CHANCE
- if(spellId)
- {
- if(Player *modOwner = GetSpellModOwner())
- modOwner->ApplySpellMod(spellId, SPELLMOD_RESIST_MISS_CHANCE, HitChance);
- }
+ if(Player *modOwner = GetSpellModOwner())
+ modOwner->ApplySpellMod(spell->Id, SPELLMOD_RESIST_MISS_CHANCE, HitChance);
// Miss = 100 - hit
float miss_chance= 100.0f - HitChance;
@@ -3116,12 +2565,7 @@ float Unit::MeleeSpellMissChance(const Unit *pVictim, WeaponAttackType attType,
miss_chance -= m_modMeleeHitChance;
// bonus from skills is 0.04%
- //miss_chance -= skillDiff * 0.04f;
- int32 diff = -skillDiff;
- if(pVictim->GetTypeId()==TYPEID_PLAYER)
- miss_chance += diff > 0 ? diff * 0.04 : diff * 0.02;
- else
- miss_chance += diff > 10 ? 2 + (diff - 10) * 0.4 : diff * 0.1;
+ miss_chance -= skillDiff * 0.04f;
// Limit miss chance from 0 to 60%
if (miss_chance < 0.0f)
@@ -3129,7 +2573,7 @@ float Unit::MeleeSpellMissChance(const Unit *pVictim, WeaponAttackType attType,
if (miss_chance > 60.0f)
return 60.0f;
return miss_chance;
-}
+}*/
// Melee based spells hit result calculations
SpellMissInfo Unit::MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell)
@@ -3145,68 +2589,107 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell)
int32 fullSkillDiff = attackerWeaponSkill - int32(pVictim->GetDefenseSkillValue(this));
uint32 roll = urand (0, 10000);
- uint32 missChance = uint32(MeleeSpellMissChance(pVictim, attType, fullSkillDiff, spell->Id)*100.0f);
+ uint32 missChance = uint32(MeleeSpellMissChance(pVictim, attType, fullSkillDiff, spell->Id)*100.0f);
// Roll miss
uint32 tmp = missChance;
if (roll < tmp)
return SPELL_MISS_MISS;
+ // Chance resist mechanic (select max value from every mechanic spell effect)
+ int32 resist_mech = 0;
+ // Get effects mechanic and chance
+ for(int eff = 0; eff < 3; ++eff)
+ {
+ int32 effect_mech = GetEffectMechanic(spell, eff);
+ if (effect_mech)
+ {
+ int32 temp = pVictim->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_MECHANIC_RESISTANCE, effect_mech);
+ if (resist_mech < temp*100)
+ resist_mech = temp*100;
+ }
+ }
+ // Roll chance
+ tmp += resist_mech;
+ if (roll < tmp)
+ return SPELL_MISS_RESIST;
+
+ bool canDodge = true;
+ bool canParry = true;
+
// Same spells cannot be parry/dodge
if (spell->Attributes & SPELL_ATTR_IMPOSSIBLE_DODGE_PARRY_BLOCK)
return SPELL_MISS_NONE;
- // Ranged attack can`t miss too
+ // Ranged attack cannot be parry/dodge
if (attType == RANGED_ATTACK)
return SPELL_MISS_NONE;
- bool attackFromBehind = !pVictim->HasInArc(M_PI,this);
-
- // Roll dodge
- int32 dodgeChance = int32(pVictim->GetUnitDodgeChance()*100.0f) - skillDiff * 4;
- // Reduce enemy dodge chance by SPELL_AURA_MOD_COMBAT_RESULT_CHANCE
- dodgeChance+= GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_COMBAT_RESULT_CHANCE, VICTIMSTATE_DODGE);
-
- // Reduce dodge chance by attacker expertise rating
- if (GetTypeId() == TYPEID_PLAYER)
- dodgeChance-=int32(((Player*)this)->GetExpertiseDodgeOrParryReduction(attType) * 100.0f);
- if (dodgeChance < 0)
- dodgeChance = 0;
-
- // Can`t dodge from behind in PvP (but its possible in PvE)
- if (GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER && attackFromBehind)
- dodgeChance = 0;
-
- // Rogue talent`s cant be dodged
- AuraList const& mCanNotBeDodge = GetAurasByType(SPELL_AURA_IGNORE_COMBAT_RESULT);
- for(AuraList::const_iterator i = mCanNotBeDodge.begin(); i != mCanNotBeDodge.end(); ++i)
+ // Check for attack from behind
+ if (!pVictim->HasInArc(M_PI,this))
{
- if((*i)->GetModifier()->m_miscvalue == VICTIMSTATE_DODGE) // can't be dodged rogue finishing move
+ // Can`t dodge from behind in PvP (but its possible in PvE)
+ if (GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER)
+ canDodge = false;
+ // Can`t parry
+ canParry = false;
+ }
+ // Check creatures flags_extra for disable parry
+ if(pVictim->GetTypeId()==TYPEID_UNIT)
+ {
+ uint32 flagEx = ((Creature*)pVictim)->GetCreatureInfo()->flags_extra;
+ if( flagEx & CREATURE_FLAG_EXTRA_NO_PARRY )
+ canParry = false;
+ }
+ // Ignore combat result aura
+ AuraList const& ignore = GetAurasByType(SPELL_AURA_IGNORE_COMBAT_RESULT);
+ for(AuraList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
+ {
+ if (!(*i)->isAffectedOnSpell(spell))
+ continue;
+ switch((*i)->GetModifier()->m_miscvalue)
{
- if(spell->SpellFamilyName==SPELLFAMILY_ROGUE && (spell->SpellFamilyFlags & SPELLFAMILYFLAG_ROGUE__FINISHING_MOVE))
- {
- dodgeChance = 0;
+ case MELEE_HIT_DODGE: canDodge = false; break;
+ case MELEE_HIT_BLOCK: break; // Block check in hit step
+ case MELEE_HIT_PARRY: canParry = false; break;
+ default:
+ DEBUG_LOG("Spell %u SPELL_AURA_IGNORE_COMBAT_RESULT have unhandled state %d", (*i)->GetId(), (*i)->GetModifier()->m_miscvalue);
break;
- }
}
}
- tmp += dodgeChance;
- if (roll < tmp)
- return SPELL_MISS_DODGE;
+ if (canDodge)
+ {
+ // Roll dodge
+ int32 dodgeChance = int32(pVictim->GetUnitDodgeChance()*100.0f) - skillDiff * 4;
+ // Reduce enemy dodge chance by SPELL_AURA_MOD_COMBAT_RESULT_CHANCE
+ dodgeChance+= GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_COMBAT_RESULT_CHANCE, VICTIMSTATE_DODGE);
+ dodgeChance = int32 (float (dodgeChance) * GetTotalAuraMultiplier(SPELL_AURA_MOD_ENEMY_DODGE));
+ // Reduce dodge chance by attacker expertise rating
+ if (GetTypeId() == TYPEID_PLAYER)
+ dodgeChance-=int32(((Player*)this)->GetExpertiseDodgeOrParryReduction(attType) * 100.0f);
+ if (dodgeChance < 0)
+ dodgeChance = 0;
- // Roll parry
- int32 parryChance = int32(pVictim->GetUnitParryChance()*100.0f) - skillDiff * 4;
- // Reduce parry chance by attacker expertise rating
- if (GetTypeId() == TYPEID_PLAYER)
- parryChance-=int32(((Player*)this)->GetExpertiseDodgeOrParryReduction(attType) * 100.0f);
- // Can`t parry from behind
- if (parryChance < 0 || attackFromBehind)
- parryChance = 0;
+ tmp += dodgeChance;
+ if (roll < tmp)
+ return SPELL_MISS_DODGE;
+ }
- tmp += parryChance;
- if (roll < tmp)
- return SPELL_MISS_PARRY;
+ if (canParry)
+ {
+ // Roll parry
+ int32 parryChance = int32(pVictim->GetUnitParryChance()*100.0f) - skillDiff * 4;
+ // Reduce parry chance by attacker expertise rating
+ if (GetTypeId() == TYPEID_PLAYER)
+ parryChance-=int32(((Player*)this)->GetExpertiseDodgeOrParryReduction(attType) * 100.0f);
+ if (parryChance < 0)
+ parryChance = 0;
+
+ tmp += parryChance;
+ if (roll < tmp)
+ return SPELL_MISS_PARRY;
+ }
return SPELL_MISS_NONE;
}
@@ -3297,8 +2780,8 @@ SpellMissInfo Unit::SpellHitResult(Unit *pVictim, SpellEntry const *spell, bool
if (spell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY)
return SPELL_MISS_NONE;
- // Check for immune (use charges)
- if (pVictim->IsImmunedToSpell(spell,true))
+ // Check for immune
+ if (pVictim->IsImmunedToSpell(spell))
return SPELL_MISS_IMMUNE;
// All positive spells can`t miss
@@ -3307,8 +2790,8 @@ SpellMissInfo Unit::SpellHitResult(Unit *pVictim, SpellEntry const *spell, bool
&&(!IsHostileTo(pVictim))) //prevent from affecting enemy by "positive" spell
return SPELL_MISS_NONE;
- // Check for immune (use charges)
- if (pVictim->IsImmunedToDamage(GetSpellSchoolMask(spell),true))
+ // Check for immune
+ if (pVictim->IsImmunedToDamage(GetSpellSchoolMask(spell)))
return SPELL_MISS_IMMUNE;
if(this == pVictim)
@@ -3321,7 +2804,7 @@ SpellMissInfo Unit::SpellHitResult(Unit *pVictim, SpellEntry const *spell, bool
Unit::AuraList const& mReflectSpellsSchool = pVictim->GetAurasByType(SPELL_AURA_REFLECT_SPELLS_SCHOOL);
for(Unit::AuraList::const_iterator i = mReflectSpellsSchool.begin(); i != mReflectSpellsSchool.end(); ++i)
if((*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spell))
- reflectchance = (*i)->GetModifierValue();
+ reflectchance += (*i)->GetModifier()->m_amount;
if (reflectchance > 0 && roll_chance_i(reflectchance))
{
// Start triggers for remove charges if need (trigger only for victim, and mark as active spell)
@@ -3496,7 +2979,7 @@ float Unit::GetUnitBlockChance() const
Player const* player = (Player const*)this;
if(player->CanBlock() )
{
- Item *tmpitem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
+ Item *tmpitem = player->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
if(tmpitem && !tmpitem->IsBroken() && tmpitem->GetProto()->Block)
return GetFloatValue(PLAYER_BLOCK_PERCENTAGE);
}
@@ -3562,6 +3045,9 @@ float Unit::GetUnitCriticalChance(WeaponAttackType attackType, const Unit *pVict
crit -= ((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_MELEE);
}
+ // Apply crit chance from defence skill
+ crit += (int32(GetMaxSkillValueForLevel(pVictim)) - int32(pVictim->GetDefenseSkillValue(this))) * 0.04f;
+
if (crit < 0.0f)
crit = 0.0f;
return crit;
@@ -3693,7 +3179,7 @@ void Unit::_UpdateAutoRepeatSpell()
if ( (GetTypeId() == TYPEID_PLAYER && ((Player*)this)->isMoving()) || IsNonMeleeSpellCasted(false,false,true) )
{
// cancel wand shoot
- if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Category == 351)
+ if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id != SPELL_ID_AUTOSHOT)
InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
m_AutoRepeatFirstCast = true;
return;
@@ -3746,7 +3232,7 @@ void Unit::SetCurrentCastedSpell( Spell * pSpell )
if ( m_currentSpells[CURRENT_AUTOREPEAT_SPELL] )
{
// break autorepeat if not Auto Shot
- if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Category == 351)
+ if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id != SPELL_ID_AUTOSHOT)
InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
m_AutoRepeatFirstCast = true;
}
@@ -3761,7 +3247,7 @@ void Unit::SetCurrentCastedSpell( Spell * pSpell )
// it also does break autorepeat if not Auto Shot
if ( m_currentSpells[CURRENT_AUTOREPEAT_SPELL] &&
- m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Category == 351 )
+ m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id != SPELL_ID_AUTOSHOT )
InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
addUnitState(UNIT_STAT_CASTING);
} break;
@@ -3769,7 +3255,7 @@ void Unit::SetCurrentCastedSpell( Spell * pSpell )
case CURRENT_AUTOREPEAT_SPELL:
{
// only Auto Shoot does not break anything
- if (pSpell->m_spellInfo->Category == 351)
+ if (pSpell->m_spellInfo->Id != SPELL_ID_AUTOSHOT)
{
// generic autorepeats break generic non-delayed and channeled non-delayed spells
InterruptSpell(CURRENT_GENERIC_SPELL,false);
@@ -3932,13 +3418,23 @@ void Unit::DeMorph()
SetDisplayId(GetNativeDisplayId());
}
+bool Unit::HasAuraTypeWithMiscvalue(AuraType auratype, uint32 miscvalue) const
+{
+ AuraList const& mTotalAuraList = GetAurasByType(auratype);
+ for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
+ if (miscvalue == (*i)->GetModifier()->m_miscvalue)
+ return true;
+
+ return false;
+}
+
int32 Unit::GetTotalAuraModifier(AuraType auratype) const
{
int32 modifier = 0;
AuraList const& mTotalAuraList = GetAurasByType(auratype);
for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
- modifier += (*i)->GetModifierValue();
+ modifier += (*i)->GetModifier()->m_amount;
return modifier;
}
@@ -3949,7 +3445,7 @@ float Unit::GetTotalAuraMultiplier(AuraType auratype) const
AuraList const& mTotalAuraList = GetAurasByType(auratype);
for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
- multiplier *= (100.0f + (*i)->GetModifierValue())/100.0f;
+ multiplier *= (100.0f + (*i)->GetModifier()->m_amount)/100.0f;
return multiplier;
}
@@ -3960,11 +3456,8 @@ int32 Unit::GetMaxPositiveAuraModifier(AuraType auratype) const
AuraList const& mTotalAuraList = GetAurasByType(auratype);
for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
- {
- int32 amount = (*i)->GetModifierValue();
- if (amount > modifier)
- modifier = amount;
- }
+ if ((*i)->GetModifier()->m_amount > modifier)
+ modifier = (*i)->GetModifier()->m_amount;
return modifier;
}
@@ -3975,11 +3468,8 @@ int32 Unit::GetMaxNegativeAuraModifier(AuraType auratype) const
AuraList const& mTotalAuraList = GetAurasByType(auratype);
for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
- {
- int32 amount = (*i)->GetModifierValue();
- if (amount < modifier)
- modifier = amount;
- }
+ if ((*i)->GetModifier()->m_amount < modifier)
+ modifier = (*i)->GetModifier()->m_amount;
return modifier;
}
@@ -3993,7 +3483,7 @@ int32 Unit::GetTotalAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask)
{
Modifier* mod = (*i)->GetModifier();
if (mod->m_miscvalue & misc_mask)
- modifier += (*i)->GetModifierValue();
+ modifier += mod->m_amount;
}
return modifier;
}
@@ -4007,7 +3497,7 @@ float Unit::GetTotalAuraMultiplierByMiscMask(AuraType auratype, uint32 misc_mask
{
Modifier* mod = (*i)->GetModifier();
if (mod->m_miscvalue & misc_mask)
- multiplier *= (100.0f + (*i)->GetModifierValue())/100.0f;
+ multiplier *= (100.0f + mod->m_amount)/100.0f;
}
return multiplier;
}
@@ -4020,9 +3510,8 @@ int32 Unit::GetMaxPositiveAuraModifierByMiscMask(AuraType auratype, uint32 misc_
for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
{
Modifier* mod = (*i)->GetModifier();
- int32 amount = (*i)->GetModifierValue();
- if (mod->m_miscvalue & misc_mask && amount > modifier)
- modifier = amount;
+ if (mod->m_miscvalue & misc_mask && mod->m_amount > modifier)
+ modifier = mod->m_amount;
}
return modifier;
@@ -4036,9 +3525,8 @@ int32 Unit::GetMaxNegativeAuraModifierByMiscMask(AuraType auratype, uint32 misc_
for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
{
Modifier* mod = (*i)->GetModifier();
- int32 amount = (*i)->GetModifierValue();
- if (mod->m_miscvalue & misc_mask && amount < modifier)
- modifier = amount;
+ if (mod->m_miscvalue & misc_mask && mod->m_amount < modifier)
+ modifier = mod->m_amount;
}
return modifier;
@@ -4053,7 +3541,7 @@ int32 Unit::GetTotalAuraModifierByMiscValue(AuraType auratype, int32 misc_value)
{
Modifier* mod = (*i)->GetModifier();
if (mod->m_miscvalue == misc_value)
- modifier += (*i)->GetModifierValue();
+ modifier += mod->m_amount;
}
return modifier;
}
@@ -4067,7 +3555,7 @@ float Unit::GetTotalAuraMultiplierByMiscValue(AuraType auratype, int32 misc_valu
{
Modifier* mod = (*i)->GetModifier();
if (mod->m_miscvalue == misc_value)
- multiplier *= (100.0f + (*i)->GetModifierValue())/100.0f;
+ multiplier *= (100.0f + mod->m_amount)/100.0f;
}
return multiplier;
}
@@ -4080,9 +3568,8 @@ int32 Unit::GetMaxPositiveAuraModifierByMiscValue(AuraType auratype, int32 misc_
for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
{
Modifier* mod = (*i)->GetModifier();
- int32 amount = (*i)->GetModifierValue();
- if (mod->m_miscvalue == misc_value && amount > modifier)
- modifier = amount;
+ if (mod->m_miscvalue == misc_value && mod->m_amount > modifier)
+ modifier = mod->m_amount;
}
return modifier;
@@ -4096,9 +3583,8 @@ int32 Unit::GetMaxNegativeAuraModifierByMiscValue(AuraType auratype, int32 misc_
for(AuraList::const_iterator i = mTotalAuraList.begin();i != mTotalAuraList.end(); ++i)
{
Modifier* mod = (*i)->GetModifier();
- int32 amount = (*i)->GetModifierValue();
- if (mod->m_miscvalue == misc_value && amount < modifier)
- modifier = amount;
+ if (mod->m_miscvalue == misc_value && mod->m_amount < modifier)
+ modifier = mod->m_amount;
}
return modifier;
@@ -4134,57 +3620,51 @@ bool Unit::AddAura(Aura *Aur)
// passive and persistent auras can stack with themselves any number of times
if (!Aur->IsPassive() && !Aur->IsPersistent())
{
- // replace aura if next will > spell StackAmount
- if(aurSpellInfo->StackAmount)
+ for(AuraMap::iterator i2 = m_Auras.lower_bound(spair); i2 != m_Auras.upper_bound(spair); ++i2)
{
- Aur->SetStackAmount(i->second->GetStackAmount());
- if(Aur->GetStackAmount() < aurSpellInfo->StackAmount)
- Aur->SetStackAmount(Aur->GetStackAmount()+1);
- RemoveAura(i,AURA_REMOVE_BY_STACK);
- }
- // if StackAmount==0 not allow auras from same caster
- else
- {
- for(AuraMap::iterator i2 = m_Auras.lower_bound(spair); i2 != m_Auras.upper_bound(spair); ++i2)
+ if(i2->second->GetCasterGUID()==Aur->GetCasterGUID())
{
- if(i2->second->GetCasterGUID()==Aur->GetCasterGUID())
- {
- // can be only single (this check done at _each_ aura add
- RemoveAura(i2,AURA_REMOVE_BY_STACK);
- break;
- }
-
- bool stop = false;
- switch(aurSpellInfo->EffectApplyAuraName[Aur->GetEffIndex()])
+ // Aura can stack on self -> Stack it;
+ if(aurSpellInfo->StackAmount)
{
- // DoT/HoT/etc
- case SPELL_AURA_PERIODIC_DAMAGE: // allow stack
- case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
- case SPELL_AURA_PERIODIC_LEECH:
- case SPELL_AURA_PERIODIC_HEAL:
- case SPELL_AURA_OBS_MOD_HEALTH:
- case SPELL_AURA_PERIODIC_MANA_LEECH:
- case SPELL_AURA_PERIODIC_ENERGIZE:
- case SPELL_AURA_OBS_MOD_MANA:
- case SPELL_AURA_POWER_BURN_MANA:
- break;
- default: // not allow
- // can be only single (this check done at _each_ aura add
- RemoveAura(i2,AURA_REMOVE_BY_STACK);
- stop = true;
- break;
+ i2->second->modStackAmount(1);
+ delete Aur;
+ return false;
}
+ // can be only single (this check done at _each_ aura add
+ RemoveAura(i2,AURA_REMOVE_BY_STACK);
+ break;
+ }
- if(stop)
+ bool stop = false;
+ switch(aurSpellInfo->EffectApplyAuraName[Aur->GetEffIndex()])
+ {
+ // DoT/HoT/etc
+ case SPELL_AURA_PERIODIC_DAMAGE: // allow stack
+ case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
+ case SPELL_AURA_PERIODIC_LEECH:
+ case SPELL_AURA_PERIODIC_HEAL:
+ case SPELL_AURA_OBS_MOD_HEALTH:
+ case SPELL_AURA_PERIODIC_MANA_LEECH:
+ case SPELL_AURA_PERIODIC_ENERGIZE:
+ case SPELL_AURA_OBS_MOD_MANA:
+ case SPELL_AURA_POWER_BURN_MANA:
+ break;
+ default: // not allow
+ // can be only single (this check done at _each_ aura add
+ RemoveAura(i2,AURA_REMOVE_BY_STACK);
+ stop = true;
break;
}
+
+ if(stop)
+ break;
}
}
}
- // passive auras stack with all (except passive spell proc auras)
- if ((!Aur->IsPassive() || !IsPassiveStackableSpell(Aur->GetId())) &&
- !(Aur->GetId() == 20584 || Aur->GetId() == 8326))
+ // passive auras not stacable with other ranks
+ if (!IsPassiveSpellStackableWithRanks(aurSpellInfo))
{
if (!RemoveNoStackAurasDueToAura(Aur))
{
@@ -4302,6 +3782,13 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur)
uint32 spellId = Aur->GetId();
uint32 effIndex = Aur->GetEffIndex();
+ // passive spell special case (only non stackable with ranks)
+ if(IsPassiveSpell(spellId))
+ {
+ if(IsPassiveSpellStackableWithRanks(spellProto))
+ return true;
+ }
+
SpellSpecific spellId_spec = GetSpellSpecific(spellId);
AuraMap::iterator i,next;
@@ -4318,9 +3805,11 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur)
uint32 i_spellId = i_spellProto->Id;
+ // early checks that spellId is passive non stackable spell
if(IsPassiveSpell(i_spellId))
{
- if(IsPassiveStackableSpell(i_spellId))
+ // passive non-stackable spells not stackable only for same caster
+ if(Aur->GetCasterGUID()!=i->second->GetCasterGUID())
continue;
// passive non-stackable spells not stackable only with another rank of same spell
@@ -4337,65 +3826,36 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur)
for(int j = 0; j < 3; ++j)
if (i_spellProto->EffectTriggerSpell[j] == spellProto->Id)
is_triggered_by_spell = true;
- if (is_triggered_by_spell) continue;
- for(int j = 0; j < 3; ++j)
- {
- // prevent remove dummy triggered spells at next effect aura add
- switch(spellProto->Effect[j]) // main spell auras added added after triggered spell
- {
- case SPELL_EFFECT_DUMMY:
- switch(spellId)
- {
- case 5420: if(i_spellId==34123) is_triggered_by_spell = true; break;
- }
- break;
- }
+ if (is_triggered_by_spell)
+ continue;
- if(is_triggered_by_spell)
- break;
+ // check if they can stack
+ bool sameCaster = Aur->GetCasterGUID() == (*i).second->GetCasterGUID();
+ if(!spellmgr.IsNoStackSpellDueToSpell(spellId, i_spellId, sameCaster))
+ continue;
- // prevent remove form main spell by triggered passive spells
- switch(i_spellProto->EffectApplyAuraName[j]) // main aura added before triggered spell
- {
- case SPELL_AURA_MOD_SHAPESHIFT:
- switch(i_spellId)
- {
- case 24858: if(spellId==24905) is_triggered_by_spell = true; break;
- case 33891: if(spellId==5420 || spellId==34123) is_triggered_by_spell = true; break;
- case 34551: if(spellId==22688) is_triggered_by_spell = true; break;
- }
- break;
- }
- }
+ //some spells should be not removed by lower rank of them (totem, paladin aura)
+ if (!sameCaster
+ &&(spellProto->Effect[effIndex]==SPELL_EFFECT_APPLY_AREA_AURA_PARTY)
+ &&(spellProto->DurationIndex==21)
+ &&(spellmgr.IsRankSpellDueToSpell(spellProto, i_spellId))
+ &&(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0))
+ return false;
- if(!is_triggered_by_spell)
+ // Its a parent aura (create this aura in ApplyModifier)
+ if ((*i).second->IsInUse())
{
- bool sameCaster = Aur->GetCasterGUID() == (*i).second->GetCasterGUID();
- if( spellmgr.IsNoStackSpellDueToSpell(spellId, i_spellId, sameCaster) )
- {
- //some spells should be not removed by lower rank of them (totem, paladin aura)
- if (!sameCaster
- &&(spellProto->Effect[effIndex]==SPELL_EFFECT_APPLY_AREA_AURA_PARTY)
- &&(spellProto->DurationIndex==21)
- &&(spellmgr.IsRankSpellDueToSpell(spellProto, i_spellId))
- &&(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0))
- return false;
+ sLog.outError("Aura (Spell %u Effect %u) is in process but attempt removed at aura (Spell %u Effect %u) adding, need add stack rule for Unit::RemoveNoStackAurasDueToAura", i->second->GetId(), i->second->GetEffIndex(),Aur->GetId(), Aur->GetEffIndex());
+ continue;
+ }
- // Its a parent aura (create this aura in ApplyModifier)
- if ((*i).second->IsInUse())
- {
- sLog.outError("Aura (Spell %u Effect %u) is in process but attempt removed at aura (Spell %u Effect %u) adding, need add stack rule for Unit::RemoveNoStackAurasDueToAura", i->second->GetId(), i->second->GetEffIndex(),Aur->GetId(), Aur->GetEffIndex());
- continue;
- }
- RemoveAurasDueToSpell(i_spellId);
+ RemoveAurasDueToSpell(i_spellId);
- if( m_Auras.empty() )
- break;
- else
- next = m_Auras.begin();
- }
- }
+ if( m_Auras.empty() )
+ break;
+ else
+ next = m_Auras.begin();
}
return true;
}
@@ -4415,6 +3875,18 @@ void Unit::RemoveAura(uint32 spellId, uint32 effindex, Aura* except)
}
}
+void Unit::RemoveAurasByCasterSpell(uint32 spellId, uint64 casterGUID)
+{
+ for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); )
+ {
+ Aura *aur = iter->second;
+ if (aur->GetId() == spellId && aur->GetCasterGUID() == casterGUID)
+ RemoveAura(iter);
+ else
+ ++iter;
+ }
+}
+
void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler)
{
for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); )
@@ -4424,20 +3896,21 @@ void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit
{
// Custom dispel case
// Unstable Affliction
- if (aur->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (aur->GetSpellProto()->SpellFamilyFlags & 0x010000000000LL))
+ if (aur->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (aur->GetSpellProto()->SpellFamilyFlags[1] & 0x0100))
{
int32 damage = aur->GetModifier()->m_amount*9;
uint64 caster_guid = aur->GetCasterGUID();
// Remove aura
- RemoveAura(iter, AURA_REMOVE_BY_DISPEL);
+ if (iter->second->modStackAmount(-1))
+ RemoveAura(iter, AURA_REMOVE_BY_DISPEL);
// backfire damage and silence
dispeler->CastCustomSpell(dispeler, 31117, &damage, NULL, NULL, true, NULL, NULL,caster_guid);
iter = m_Auras.begin(); // iterator can be invalidate at cast if self-dispel
}
- else
+ else if (iter->second->modStackAmount(-1))
RemoveAura(iter, AURA_REMOVE_BY_DISPEL);
}
else
@@ -4469,7 +3942,8 @@ void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit
stealer->AddAura(new_aur);
// Remove aura as dispel
- RemoveAura(iter, AURA_REMOVE_BY_DISPEL);
+ if (iter->second->modStackAmount(-1))
+ RemoveAura(iter, AURA_REMOVE_BY_DISPEL);
}
else
++iter;
@@ -4507,73 +3981,26 @@ void Unit::RemoveAurasWithDispelType( DispelType type )
}
}
-void Unit::RemoveSingleAuraFromStackByDispel(uint32 spellId)
-{
- for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); )
- {
- Aura *aur = iter->second;
- if (aur->GetId() == spellId)
- {
- if(iter->second->GetStackAmount() > 1)
- {
- // reapply modifier with reduced stack amount
- iter->second->ApplyModifier(false,true);
- iter->second->SetStackAmount(iter->second->GetStackAmount()-1);
- iter->second->ApplyModifier(true,true);
-
- iter->second->UpdateSlotCounterAndDuration();
- return; // not remove aura if stack amount > 1
- }
- else
- RemoveAura(iter,AURA_REMOVE_BY_DISPEL);
- }
- else
- ++iter;
- }
-}
-
void Unit::RemoveSingleAuraFromStack(uint32 spellId, uint32 effindex)
{
AuraMap::iterator iter = m_Auras.find(spellEffectPair(spellId, effindex));
if(iter != m_Auras.end())
{
- if(iter->second->GetStackAmount() > 1)
- {
- // reapply modifier with reduced stack amount
- iter->second->ApplyModifier(false,true);
- iter->second->SetStackAmount(iter->second->GetStackAmount()-1);
- iter->second->ApplyModifier(true,true);
-
- iter->second->UpdateSlotCounterAndDuration();
- return; // not remove aura if stack amount > 1
- }
- RemoveAura(iter);
+ if (iter->second->modStackAmount(-1))
+ RemoveAura(iter);
}
}
-void Unit::RemoveAurasDueToSpell(uint32 spellId, Aura* except)
+void Unit::RemoveSingleSpellAurasFromStack(uint32 spellId)
{
- for (int i = 0; i < 3; ++i)
- RemoveAura(spellId,i,except);
+ for (int i=0; i<3; ++i)
+ RemoveSingleAuraFromStack(spellId, i);
}
-void Unit::RemoveAurasDueToCasterSpell(uint32 spellId, uint64 guid)
+void Unit::RemoveAurasDueToSpell(uint32 spellId, Aura* except)
{
- for (int k=0; k < 3; ++k)
- {
- spellEffectPair spair = spellEffectPair(spellId, k);
- for (AuraMap::iterator iter = m_Auras.lower_bound(spair); iter != m_Auras.upper_bound(spair);)
- {
- if (iter->second->GetCasterGUID() == guid)
- {
- RemoveAura(iter);
- break;
- //iter = m_Auras.upper_bound(spair); // overwrite by more appropriate
- }
- else
- ++iter;
- }
- }
+ for (int i = 0; i < 3; ++i)
+ RemoveAura(spellId,i,except);
}
void Unit::RemoveAurasDueToItemSpell(Item* castItem,uint32 spellId)
@@ -4703,9 +4130,6 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
sLog.outDebug("Aura %u (%u) now is remove mode %d", Aur->GetId(), Aur->GetModifier()->m_auraname, mode);
assert(!Aur->IsInUse());
Aur->ApplyModifier(false,true);
-
- Aur->SetStackAmount(0);
-
Aur->_RemoveAura();
if(mode != AURA_REMOVE_BY_STACK)
@@ -4798,7 +4222,8 @@ void Unit::DelayAura(uint32 spellId, uint32 effindex, int32 delaytime)
iter->second->SetAuraDuration(0);
else
iter->second->SetAuraDuration(iter->second->GetAuraDuration() - delaytime);
- iter->second->UpdateAuraDuration();
+ // update for out of range group members (on 1 slot use)
+ UpdateAuraForGroup(iter->second->GetAuraSlot());
sLog.outDebug("Aura %u partially interrupted on unit %u, new duration: %u ms",iter->second->GetModifier()->m_auraname, GetGUIDLow(), iter->second->GetAuraDuration());
}
}
@@ -4827,6 +4252,33 @@ Aura* Unit::GetAura(uint32 spellId, uint32 effindex)
return NULL;
}
+Aura* Unit::GetAura(AuraType type, uint32 family, uint32 familyFlag1, uint32 familyFlag2, uint32 familyFlag3, uint64 casterGUID)
+{
+ AuraList const& auras = GetAurasByType(type);
+ for(AuraList::const_iterator i = auras.begin();i != auras.end(); ++i)
+ {
+ SpellEntry const *spell = (*i)->GetSpellProto();
+ if (spell->SpellFamilyName == family && spell->SpellFamilyFlags.HasFlag(familyFlag1, familyFlag2, familyFlag3))
+ {
+ if (casterGUID && (*i)->GetCasterGUID()!=casterGUID)
+ continue;
+ return (*i);
+ }
+ }
+ return NULL;
+}
+
+bool Unit::HasAura(uint32 spellId) const
+{
+ for (int i = 0; i < 3 ; ++i)
+ {
+ AuraMap::const_iterator iter = m_Auras.find(spellEffectPair(spellId, i));
+ if (iter != m_Auras.end())
+ return true;
+ }
+ return false;
+}
+
void Unit::AddDynObject(DynamicObject* dynObj)
{
m_dynObjGUIDs.push_back(dynObj->GetGUID());
@@ -4971,6 +4423,7 @@ void Unit::SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log)
data.append(log->attacker->GetPackGUID());
data << uint32(log->SpellID);
data << uint32(log->damage); //damage amount
+ data << uint32(0);
data << uint8 (log->schoolMask); //damage school
data << uint32(log->absorb); //AbsorbedDamage
data << uint32(log->resist); //resist
@@ -4990,6 +4443,7 @@ void Unit::SendSpellNonMeleeDamageLog(Unit *target,uint32 SpellID,uint32 Damage,
data.append(GetPackGUID());
data << uint32(SpellID);
data << uint32(Damage-AbsorbedDamage-Resist-Blocked);
+ data << uint32(0); // wotlk
data << uint8(damageSchoolMask); // spell school
data << uint32(AbsorbedDamage); // AbsorbedDamage
data << uint32(Resist); // resist
@@ -5028,25 +4482,65 @@ void Unit::SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo)
void Unit::SendAttackStateUpdate(CalcDamageInfo *damageInfo)
{
- WorldPacket data(SMSG_ATTACKERSTATEUPDATE, (16+84)); // we guess size
+ uint32 count = 1;
+ WorldPacket data(SMSG_ATTACKERSTATEUPDATE, (16+45)); // we guess size
data << (uint32)damageInfo->HitInfo;
data.append(GetPackGUID());
data.append(damageInfo->target->GetPackGUID());
data << (uint32)(damageInfo->damage); // Full damage
+ data << uint32(0); // overkill value
+
+ data << (uint8)count; // Sub damage count
+
+ for(int i = 0; i < count; ++i)
+ {
+ data << (uint32)(damageInfo->damageSchoolMask); // School of sub damage
+ data << (float)damageInfo->damage; // sub damage
+ data << (uint32)damageInfo->damage; // Sub Damage
+ }
+
+ if(damageInfo->HitInfo & (HITINFO_ABSORB | HITINFO_ABSORB2))
+ {
+ for(int i = 0; i < count; ++i)
+ data << (uint32)damageInfo->absorb; // Absorb
+ }
+
+ if(damageInfo->HitInfo & (HITINFO_RESIST | HITINFO_RESIST2))
+ {
+ for(int i = 0; i < count; ++i)
+ data << (uint32)damageInfo->resist; // Resist
+ }
- data << (uint8)1; // Sub damage count
- //=== Sub damage description
- data << (uint32)(damageInfo->damageSchoolMask); // School of sub damage
- data << (float)damageInfo->damage; // sub damage
- data << (uint32)damageInfo->damage; // Sub Damage
- data << (uint32)damageInfo->absorb; // Absorb
- data << (uint32)damageInfo->resist; // Resist
- //=================================================
- data << (uint32)damageInfo->TargetState;
+ data << (uint8)damageInfo->TargetState;
data << (uint32)0;
data << (uint32)0;
- data << (uint32)damageInfo->blocked_amount;
- SendMessageToSet( &data, true );/**/
+
+ if(damageInfo->HitInfo & HITINFO_BLOCK)
+ data << (uint32)damageInfo->blocked_amount;
+
+ if(damageInfo->HitInfo & HITINFO_UNK3)
+ data << uint32(0);
+
+ if(damageInfo->HitInfo & HITINFO_UNK1)
+ {
+ data << uint32(0);
+ data << float(0);
+ data << float(0);
+ data << float(0);
+ data << float(0);
+ data << float(0);
+ data << float(0);
+ data << float(0);
+ data << float(0);
+ for(uint8 i = 0; i < 5; ++i)
+ {
+ data << float(0);
+ data << float(0);
+ }
+ data << uint32(0);
+ }
+
+ SendMessageToSet( &data, true );
}
void Unit::SendAttackStateUpdate(uint32 HitInfo, Unit *target, uint8 SwingType, SpellSchoolMask damageSchoolMask, uint32 Damage, uint32 AbsorbDamage, uint32 Resist, VictimState TargetState, uint32 BlockedAmount)
@@ -5054,169 +4548,69 @@ void Unit::SendAttackStateUpdate(uint32 HitInfo, Unit *target, uint8 SwingType,
sLog.outDebug("WORLD: Sending SMSG_ATTACKERSTATEUPDATE");
WorldPacket data(SMSG_ATTACKERSTATEUPDATE, (16+45)); // we guess size
- data << (uint32)HitInfo;
+ data << uint32(HitInfo); // flags
data.append(GetPackGUID());
data.append(target->GetPackGUID());
- data << (uint32)(Damage-AbsorbDamage-Resist-BlockedAmount);
+ data << uint32(Damage-AbsorbDamage-Resist-BlockedAmount);// damage
+ data << uint32(0); // overkill value
data << (uint8)SwingType; // count?
// for(i = 0; i < SwingType; ++i)
data << (uint32)damageSchoolMask;
data << (float)(Damage-AbsorbDamage-Resist-BlockedAmount);
- // still need to double check damage
data << (uint32)(Damage-AbsorbDamage-Resist-BlockedAmount);
- data << (uint32)AbsorbDamage;
- data << (uint32)Resist;
// end loop
- data << (uint32)TargetState;
-
- if( AbsorbDamage == 0 ) //also 0x3E8 = 0x3E8, check when that happens
- data << (uint32)0;
- else
- data << (uint32)-1;
-
- data << (uint32)0;
- data << (uint32)BlockedAmount;
-
- SendMessageToSet( &data, true );
-}
-/*
-void Unit::ProcDamageAndSpell(Unit *pVictim, uint32 procAttacker, uint32 procVictim, uint32 damage, SpellSchoolMask damageSchoolMask, SpellEntry const *procSpell, bool isTriggeredSpell, WeaponAttackType attType)
-{
- sLog.outDebug("ProcDamageAndSpell: attacker flags are 0x%x, victim flags 0x%x", procAttacker, procVictim);
- if(procSpell)
- sLog.outDebug("ProcDamageAndSpell: invoked due to spell id %u %s", procSpell->Id, (isTriggeredSpell?"(triggered)":""));
-
- // Assign melee/ranged proc flags for magic attacks, that are actually melee/ranged abilities
- // not assign for spell proc triggered spell to prevent infinity (or unexpected 2-3 times) melee damage spell proc call with melee damage effect
- // That is the question though if it's fully correct
- if(procSpell && !isTriggeredSpell)
+ if(HitInfo & (HITINFO_ABSORB | HITINFO_ABSORB2))
{
- if(procSpell->DmgClass == SPELL_DAMAGE_CLASS_MELEE)
- {
- if(procAttacker & PROC_FLAG_HIT_SPELL) procAttacker |= PROC_FLAG_HIT_MELEE;
- if(procAttacker & PROC_FLAG_CRIT_SPELL) procAttacker |= PROC_FLAG_CRIT_MELEE;
- if(procVictim & PROC_FLAG_STRUCK_SPELL) procVictim |= PROC_FLAG_STRUCK_MELEE;
- if(procVictim & PROC_FLAG_STRUCK_CRIT_SPELL) procVictim |= PROC_FLAG_STRUCK_CRIT_MELEE;
- attType = BASE_ATTACK; // Melee abilities are assumed to be dealt with mainhand weapon
- }
- else if (procSpell->DmgClass == SPELL_DAMAGE_CLASS_RANGED)
- {
- if(procAttacker & PROC_FLAG_HIT_SPELL) procAttacker |= PROC_FLAG_HIT_RANGED;
- if(procAttacker & PROC_FLAG_CRIT_SPELL) procAttacker |= PROC_FLAG_CRIT_RANGED;
- if(procVictim & PROC_FLAG_STRUCK_SPELL) procVictim |= PROC_FLAG_STRUCK_RANGED;
- if(procVictim & PROC_FLAG_STRUCK_CRIT_SPELL) procVictim |= PROC_FLAG_STRUCK_CRIT_RANGED;
- attType = RANGED_ATTACK;
- }
+ // for(i = 0; i < SwingType; ++i)
+ data << uint32(AbsorbDamage);
+ // end loop
}
- if(damage && (procVictim & (PROC_FLAG_STRUCK_MELEE|PROC_FLAG_STRUCK_RANGED|PROC_FLAG_STRUCK_SPELL)))
- procVictim |= (PROC_FLAG_TAKE_DAMAGE|PROC_FLAG_TOUCH);
- // Not much to do if no flags are set.
- if (procAttacker)
+ if(HitInfo & (HITINFO_RESIST | HITINFO_RESIST2))
{
- // processing auras that not generate casts at proc event before auras that generate casts to prevent proc aura added at prev. proc aura execute in set
- ProcDamageAndSpellFor(false,pVictim,procAttacker,attackerProcEffectAuraTypes,attType, procSpell, damage, damageSchoolMask);
- ProcDamageAndSpellFor(false,pVictim,procAttacker,attackerProcCastAuraTypes,attType, procSpell, damage, damageSchoolMask);
+ // for(i = 0; i < SwingType; ++i)
+ data << uint32(Resist);
+ // end loop
}
- // Now go on with a victim's events'n'auras
- // Not much to do if no flags are set or there is no victim
- if(pVictim && pVictim->isAlive() && procVictim)
+ data << (uint8)TargetState;
+ data << (uint32)0;
+ data << (uint32)0;
+
+ if(HitInfo & HITINFO_BLOCK)
{
- // processing auras that not generate casts at proc event before auras that generate casts to prevent proc aura added at prev. proc aura execute in set
- pVictim->ProcDamageAndSpellFor(true,this,procVictim,victimProcEffectAuraTypes,attType,procSpell, damage, damageSchoolMask);
- pVictim->ProcDamageAndSpellFor(true,this,procVictim,victimProcCastAuraTypes,attType,procSpell, damage, damageSchoolMask);
+ data << uint32(BlockedAmount);
}
-}
-void Unit::CastMeleeProcDamageAndSpell(Unit* pVictim, uint32 damage, SpellSchoolMask damageSchoolMask, WeaponAttackType attType, MeleeHitOutcome outcome, SpellEntry const *spellCasted, bool isTriggeredSpell)
-{
- if(!pVictim)
- return;
-
- uint32 procAttacker = PROC_FLAG_NONE;
- uint32 procVictim = PROC_FLAG_NONE;
-
- switch(outcome)
+ if(HitInfo & HITINFO_UNK3)
{
- case MELEE_HIT_EVADE:
- return;
- case MELEE_HIT_MISS:
- if(attType == BASE_ATTACK || attType == OFF_ATTACK)
- {
- procAttacker = PROC_FLAG_MISS;
- }
- break;
- case MELEE_HIT_BLOCK_CRIT:
- case MELEE_HIT_CRIT:
- if(spellCasted && attType == BASE_ATTACK)
- {
- procAttacker |= PROC_FLAG_CRIT_SPELL;
- procVictim |= PROC_FLAG_STRUCK_CRIT_SPELL;
- if ( outcome == MELEE_HIT_BLOCK_CRIT )
- {
- procVictim |= PROC_FLAG_BLOCK;
- procAttacker |= PROC_FLAG_TARGET_BLOCK;
- }
- }
- else if(attType == BASE_ATTACK || attType == OFF_ATTACK)
- {
- procAttacker = PROC_FLAG_HIT_MELEE | PROC_FLAG_CRIT_MELEE;
- procVictim = PROC_FLAG_STRUCK_MELEE | PROC_FLAG_STRUCK_CRIT_MELEE;
- }
- else
- {
- procAttacker = PROC_FLAG_HIT_RANGED | PROC_FLAG_CRIT_RANGED;
- procVictim = PROC_FLAG_STRUCK_RANGED | PROC_FLAG_STRUCK_CRIT_RANGED;
- }
- break;
- case MELEE_HIT_PARRY:
- procAttacker = PROC_FLAG_TARGET_DODGE_OR_PARRY;
- procVictim = PROC_FLAG_PARRY;
- break;
- case MELEE_HIT_BLOCK:
- procAttacker = PROC_FLAG_TARGET_BLOCK;
- procVictim = PROC_FLAG_BLOCK;
- break;
- case MELEE_HIT_DODGE:
- procAttacker = PROC_FLAG_TARGET_DODGE_OR_PARRY;
- procVictim = PROC_FLAG_DODGE;
- break;
- case MELEE_HIT_CRUSHING:
- if(attType == BASE_ATTACK || attType == OFF_ATTACK)
- {
- procAttacker = PROC_FLAG_HIT_MELEE | PROC_FLAG_CRIT_MELEE;
- procVictim = PROC_FLAG_STRUCK_MELEE | PROC_FLAG_STRUCK_CRIT_MELEE;
- }
- else
- {
- procAttacker = PROC_FLAG_HIT_RANGED | PROC_FLAG_CRIT_RANGED;
- procVictim = PROC_FLAG_STRUCK_RANGED | PROC_FLAG_STRUCK_CRIT_RANGED;
- }
- break;
- default:
- if(attType == BASE_ATTACK || attType == OFF_ATTACK)
- {
- procAttacker = PROC_FLAG_HIT_MELEE;
- procVictim = PROC_FLAG_STRUCK_MELEE;
- }
- else
- {
- procAttacker = PROC_FLAG_HIT_RANGED;
- procVictim = PROC_FLAG_STRUCK_RANGED;
- }
- break;
+ data << uint32(0);
}
- if(damage > 0)
- procVictim |= PROC_FLAG_TAKE_DAMAGE;
+ if(HitInfo & HITINFO_UNK1)
+ {
+ data << uint32(0);
+ data << float(0);
+ data << float(0);
+ data << float(0);
+ data << float(0);
+ data << float(0);
+ data << float(0);
+ data << float(0);
+ data << float(0);
+ for(uint8 i = 0; i < 5; ++i)
+ {
+ data << float(0);
+ data << float(0);
+ }
+ data << uint32(0);
+ }
- if(procAttacker != PROC_FLAG_NONE || procVictim != PROC_FLAG_NONE)
- ProcDamageAndSpell(pVictim, procAttacker, procVictim, damage, damageSchoolMask, spellCasted, isTriggeredSpell, attType);
-}*/
+ SendMessageToSet( &data, true );
+}
bool Unit::HandleHasteAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 cooldown)
{
@@ -5284,7 +4678,8 @@ bool Unit::HandleHasteAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown)
{
SpellEntry const *dummySpell = triggeredByAura->GetSpellProto ();
- uint32 effIndex = triggeredByAura->GetEffIndex ();
+ uint32 effIndex = triggeredByAura->GetEffIndex();
+ int32 triggerAmount = triggeredByAura->GetModifier()->m_amount;
Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER
? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL;
@@ -5299,7 +4694,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
{
switch (dummySpell->Id)
{
- // Eye of Eye
+ // Eye for an Eye
case 9799:
case 25988:
{
@@ -5308,7 +4703,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
// return damage % to attacker but < 50% own total health
- basepoints0 = triggeredByAura->GetModifier()->m_amount*int32(damage)/100;
+ basepoints0 = triggerAmount*int32(damage)/100;
if(basepoints0 > GetMaxHealth()/2)
basepoints0 = GetMaxHealth()/2;
@@ -5337,15 +4732,14 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
if (!procSpell || procSpell->Id == 24659)
return false;
// Need remove one 24659 aura
- RemoveSingleAuraFromStack(24659, 0);
- RemoveSingleAuraFromStack(24659, 1);
+ RemoveSingleSpellAurasFromStack(24659);
return true;
}
// Restless Strength
case 24661:
{
// Need remove one 24662 aura
- RemoveSingleAuraFromStack(24662, 0);
+ RemoveSingleSpellAurasFromStack(24662);
return true;
}
// Adaptive Warding (Frostfire Regalia set)
@@ -5361,7 +4755,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
{
if(SpellEntry const* iterSpellProto = (*iter)->GetSpellProto())
{
- if(iterSpellProto->SpellFamilyName==SPELLFAMILY_MAGE && (iterSpellProto->SpellFamilyFlags & 0x10000000))
+ if(iterSpellProto->SpellFamilyName==SPELLFAMILY_MAGE && (iterSpellProto->SpellFamilyFlags[0] & 0x10000000))
{
found=true;
break;
@@ -5419,7 +4813,6 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
if(!target)
return false;
- basepoints0 = int32(damage * 2.5f); // manaregen
triggered_spell_id = 34650;
break;
}
@@ -5427,7 +4820,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
case 33493:
{
// Cast finish spell at last charge
- if (triggeredByAura->m_procCharges > 1)
+ if (triggeredByAura->GetAuraCharges() > 1)
return false;
target = this;
@@ -5627,6 +5020,47 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
}
return false;
}
+ // Living Seed
+ case 48504:
+ {
+ triggered_spell_id = 48503;
+ basepoints0 = triggerAmount;
+ target = this;
+ break;
+ }
+ // Vampiric Touch (generic, used by some boss)
+ case 52723:
+ case 60501:
+ {
+ triggered_spell_id = 52724;
+ basepoints0 = damage / 2;
+ target = this;
+ break;
+ }
+ // Divine purpose
+ case 31871:
+ case 31872:
+ {
+ // Roll chane
+ if (!roll_chance_i(triggerAmount))
+ return false;
+
+ // Remove any stun effect on target
+ AuraMap& Auras = pVictim->GetAuras();
+ for(AuraMap::iterator iter = Auras.begin(); iter != Auras.end();)
+ {
+ SpellEntry const *spell = iter->second->GetSpellProto();
+ if( spell->Mechanic == MECHANIC_STUN ||
+ spell->EffectMechanic[iter->second->GetEffIndex()] == MECHANIC_STUN)
+ {
+ pVictim->RemoveAurasDueToSpell(spell->Id);
+ iter = Auras.begin();
+ }
+ else
+ ++iter;
+ }
+ return true;
+ }
}
break;
}
@@ -5639,7 +5073,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
// mana reward
- basepoints0 = (triggeredByAura->GetModifier()->m_amount * GetMaxPower(POWER_MANA) / 100);
+ basepoints0 = (triggerAmount * GetMaxPower(POWER_MANA) / 100);
target = this;
triggered_spell_id = 29442;
break;
@@ -5651,7 +5085,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
// mana cost save
- basepoints0 = procSpell->manaCost * triggeredByAura->GetModifier()->m_amount/100;
+ int32 cost = procSpell->manaCost + procSpell->ManaCostPercentage * GetCreateMana() / 100;
+ basepoints0 = cost * triggerAmount/100;
if( basepoints0 <=0 )
return false;
@@ -5659,8 +5094,45 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
triggered_spell_id = 29077;
break;
}
+ // Hot Streak
+ if (dummySpell->SpellIconID == 2999)
+ {
+ if (effIndex!=0)
+ return true;
+ Aura *counter = GetAura(triggeredByAura->GetId(), 1);
+ if (!counter)
+ return true;
+
+ // Count spell criticals in a row in second aura
+ Modifier *mod = counter->GetModifier();
+ if (procEx & PROC_EX_CRITICAL_HIT)
+ {
+ mod->m_amount *=2;
+ if (mod->m_amount < 100) // not enough
+ return true;
+ // Crititcal counted -> roll chance
+ if (roll_chance_i(triggerAmount))
+ CastSpell(this, 48108, true, castItem, triggeredByAura);
+ }
+ mod->m_amount = 25;
+ return true;
+ }
+ // Burnout
+ if (dummySpell->SpellIconID == 2998)
+ {
+ if(!procSpell)
+ return false;
+
+ int32 cost = procSpell->manaCost + procSpell->ManaCostPercentage * GetCreateMana() / 100;
+ basepoints0 = cost * triggerAmount/100;
+ if( basepoints0 <=0 )
+ return false;
+ triggered_spell_id = 44450;
+ target = this;
+ break;
+ }
// Incanter's Regalia set (add trigger chance to Mana Shield)
- if (dummySpell->SpellFamilyFlags & 0x0000000000008000LL)
+ if (dummySpell->SpellFamilyFlags[0] & 0x8000)
{
if(GetTypeId() != TYPEID_PLAYER)
return false;
@@ -5697,7 +5169,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
case 11129:
{
//last charge and crit
- if (triggeredByAura->m_procCharges <= 1 && (procEx & PROC_EX_CRITICAL_HIT) )
+ if (triggeredByAura->GetAuraCharges() <= 1 && (procEx & PROC_EX_CRITICAL_HIT) )
{
RemoveAurasDueToSpell(28682); //-> remove Combustion auras
return true; // charge counting (will removed)
@@ -5712,7 +5184,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
case SPELLFAMILY_WARRIOR:
{
// Retaliation
- if(dummySpell->SpellFamilyFlags==0x0000000800000000LL)
+ if(dummySpell->SpellFamilyFlags.IsEqual(0, 0x8, 0))
{
// check attack comes not from behind
if (!HasInArc(M_PI, pVictim))
@@ -5721,26 +5193,21 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
triggered_spell_id = 22858;
break;
}
- else if (dummySpell->SpellIconID == 1697) // Second Wind
+ // Second Wind
+ if (dummySpell->SpellIconID == 1697)
{
// only for spells and hit/crit (trigger start always) and not start from self casted spells (5530 Mace Stun Effect for example)
if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) || this == pVictim)
return false;
// Need stun or root mechanic
- if (procSpell->Mechanic != MECHANIC_ROOT && procSpell->Mechanic != MECHANIC_STUN)
- {
- int32 i;
- for (i=0; i<3; i++)
- if (procSpell->EffectMechanic[i] == MECHANIC_ROOT || procSpell->EffectMechanic[i] == MECHANIC_STUN)
- break;
- if (i == 3)
- return false;
- }
+ if (!(GetAllSpellMechanicMask(procSpell) & ((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:
sLog.outError("Unit::HandleDummyAuraProc: non handled spell id: %u (SW)",dummySpell->Id);
return false;
@@ -5749,12 +5216,19 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
target = this;
break;
}
+ // Damage Shield
+ if (dummySpell->SpellIconID == 3214)
+ {
+ triggered_spell_id = 59653;
+ basepoints0 = GetShieldBlockValue() * triggerAmount / 100;
+ break;
+ }
break;
}
case SPELLFAMILY_WARLOCK:
{
// Seed of Corruption
- if (dummySpell->SpellFamilyFlags & 0x0000001000000000LL)
+ if (dummySpell->SpellFamilyFlags[1] & 0x00000010)
{
Modifier* mod = triggeredByAura->GetModifier();
// if damage is more than need or target die from damage deal finish spell
@@ -5798,6 +5272,16 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
mod->m_amount-=damage;
return true;
}
+ // Fel Synergy
+ if (dummySpell->SpellIconID == 3222)
+ {
+ target = GetPet();
+ if (!target)
+ return false;
+ triggered_spell_id = 54181;
+ basepoints0 = damage * triggerAmount / 100;
+ break;
+ }
switch(dummySpell->Id)
{
// Nightfall
@@ -5814,7 +5298,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
case 30296:
{
// health
- basepoints0 = int32(damage*triggeredByAura->GetModifier()->m_amount/100);
+ basepoints0 = int32(damage*triggerAmount/100);
target = this;
triggered_spell_id = 30294;
break;
@@ -5833,7 +5317,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
// heal amount
- basepoints0 = damage * triggeredByAura->GetModifier()->m_amount/100;
+ basepoints0 = damage * triggerAmount/100;
triggered_spell_id = 37382;
break;
}
@@ -5849,7 +5333,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
case SPELLFAMILY_PRIEST:
{
// Vampiric Touch
- if( dummySpell->SpellFamilyFlags & 0x0000040000000000LL )
+ if( dummySpell->SpellFamilyFlags[1] & 0x00000400 )
{
if(!pVictim || !pVictim->isAlive())
return false;
@@ -5859,10 +5343,17 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
// energize amount
- basepoints0 = triggeredByAura->GetModifier()->m_amount*damage/100;
+ basepoints0 = triggerAmount*damage/100;
pVictim->CastCustomSpell(pVictim,34919,&basepoints0,NULL,NULL,true,castItem,triggeredByAura);
return true; // no hidden cooldown
}
+ // Divine Aegis
+ if (dummySpell->SpellIconID == 2820)
+ {
+ basepoints0 = damage * triggerAmount/100;
+ triggered_spell_id = 47753;
+ break;
+ }
switch(dummySpell->Id)
{
// Vampiric Embrace
@@ -5876,18 +5367,19 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
// heal amount
- basepoints0 = triggeredByAura->GetModifier()->m_amount*damage/100;
- pVictim->CastCustomSpell(pVictim,15290,&basepoints0,NULL,NULL,true,castItem,triggeredByAura);
+ int32 team = triggerAmount*damage/500;
+ int32 self = triggerAmount*damage/100 - team;
+ pVictim->CastCustomSpell(pVictim,15290,&team,&self,NULL,true,castItem,triggeredByAura);
return true; // no hidden cooldown
}
// Priest Tier 6 Trinket (Ashtongue Talisman of Acumen)
case 40438:
{
// Shadow Word: Pain
- if( procSpell->SpellFamilyFlags & 0x0000000000008000LL )
+ if( procSpell->SpellFamilyFlags[0] & 0x8000 )
triggered_spell_id = 40441;
// Renew
- else if( procSpell->SpellFamilyFlags & 0x0000000000000010LL )
+ else if( procSpell->SpellFamilyFlags[0] & 0x10 )
triggered_spell_id = 40440;
else
return false;
@@ -5911,12 +5403,12 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
// heal amount
- basepoints0 = int32(damage * 2 / 100);
+ basepoints0 = damage * triggerAmount/100;
target = this;
triggered_spell_id = 39373;
break;
}
- // Vestments of Faith (Priest Tier 3) - 4 pieces bonus
+ // Greater Heal (Vestments of Faith (Priest Tier 3) - 4 pieces bonus)
case 28809:
{
triggered_spell_id = 28810;
@@ -5959,19 +5451,19 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
float chance;
// Starfire
- if( procSpell->SpellFamilyFlags & 0x0000000000000004LL )
+ if( procSpell->SpellFamilyFlags[0] & 0x4 )
{
triggered_spell_id = 40445;
chance = 25.f;
}
// Rejuvenation
- else if( procSpell->SpellFamilyFlags & 0x0000000000000010LL )
+ else if( procSpell->SpellFamilyFlags[0] & 0x10 )
{
triggered_spell_id = 40446;
chance = 25.f;
}
// Mangle (cat/bear)
- else if( procSpell->SpellFamilyFlags & 0x0000044000000000LL )
+ else if( procSpell->SpellFamilyFlags[1] & 0x00000440)
{
triggered_spell_id = 40452;
chance = 40.f;
@@ -5993,6 +5485,39 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
break;
}
}
+ // Eclipse
+ if (dummySpell->SpellIconID == 2856)
+ {
+ if (!procSpell)
+ return false;
+ // Only 0 aura can proc
+ if (effIndex!=0)
+ return true;
+ // Wrath crit
+ if (procSpell->SpellFamilyFlags[0] & 0x1)
+ {
+ if (!roll_chance_i(60))
+ return false;
+ triggered_spell_id = 48518;
+ target = this;
+ break;
+ }
+ // Starfire crit
+ if (procSpell->SpellFamilyFlags[0] & 0x4)
+ {
+ triggered_spell_id = 48517;
+ target = this;
+ break;
+ }
+ return false;
+ }
+ // Living Seed
+ else if (dummySpell->SpellIconID == 2860)
+ {
+ triggered_spell_id = 48504;
+ basepoints0 = triggerAmount * damage / 100;
+ break;
+ }
break;
}
case SPELLFAMILY_ROGUE:
@@ -6010,19 +5535,39 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
break;
}
}
+ // Cut to the Chase
+ if( dummySpell->SpellIconID == 2909 )
+ {
+ // "refresh your Slice and Dice duration to its 5 combo point maximum"
+ // lookup Slice and Dice
+ AuraList const& sd = GetAurasByType(SPELL_AURA_MOD_HASTE);
+ for(AuraList::const_iterator itr = sd.begin(); itr != sd.end(); ++itr)
+ {
+ SpellEntry const *spellProto = (*itr)->GetSpellProto();
+ if( spellProto->SpellFamilyName == SPELLFAMILY_ROGUE &&
+ spellProto->SpellFamilyFlags[0] & 0x40000)
+ {
+ (*itr)->SetAuraMaxDuration(GetSpellMaxDuration(spellProto));
+ (*itr)->RefreshAura();
+ return true;
+ }
+ }
+ return false;
+ }
+ // Deadly Brew
+ if( dummySpell->SpellIconID == 2963 )
+ {
+ triggered_spell_id = 25809;
+ break;
+ }
// Quick Recovery
if( dummySpell->SpellIconID == 2116 )
{
if(!procSpell)
return false;
- // only rogue's finishing moves (maybe need additional checks)
- if( procSpell->SpellFamilyName!=SPELLFAMILY_ROGUE ||
- (procSpell->SpellFamilyFlags & SPELLFAMILYFLAG_ROGUE__FINISHING_MOVE) == 0)
- return false;
-
// energy cost save
- basepoints0 = procSpell->manaCost * triggeredByAura->GetModifier()->m_amount/100;
+ basepoints0 = procSpell->manaCost * triggerAmount/100;
if(basepoints0 <= 0)
return false;
@@ -6041,7 +5586,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
// mana cost save
- basepoints0 = procSpell->manaCost * 40/100;
+ int32 mana = procSpell->manaCost + procSpell->ManaCostPercentage * GetCreateMana() / 100;
+ basepoints0 = mana * 40/100;
if(basepoints0 <= 0)
return false;
@@ -6049,75 +5595,93 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
triggered_spell_id = 34720;
break;
}
+ // Hunting Party
+ if ( dummySpell->SpellIconID == 3406 )
+ {
+ triggered_spell_id = 57669;
+ target = this;
+ break;
+ }
+ // Lock and Load
+ if ( dummySpell->SpellIconID == 3579 )
+ {
+ // Proc only from periodic (from trap activation proc another aura of this spell)
+ if (!(procFlag & PROC_FLAG_ON_DO_PERIODIC) || !roll_chance_i(triggerAmount))
+ return false;
+ triggered_spell_id = 56453;
+ target = this;
+ break;
+ }
+ // Rapid Recuperation
+ if ( dummySpell->SpellIconID == 3560 )
+ {
+ // This effect only from Rapid Killing (mana regen)
+ if (!(procSpell->SpellFamilyFlags[1] & 0x01000000))
+ return false;
+ triggered_spell_id = 56654;
+ target = this;
+ break;
+ }
break;
}
case SPELLFAMILY_PALADIN:
{
- // Seal of Righteousness - melee proc dummy
- if (dummySpell->SpellFamilyFlags&0x000000008000000LL && triggeredByAura->GetEffIndex()==0)
+ // Seal of Righteousness - melee proc dummy (addition ${$MWS*(0.022*$AP+0.044*$SPH)} damage)
+ if (dummySpell->SpellFamilyFlags[0]&0x8000000 && effIndex==0)
{
- if(GetTypeId() != TYPEID_PLAYER)
- return false;
-
- uint32 spellId;
- switch (triggeredByAura->GetId())
- {
- case 21084: spellId = 25742; break; // Rank 1
- case 20287: spellId = 25740; break; // Rank 2
- case 20288: spellId = 25739; break; // Rank 3
- case 20289: spellId = 25738; break; // Rank 4
- case 20290: spellId = 25737; break; // Rank 5
- case 20291: spellId = 25736; break; // Rank 6
- case 20292: spellId = 25735; break; // Rank 7
- case 20293: spellId = 25713; break; // Rank 8
- case 27155: spellId = 27156; break; // Rank 9
- default:
- sLog.outError("Unit::HandleDummyAuraProc: non handled possibly SoR (Id = %u)", triggeredByAura->GetId());
- return false;
- }
- Item *item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
- float speed = (item ? item->GetProto()->Delay : BASE_ATTACK_TIME)/1000.0f;
-
- float damageBasePoints;
- if(item && item->GetProto()->InventoryType == INVTYPE_2HWEAPON)
- // two hand weapon
- damageBasePoints=1.20f*triggeredByAura->GetModifier()->m_amount * 1.2f * 1.03f * speed/100.0f + 1;
- else
- // one hand weapon/no weapon
- damageBasePoints=0.85f*ceil(triggeredByAura->GetModifier()->m_amount * 1.2f * 1.03f * speed/100.0f) - 1;
-
- int32 damagePoint = int32(damageBasePoints + 0.03f * (GetWeaponDamageRange(BASE_ATTACK,MINDAMAGE)+GetWeaponDamageRange(BASE_ATTACK,MAXDAMAGE))/2.0f) + 1;
-
- // apply damage bonuses manually
- if(damagePoint >= 0)
- damagePoint = SpellDamageBonus(pVictim, dummySpell, damagePoint, SPELL_DIRECT_DAMAGE);
-
- CastCustomSpell(pVictim,spellId,&damagePoint,NULL,NULL,true,NULL, triggeredByAura);
- return true; // no hidden cooldown
+ triggered_spell_id = 25742;
+ float ap = GetTotalAttackPowerValue(BASE_ATTACK);
+ int32 holy = SpellBaseDamageBonus(SPELL_SCHOOL_MASK_HOLY) +
+ SpellBaseDamageBonusForVictim(SPELL_SCHOOL_MASK_HOLY, pVictim);
+ basepoints0 = GetAttackTime(BASE_ATTACK) * int32(ap*0.022f + 0.044f * holy) / 1000;
+ break;
}
- // Seal of Blood do damage trigger
- if(dummySpell->SpellFamilyFlags & 0x0000040000000000LL)
+ // Sacred Shield
+ if (dummySpell->SpellFamilyFlags[1]&0x00080000)
{
- switch(triggeredByAura->GetEffIndex())
- {
- case 0:
- triggered_spell_id = 31893;
- break;
- case 1:
- {
- // damage
- damage += CalculateDamage(BASE_ATTACK, false) * 35 / 100; // add spell damage from prev effect (35%)
- basepoints0 = triggeredByAura->GetModifier()->m_amount * damage / 100;
-
- target = this;
- triggered_spell_id = 32221;
- break;
- }
- }
+ triggered_spell_id = 58597;
+ target = this;
+ break;
+ }
+ // Righteous Vengeance
+ if (dummySpell->SpellIconID == 3025)
+ {
+ // 4 damage tick
+ basepoints0 = triggerAmount*damage/400;
+ triggered_spell_id = 61840;
+ break;
+ }
+ // Sheath of Light
+ if (dummySpell->SpellIconID == 3030)
+ {
+ // 4 healing tick
+ basepoints0 = triggerAmount*damage/400;
+ triggered_spell_id = 54203;
+ break;
}
-
switch(dummySpell->Id)
{
+ // Judgement of Light
+ case 20185:
+ {
+ // Get judgement caster
+ Unit *caster = triggeredByAura->GetCaster();
+ if (!caster)
+ return false;
+ float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK);
+ int32 holy = caster->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_HOLY) +
+ caster->SpellBaseDamageBonusForVictim(SPELL_SCHOOL_MASK_HOLY, this);
+ basepoints0 = int32(ap*0.10f + 0.10f*holy);
+ pVictim->CastCustomSpell(pVictim, 20267, &basepoints0, 0, 0, true, 0, triggeredByAura);
+ return true;
+ }
+ // Judgement of Wisdom
+ case 20186:
+ {
+ if (pVictim->getPowerType() == POWER_MANA)
+ pVictim->CastSpell(pVictim, 20268, true, 0, triggeredByAura);
+ return true;
+ }
// Holy Power (Redemption Armor set)
case 28789:
{
@@ -6149,7 +5713,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
}
break;
}
- //Seal of Vengeance
+ // Seal of Vengeance (damage calc on apply aura)
case 31801:
{
if(effIndex != 0) // effect 1,2 used by seal unleashing code
@@ -6158,7 +5722,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
triggered_spell_id = 31803;
break;
}
- // Spiritual Att.
+ // Spiritual Attunement
case 31785:
case 33776:
{
@@ -6167,11 +5731,45 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
// heal amount
- basepoints0 = triggeredByAura->GetModifier()->m_amount*damage/100;
+ basepoints0 = triggerAmount*damage/100;
target = this;
triggered_spell_id = 31786;
break;
}
+ // Seal of Blood do damage trigger
+ case 31892:
+ {
+ if (effIndex == 0) // 0 effect - is proc on enemy
+ triggered_spell_id = 31893;
+ else if (effIndex == 1) // 1 effect - is proc on self
+ {
+ // add spell damage from prev effect (27%)
+ damage += CalculateDamage(BASE_ATTACK, false) * 27 / 100;
+ basepoints0 = triggerAmount * damage / 100;
+ target = this;
+ triggered_spell_id = 32221;
+ }
+ else
+ return true;
+ break;
+ }
+ // Seal of the Martyr do damage trigger
+ case 53720:
+ {
+ if (effIndex == 0) // 0 effect - is proc on enemy
+ triggered_spell_id = 53719;
+ else if (effIndex == 1) // 1 effect - is proc on self
+ {
+ // add spell damage from prev effect (27%)
+ damage += CalculateDamage(BASE_ATTACK, false) * 27 / 100;
+ basepoints0 = triggerAmount * damage / 100;
+ target = this;
+ triggered_spell_id = 53718;
+ }
+ else
+ return true;
+ break;
+ }
// Paladin Tier 6 Trinket (Ashtongue Talisman of Zeal)
case 40470:
{
@@ -6181,13 +5779,13 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
float chance;
// Flash of light/Holy light
- if( procSpell->SpellFamilyFlags & 0x00000000C0000000LL)
+ if( procSpell->SpellFamilyFlags[0] & 0xC0000000)
{
triggered_spell_id = 40471;
chance = 15.f;
}
// Judgement
- else if( procSpell->SpellFamilyFlags & 0x0000000000800000LL )
+ else if( procSpell->SpellFamilyFlags[0] & 0x800000 )
{
triggered_spell_id = 40472;
chance = 50.f;
@@ -6200,6 +5798,33 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
break;
}
+ // Glyph of Divinity
+ case 54939:
+ {
+ // Lookup base amount mana restore
+ for (int i=0; i<3;i++)
+ if (procSpell->Effect[i] == SPELL_EFFECT_ENERGIZE)
+ {
+ int32 mana = procSpell->EffectBasePoints[i];
+ CastCustomSpell(this, 54986, 0, &mana, 0, true, castItem, triggeredByAura);
+ break;
+ }
+ return true;
+ }
+ // Glyph of Flash of Light
+ case 54936:
+ {
+ triggered_spell_id = 54957;
+ basepoints0 = triggerAmount*damage/100;
+ break;
+ }
+ // Glyph of Holy Light
+ case 54937:
+ {
+ triggered_spell_id = 54968;
+ basepoints0 = triggerAmount*damage/100;
+ break;
+ }
}
break;
}
@@ -6258,14 +5883,19 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
if( cooldown && ((Player*)this)->HasSpellCooldown(dummySpell->Id))
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 = 33757; break; //1 Rank
- case 284: spellId = 33756; break; //2 Rank
- case 525: spellId = 33755; break; //3 Rank
- case 1669:spellId = 33754; break; //4 Rank
- case 2636:spellId = 33727; break; //5 Rank
+ 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:
{
sLog.outError("Unit::HandleDummyAuraProc: non handled item enchantment (rank?) %u for spell id: %u (Windfury)",
@@ -6281,7 +5911,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
}
- int32 extra_attack_power = CalculateSpellDamage(windfurySpellEntry,0,windfurySpellEntry->EffectBasePoints[0],pVictim);
+ int32 extra_attack_power = CalculateSpellDamage(windfurySpellEntry, 1, windfurySpellEntry->EffectBasePoints[1], pVictim);
// Off-Hand case
if ( castItem->GetSlot() == EQUIPMENT_SLOT_OFFHAND )
@@ -6315,17 +5945,17 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
float chance;
- if (procSpell->SpellFamilyFlags & 0x0000000000000001LL)
+ if (procSpell->SpellFamilyFlags[0] & 0x1)
{
triggered_spell_id = 40465; // Lightning Bolt
chance = 15.f;
}
- else if (procSpell->SpellFamilyFlags & 0x0000000000000080LL)
+ else if (procSpell->SpellFamilyFlags[0] & 0x80)
{
triggered_spell_id = 40465; // Lesser Healing Wave
chance = 10.f;
}
- else if (procSpell->SpellFamilyFlags & 0x0000001000000000LL)
+ else if (procSpell->SpellFamilyFlags[1] & 0x00000010)
{
triggered_spell_id = 40466; // Stormstrike
chance = 50.f;
@@ -6339,20 +5969,69 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
target = this;
break;
}
+ // Glyph of Healing Wave
+ case 55440:
+ {
+ // Not proc from self heals
+ if (this==pVictim)
+ return false;
+ basepoints0 = triggerAmount * damage / 100;
+ target = this;
+ triggered_spell_id = 55533;
+ break;
+ }
+ // Spirit Hunt
+ case 58877:
+ {
+ // Cast on owner
+ target = GetOwner();
+ if(!target)
+ return false;
+ basepoints0 = triggerAmount * damage / 100;
+ triggered_spell_id = 58879;
+ break;
+ }
+ }
+ // Ancestral Awakening
+ if (dummySpell->SpellIconID == 2018)
+ {
+ // TODO: frite dummy fot triggered spell
+ triggered_spell_id = 52759;
+ basepoints0 = triggerAmount * damage / 100;
+ target = this;
+ break;
}
-
// Earth Shield
- if(dummySpell->SpellFamilyFlags==0x40000000000LL)
+ if(dummySpell->SpellFamilyFlags[1] & 0x00000400)
{
- if(GetTypeId() != TYPEID_PLAYER)
- return false;
-
- // heal
- basepoints0 = triggeredByAura->GetModifier()->m_amount;
+ basepoints0 = triggerAmount;
target = this;
triggered_spell_id = 379;
break;
}
+ // Improved Water Shield
+ if (dummySpell->SpellIconID == 2287)
+ {
+ // Lesser Healing Wave need aditional 60% roll
+ if (procSpell->SpellFamilyFlags[0] & 0x80 && !roll_chance_i(60))
+ return false;
+ // lookup water shield
+ AuraList const& vs = GetAurasByType(SPELL_AURA_PROC_TRIGGER_SPELL);
+ for(AuraList::const_iterator itr = vs.begin(); itr != vs.end(); ++itr)
+ {
+ if( (*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN &&
+ (*itr)->GetSpellProto()->SpellFamilyFlags[1] & 0x00000020)
+ {
+ uint32 spell = (*itr)->GetSpellProto()->EffectTriggerSpell[(*itr)->GetEffIndex()];
+ CastSpell(this, spell, true, castItem, triggeredByAura);
+ if ((*itr)->DropAuraCharge())
+ RemoveAurasDueToSpell((*itr)->GetId());
+ return true;
+ }
+ }
+ return false;
+ break;
+ }
// Lightning Overload
if (dummySpell->SpellIconID == 2018) // only this spell have SpellFamily Shaman SpellIconID == 2018 and dummy aura
{
@@ -6380,6 +6059,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
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
@@ -6387,31 +6068,26 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
case 10605: spellId = 45300; break; // Rank 4
case 25439: spellId = 45301; break; // Rank 5
case 25442: spellId = 45302; break; // Rank 6
+ case 49268: spellId = 49270; break; // Rank 7
+ case 49269: spellId = 49271; break; // Rank 8
default:
sLog.outError("Unit::HandleDummyAuraProc: non handled spell id: %u (LO)", procSpell->Id);
return false;
}
// No thread generated mod
+ // TODO: exist special flag in spell attributes for this, need found and use!
SpellModifier *mod = new SpellModifier;
mod->op = SPELLMOD_THREAT;
mod->value = -100;
mod->type = SPELLMOD_PCT;
mod->spellId = dummySpell->Id;
- mod->effectId = 0;
- mod->lastAffected = NULL;
- mod->mask = 0x0000000000000003LL;
- mod->charges = 0;
+ mod->mask[0] = 0x3;
((Player*)this)->AddSpellMod(mod, true);
// Remove cooldown (Chain Lightning - have Category Recovery time)
- if (procSpell->SpellFamilyFlags & 0x0000000000000002LL)
+ if (procSpell->SpellFamilyFlags[0] & 0x2)
((Player*)this)->RemoveSpellCooldown(spellId);
- // Hmmm.. in most case spells already set half basepoints but...
- // Lightning Bolt (2-10 rank) have full basepoint and half bonus from level
- // As on wiki:
- // BUG: Rank 2 to 10 (and maybe 11) of Lightning Bolt will proc another Bolt with FULL damage (not halved). This bug is known and will probably be fixed soon.
- // So - no add changes :)
CastSpell(pVictim, spellId, true, castItem, triggeredByAura);
((Player*)this)->AddSpellMod(mod, false);
@@ -6421,6 +6097,117 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return true;
}
+ // Static Shock
+ if(dummySpell->SpellIconID == 3059)
+ {
+ // lookup Lightning Shield
+ AuraList const& vs = GetAurasByType(SPELL_AURA_PROC_TRIGGER_SPELL);
+ for(AuraList::const_iterator itr = vs.begin(); itr != vs.end(); ++itr)
+ {
+ if( (*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN &&
+ (*itr)->GetSpellProto()->SpellFamilyFlags[0] & 0x400)
+ {
+ uint32 spell = 0;
+ switch ((*itr)->GetId())
+ {
+ case 324: spell = 26364; break;
+ case 325: spell = 26365; break;
+ case 905: spell = 26366; break;
+ case 945: spell = 26367; break;
+ case 8134: spell = 26369; break;
+ case 10431: spell = 26370; break;
+ case 10432: spell = 26363; break;
+ case 25469: spell = 26371; break;
+ case 25472: spell = 26372; break;
+ case 49280: spell = 49278; break;
+ case 49281: spell = 49279; break;
+ default:
+ return false;
+ }
+ CastSpell(this, spell, true, castItem, triggeredByAura);
+ if ((*itr)->DropAuraCharge())
+ RemoveAurasDueToSpell((*itr)->GetId());
+ return true;
+ }
+ }
+ return false;
+ break;
+ }
+ break;
+ }
+ case SPELLFAMILY_DEATHKNIGHT:
+ {
+ // Blood Aura
+ if (dummySpell->SpellIconID == 2636)
+ {
+ if (GetTypeId() != TYPEID_PLAYER || !((Player*)this)->isHonorOrXPTarget(pVictim))
+ return false;
+ basepoints0 = triggerAmount * damage / 100;
+ triggered_spell_id = 53168;
+ break;
+ }
+ // Butchery
+ if (dummySpell->SpellIconID == 2664)
+ {
+ basepoints0 = triggerAmount;
+ triggered_spell_id = 50163;
+ target = this;
+ break;
+ }
+ // Dancing Rune Weapon
+ if (dummySpell->Id == 49028)
+ {
+ // 1 dummy aura for dismiss rune blade
+ if (effIndex!=2)
+ return false;
+ // TODO: wite script for this "fights on its own, doing the same attacks"
+ // NOTE: Trigger here on every attack and spell cast
+ return false;
+ }
+ // Mark of Blood
+ if (dummySpell->Id == 49005)
+ {
+ // TODO: need more info (cooldowns/PPM)
+ triggered_spell_id = 50424;
+ break;
+ }
+ // Vendetta
+ if (dummySpell->SpellFamilyFlags[0] & 0x10000)
+ {
+ basepoints0 = triggerAmount * GetMaxHealth() / 100;
+ triggered_spell_id = 50181;
+ target = this;
+ break;
+ }
+ // Necrosis
+ if (dummySpell->SpellIconID == 2709)
+ {
+ basepoints0 = triggerAmount * damage / 100;
+ triggered_spell_id = 51460;
+ break;
+ }
+ // Runic Power Back on Snare/Root
+ if (dummySpell->Id == 61257)
+ {
+ // only for spells and hit/crit (trigger start always) and not start from self casted spells
+ if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) || this == pVictim)
+ return false;
+ // Need snare or root mechanic
+ if (!(GetAllSpellMechanicMask(procSpell) & ((1<<MECHANIC_ROOT)|(1<<MECHANIC_SNARE))))
+ return false;
+ triggered_spell_id = 61258;
+ target = this;
+ break;
+ }
+ // Wandering Plague
+ if (dummySpell->SpellIconID == 1614)
+ {
+ if (!roll_chance_f(GetUnitCriticalChance(BASE_ATTACK, pVictim)))
+ return false;
+ basepoints0 = triggerAmount * damage / 100;
+ triggered_spell_id = 50526;
+ break;
+ }
break;
}
default:
@@ -6456,1172 +6243,518 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return true;
}
-/*
-bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlags,WeaponAttackType attackType, uint32 cooldown)
+
+bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlags, uint32 procEx, uint32 cooldown)
{
+ // Get triggered aura spell info
SpellEntry const* auraSpellInfo = triggeredByAura->GetSpellProto();
+ // Basepoints of trigger aura
+ int32 triggerAmount = triggeredByAura->GetModifier()->m_amount;
+
+ // Set trigger spell id, target, custom basepoints
+ uint32 trigger_spell_id = auraSpellInfo->EffectTriggerSpell[triggeredByAura->GetEffIndex()];
+ Unit* target = NULL;
+ int32 basepoints0 = 0;
+
+ if(triggeredByAura->GetModifier()->m_auraname == SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE)
+ basepoints0 = triggerAmount;
+
Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER
? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL;
- uint32 triggered_spell_id = auraSpellInfo->EffectTriggerSpell[triggeredByAura->GetEffIndex()];
- Unit* target = !(procFlags & PROC_FLAG_HEAL) && IsPositiveSpell(triggered_spell_id) ? this : pVictim;
- int32 basepoints0 = 0;
-
- switch(auraSpellInfo->SpellFamilyName)
+ // Try handle uncnown trigger spells
+ if (sSpellStore.LookupEntry(trigger_spell_id)==NULL)
{
- case SPELLFAMILY_GENERIC:
- {
- switch(auraSpellInfo->Id)
- {
- // Aegis of Preservation
- case 23780:
- //Aegis Heal (instead non-existed triggered spell)
- triggered_spell_id = 23781;
- target = this;
- break;
- // Elune's Touch (moonkin mana restore)
- case 24905:
- {
- // Elune's Touch (instead non-existed triggered spell)
- triggered_spell_id = 33926;
- basepoints0 = int32(0.3f * GetTotalAttackPowerValue(BASE_ATTACK));
- target = this;
+ switch (auraSpellInfo->SpellFamilyName)
+ {
+ case SPELLFAMILY_GENERIC:
+ //if (auraSpellInfo->Id==59532) // Abandon Passengers on Poly
+ //if (auraSpellInfo->Id==54775) // Abandon Vehicle on Poly
+ //if (auraSpellInfo->Id==34082) // Advantaged State (DND)
+ if (auraSpellInfo->Id == 23780) // Aegis of Preservation (Aegis of Preservation trinket)
+ trigger_spell_id = 23781;
+ //else if (auraSpellInfo->Id==43504) // Alterac Valley OnKill Proc Aura
+ //else if (auraSpellInfo->Id == 48876) // Beast's Mark
+ //{
+ // trigger_spell_id = 48877;
+ //}
+ //else if (auraSpellInfo->Id == 59237) // Beast's Mark
+ //{
+ // trigger_spell_id = 59233;
+ //}
+ //else if (auraSpellInfo->Id==46939) // Black Bow of the Betrayer
+ //{
+ // trigger_spell_id = 29471; // gain mana
+ // 27526; // drain mana if possible
+ //}
+ //else if (auraSpellInfo->Id==50844) // Blood Mirror
+ //else if (auraSpellInfo->Id==54476) // Blood Presence
+ //else if (auraSpellInfo->Id==50689) // Blood Presence (Rank 1)
+ //else if (auraSpellInfo->Id==37030) // Chaotic Temperament
+ //else if (auraSpellInfo->Id==52856) // Charge
+ else if (auraSpellInfo->Id==43820) // Charm of the Witch Doctor (Amani Charm of the Witch Doctor trinket)
+ {
+ // Pct value stored in dummy
+ basepoints0 = pVictim->GetCreateHealth() * auraSpellInfo->EffectBasePoints[1] / 100;
+ target = pVictim;
break;
}
- // Enlightenment
- case 29601:
- {
- // only for cast with mana price
- if(!procSpell || procSpell->powerType!=POWER_MANA || procSpell->manaCost==0 && procSpell->ManaCostPercentage==0 && procSpell->manaCostPerlevel==0)
- return false;
- break; // fall through to normal cast
- }
- // Health Restore
- case 33510:
+ //else if (auraSpellInfo->Id==41248) // Consuming Strikes
+ // trigger_spell_id = 41249;
+ //else if (auraSpellInfo->Id==45205) // Copy Offhand Weapon
+ //else if (auraSpellInfo->Id==57594) // Copy Ranged Weapon
+ //else if (auraSpellInfo->Id==41054) // Copy Weapon
+ // trigger_spell_id = 41055;
+ //else if (auraSpellInfo->Id==45343) // Dark Flame Aura
+ //else if (auraSpellInfo->Id==47300) // Dark Flame Aura
+ else if (auraSpellInfo->Id==57345) // Darkmoon Card: Greatness
+ {
+ uint32 stat = 0;
+ // strength
+ if (GetStat(STAT_STRENGTH) > stat) { trigger_spell_id = 60229;stat = GetStat(STAT_STRENGTH); }
+ // agility
+ if (GetStat(STAT_AGILITY) > stat) { trigger_spell_id = 60233;stat = GetStat(STAT_AGILITY); }
+ // intellect
+ if (GetStat(STAT_INTELLECT)> stat) { trigger_spell_id = 60234;stat = GetStat(STAT_INTELLECT);}
+ // spirit
+ if (GetStat(STAT_SPIRIT) > stat) { trigger_spell_id = 60235;stat = GetStat(STAT_SPIRIT); }
+ }
+ //else if (auraSpellInfo->Id==31255) // Deadly Swiftness (Rank 1)
+ //else if (auraSpellInfo->Id==5301) // Defensive State (DND)
+ //else if (auraSpellInfo->Id==13358) // Defensive State (DND)
+ //else if (auraSpellInfo->Id==16092) // Defensive State (DND)
+ //else if (auraSpellInfo->Id==24949) // Defensive State 2 (DND)
+ //else if (auraSpellInfo->Id==40329) // Demo Shout Sensor
+ else if (auraSpellInfo->Id == 33896) // Desperate Defense (Stonescythe Whelp, Stonescythe Alpha, Stonescythe Ambusher)
+ trigger_spell_id = 33898;
+ //else if (auraSpellInfo->Id==18943) // Double Attack
+ //else if (auraSpellInfo->Id==19194) // Double Attack
+ //else if (auraSpellInfo->Id==19817) // Double Attack
+ //else if (auraSpellInfo->Id==19818) // Double Attack
+ //else if (auraSpellInfo->Id==22835) // Drunken Rage
+ // trigger_spell_id = 14822;
+ /*
+ else if (auraSpellInfo->SpellIconID==191) // Elemental Response
{
- // at melee hit call std triggered spell
- if(procFlags & PROC_FLAG_HIT_MELEE)
- break; // fall through to normal cast
-
- // Mark of Conquest - else (at range hit) called custom case
- triggered_spell_id = 39557;
- target = this;
- break;
+ switch (auraSpellInfo->Id && auraSpellInfo->AttributesEx==0)
+ {
+ case 34191:
+ case 34329:
+ case 34524:
+ case 34582:
+ case 36733:
+ break;
+ default:
+ sLog.outError("Unit::HandleProcTriggerSpell: Spell %u miss posibly Elemental Response",auraSpellInfo->Id);
+ return false;
+ }
+ //This generic aura self-triggers a different spell for each school of magic that lands on the wearer:
+ switch (procSpell->School)
+ {
+ case SPELL_SCHOOL_FIRE: trigger_spell_id = 34192; break;
+ case SPELL_SCHOOL_FROST: trigger_spell_id = 34193; break;
+ case SPELL_SCHOOL_ARCANE:trigger_spell_id = 34194; break;
+ case SPELL_SCHOOL_NATURE:trigger_spell_id = 34195; break;
+ case SPELL_SCHOOL_SHADOW:trigger_spell_id = 34196; break;
+ case SPELL_SCHOOL_HOLY: trigger_spell_id = 34197; break;
+ case SPELL_SCHOOL_NORMAL:trigger_spell_id = 34198; break;
+ default:
+ sLog.outError("Unit::HandleProcTriggerSpell: Spell %u Elemental Response wrong school",auraSpellInfo->Id);
+ return false;
+ }
}
- // Shaleskin
- case 36576:
- return true; // nothing to do
- // Forgotten Knowledge (Blade of Wizardry)
- case 38319:
- // only for harmful enemy targeted spell
- if(!pVictim || pVictim==this || !procSpell || IsPositiveSpell(procSpell->Id))
- return false;
- break; // fall through to normal cast
- // Aura of Wrath (Darkmoon Card: Wrath trinket bonus)
- case 39442:
- {
- // proc only at non-crit hits
- if(procFlags & (PROC_FLAG_CRIT_MELEE|PROC_FLAG_CRIT_RANGED|PROC_FLAG_CRIT_SPELL))
- return false;
- break; // fall through to normal cast
+ */
+ //else if (auraSpellInfo->Id==40364) // Entangling Roots Sensor
+ //else if (auraSpellInfo->Id==33207) // Gossip NPC Periodic - Fidget
+ //else if (auraSpellInfo->Id==50051) // Ethereal Pet Aura
+ //else if (auraSpellInfo->Id==35321) // Gushing Wound
+ //else if (auraSpellInfo->Id==38363) // Gushing Wound
+ //else if (auraSpellInfo->Id==39215) // Gushing Wound
+ //else if (auraSpellInfo->Id==44527) // Hate Monster (Spar Buddy) (30 sec)
+ //else if (auraSpellInfo->Id==44819) // Hate Monster (Spar Buddy) (>30% Health)
+ //else if (auraSpellInfo->Id==44526) // Hate Monster (Spar) (30 sec)
+ //else if (auraSpellInfo->Id==44820) // Hate Monster (Spar) (<30%)
+ //else if (auraSpellInfo->Id==49059) // Horde, Hate Monster (Spar Buddy) (>30% Health)
+ //else if (auraSpellInfo->Id==40250) // Improved Duration
+ //else if (auraSpellInfo->Id==59288) // Infra-Green Shield
+ //else if (auraSpellInfo->Id==54072) // Knockback Ball Passive
+ else if (auraSpellInfo->Id==27522 || auraSpellInfo->Id==40336)
+ // Mana Drain Trigger
+ {
+ // On successful melee or ranged attack gain $29471s1 mana and if possible drain $27526s1 mana from the target.
+ if (this && this->isAlive())
+ CastSpell(this, 29471, true, castItem, triggeredByAura);
+ if (pVictim && pVictim->isAlive())
+ CastSpell(pVictim, 27526, true, castItem, triggeredByAura);
+ return true;
}
- // Augment Pain (Timbal's Focusing Crystal trinket bonus)
- case 45054:
+ //else if (auraSpellInfo->Id==55580) // Mana Link
+ //else if (auraSpellInfo->Id==45903) // Offensive State
+ //else if (auraSpellInfo->Id==44326) // Pure Energy Passive
+ //else if (auraSpellInfo->Id==43453) // Rune Ward
+ //else if (auraSpellInfo->Id== 7137) // Shadow Charge (Rank 1)
+ //else if (auraSpellInfo->Id==36576) // Shaleskin (Shaleskin Flayer, Shaleskin Ripper) 30023 trigger
+ //else if (auraSpellInfo->Id==34783) // Spell Reflection
+ //else if (auraSpellInfo->Id==36096) // Spell Reflection
+ //else if (auraSpellInfo->Id==57587) // Steal Ranged ()
+ //else if (auraSpellInfo->Id==36207) // Steal Weapon
+ //else if (auraSpellInfo->Id== 7377) // Take Immune Periodic Damage <Not Working>
+ //else if (auraSpellInfo->Id==35205) // Vanish
+ //else if (auraSpellInfo->Id==42730) // Woe Strike
+ //else if (auraSpellInfo->Id==59735) // Woe Strike
+ //else if (auraSpellInfo->Id==46146) // [PH] Ahune Spanky Hands
+ break;
+ case SPELLFAMILY_MAGE:
+ if (auraSpellInfo->SpellIconID == 2127) // Blazing Speed
{
- if(!procSpell)
- return false;
-
- //only periodic damage can trigger spell
- bool found = false;
- for(int j = 0; j < 3; ++j)
+ switch (auraSpellInfo->Id)
{
- if( procSpell->EffectApplyAuraName[j]==SPELL_AURA_PERIODIC_DAMAGE ||
- procSpell->EffectApplyAuraName[j]==SPELL_AURA_PERIODIC_DAMAGE_PERCENT ||
- procSpell->EffectApplyAuraName[j]==SPELL_AURA_PERIODIC_LEECH )
- {
- found = true;
+ case 31641: // Rank 1
+ case 31642: // Rank 2
+ trigger_spell_id = 31643;
break;
- }
+ default:
+ sLog.outError("Unit::HandleProcTriggerSpell: Spell %u miss posibly Blazing Speed",auraSpellInfo->Id);
+ return false;
}
- if(!found)
- return false;
-
- break; // fall through to normal cast
}
- // Evasive Maneuvers (Commendation of Kael'thas)
- case 45057:
+ break;
+ case SPELLFAMILY_WARRIOR:
+ if (auraSpellInfo->Id == 50421) // Scent of Blood
+ trigger_spell_id = 50422;
+ break;
+ case SPELLFAMILY_WARLOCK:
+ {
+ // Pyroclasm
+ if (auraSpellInfo->SpellIconID == 1137)
{
- // damage taken that reduces below 35% health
- // does NOT mean you must have been >= 35% before
- if (int32(GetHealth())-int32(damage) >= int32(GetMaxHealth()*0.35f))
+ if(!pVictim || !pVictim->isAlive() || pVictim == this || procSpell == NULL)
+ return false;
+ // Calculate spell tick count for spells
+ uint32 tick = 1; // Default tick = 1
+
+ // Hellfire have 15 tick
+ if (procSpell->SpellFamilyFlags[0]&0x40)
+ tick = 15;
+ // Rain of Fire have 4 tick
+ else if (procSpell->SpellFamilyFlags[0]&0x20)
+ tick = 4;
+ else
return false;
- break; // fall through to normal cast
- }
- }
- switch(triggered_spell_id)
- {
- // Setup
- case 15250:
- {
- // applied only for main target
- if(!pVictim || pVictim != getVictim())
+ // Calculate chance = baseChance / tick
+ float chance = 0;
+ switch (auraSpellInfo->Id)
+ {
+ case 18096: chance = 13.0f / tick; break;
+ case 18073: chance = 26.0f / tick; break;
+ }
+ // Roll chance
+ if (!roll_chance_f(chance))
return false;
- // continue normal case
- break;
+ trigger_spell_id = 18093;
}
- // Shamanistic Rage triggered spell
- case 30824:
- basepoints0 = int32(GetTotalAttackPowerValue(BASE_ATTACK)*triggeredByAura->GetModifier()->m_amount/100);
- break;
- }
- break;
- }
- case SPELLFAMILY_MAGE:
- {
- switch(auraSpellInfo->SpellIconID)
- {
- // Blazing Speed
- case 2127:
- //Blazing Speed (instead non-existed triggered spell)
- triggered_spell_id = 31643;
- target = this;
- break;
- }
- switch(auraSpellInfo->Id)
- {
- // Persistent Shield (Scarab Brooch)
- case 26467:
- basepoints0 = int32(damage * 0.15f);
- break;
- }
- break;
- }
- case SPELLFAMILY_WARRIOR:
- {
- //Rampage
- if((auraSpellInfo->SpellFamilyFlags & 0x100000) && auraSpellInfo->SpellIconID==2006)
- {
- //all ranks have effect[0]==AURA (Proc Trigger Spell, non-existed)
- //and effect[1]==TriggerSpell
- if(auraSpellInfo->Effect[1]!=SPELL_EFFECT_TRIGGER_SPELL)
+ // Drain Soul
+ else if (auraSpellInfo->SpellFamilyFlags[0] & 0x4000)
{
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u have wrong effect in RM",triggeredByAura->GetSpellProto()->Id);
+ Unit::AuraList const& mAddFlatModifier = GetAurasByType(SPELL_AURA_ADD_FLAT_MODIFIER);
+ for(Unit::AuraList::const_iterator i = mAddFlatModifier.begin(); i != mAddFlatModifier.end(); ++i)
+ {
+ if ((*i)->GetModifier()->m_miscvalue == SPELLMOD_CHANCE_OF_SUCCESS && (*i)->GetSpellProto()->SpellIconID == 113)
+ {
+ int32 value2 = CalculateSpellDamage((*i)->GetSpellProto(),2,(*i)->GetSpellProto()->EffectBasePoints[2],this);
+ // 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;
}
- triggered_spell_id = auraSpellInfo->EffectTriggerSpell[1];
- break; // fall through to normal cast
- }
- break;
- }
- case SPELLFAMILY_WARLOCK:
- {
- // Pyroclasm
- if(auraSpellInfo->SpellFamilyFlags == 0x0000000000000000 && auraSpellInfo->SpellIconID==1137)
- {
- // last case for Hellfire that damage caster also but don't must stun caster
- if( pVictim == this )
- return false;
-
- // custom chance
- float chance = 0;
- switch (triggeredByAura->GetId())
+ // Nether Protection
+ else if (auraSpellInfo->SpellIconID == 1985)
{
- case 18096: chance = 13.0f; break;
- case 18073: chance = 26.0f; break;
- }
- if (!roll_chance_f(chance))
- return false;
-
- // Pyroclasm (instead non-existed triggered spell)
- triggered_spell_id = 18093;
- target = pVictim;
- break;
- }
- // Drain Soul
- if(auraSpellInfo->SpellFamilyFlags & 0x0000000000004000)
- {
- bool found = false;
- Unit::AuraList const& mAddFlatModifier = GetAurasByType(SPELL_AURA_ADD_FLAT_MODIFIER);
- for(Unit::AuraList::const_iterator i = mAddFlatModifier.begin(); i != mAddFlatModifier.end(); ++i)
- {
- //Improved Drain Soul
- if ((*i)->GetModifier()->m_miscvalue == SPELLMOD_CHANCE_OF_SUCCESS && (*i)->GetSpellProto()->SpellIconID == 113)
+ if (!procSpell)
+ return false;
+ switch(GetFirstSchoolInMask(GetSpellSchoolMask(procSpell)))
{
- int32 value2 = CalculateSpellDamage((*i)->GetSpellProto(),2,(*i)->GetSpellProto()->EffectBasePoints[2],this);
- basepoints0 = value2 * GetMaxPower(POWER_MANA) / 100;
- // Drain Soul
- CastCustomSpell(this, 18371, &basepoints0, NULL, NULL, true, castItem, triggeredByAura);
- break;
+ case SPELL_SCHOOL_NORMAL:
+ case SPELL_SCHOOL_HOLY:
+ return false; // ignore
+ 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;
}
}
- // Not remove charge (aura removed on death in any cases)
- // Need for correct work Drain Soul SPELL_AURA_CHANNEL_DEATH_ITEM aura
- return false;
+ break;
}
- break;
- }
- case SPELLFAMILY_PRIEST:
- {
- //Blessed Recovery
- if(auraSpellInfo->SpellFamilyFlags == 0x00000000LL && auraSpellInfo->SpellIconID==1875)
+ case SPELLFAMILY_PRIEST:
{
- switch (triggeredByAura->GetSpellProto()->Id)
+ // Greater Heal Refund
+ if (auraSpellInfo->Id==37594)
+ trigger_spell_id = 37595;
+ // Blessed Recovery
+ else if (auraSpellInfo->SpellIconID == 1875)
{
- case 27811: triggered_spell_id = 27813; break;
- case 27815: triggered_spell_id = 27817; break;
- case 27816: triggered_spell_id = 27818; break;
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in BR",triggeredByAura->GetSpellProto()->Id);
- return false;
- }
-
- int32 heal_amount = damage * triggeredByAura->GetModifier()->m_amount / 100;
- basepoints0 = heal_amount/3;
- target = this;
- break;
- }
- // Shadowguard
- if((auraSpellInfo->SpellFamilyFlags & 0x80000000LL) && auraSpellInfo->SpellVisual==7958)
- {
- switch(triggeredByAura->GetSpellProto()->Id)
- {
- case 18137:
- triggered_spell_id = 28377; break; // Rank 1
- case 19308:
- triggered_spell_id = 28378; break; // Rank 2
- case 19309:
- triggered_spell_id = 28379; break; // Rank 3
- case 19310:
- triggered_spell_id = 28380; break; // Rank 4
- case 19311:
- triggered_spell_id = 28381; break; // Rank 5
- case 19312:
- triggered_spell_id = 28382; break; // Rank 6
- case 25477:
- triggered_spell_id = 28385; break; // Rank 7
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in SG",triggeredByAura->GetSpellProto()->Id);
+ 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:
+ sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in BR", auraSpellInfo->Id);
return false;
+ }
+ basepoints0 = damage * triggerAmount / 100 / 3;
+ target = this;
}
- target = pVictim;
break;
}
- break;
- }
- case SPELLFAMILY_DRUID:
- {
- switch(auraSpellInfo->Id)
+ case SPELLFAMILY_DRUID:
{
- // Leader of the Pack (triggering Improved Leader of the Pack heal)
- case 24932:
- {
- if (triggeredByAura->GetModifier()->m_amount == 0)
- return false;
- basepoints0 = triggeredByAura->GetModifier()->m_amount * GetMaxHealth() / 100;
- triggered_spell_id = 34299;
- break;
- };
- // Druid Forms Trinket (Druid Tier5 Trinket, triggers different spells per Form)
- case 37336:
+ // Druid Forms Trinket
+ if (auraSpellInfo->Id==37336)
{
switch(m_form)
{
+ case FORM_NONE: trigger_spell_id = 37344;break;
+ case FORM_CAT: trigger_spell_id = 37341;break;
case FORM_BEAR:
- case FORM_DIREBEAR:
- triggered_spell_id=37340; break;// Ursine Blessing
- case FORM_CAT:
- triggered_spell_id=37341; break;// Feline Blessing
- case FORM_TREE:
- triggered_spell_id=37342; break;// Slyvan Blessing
- case FORM_MOONKIN:
- triggered_spell_id=37343; break;// Lunar Blessing
- case FORM_NONE:
- triggered_spell_id=37344; break;// Cenarion Blessing (for caster form, except FORM_MOONKIN)
+ case FORM_DIREBEAR: trigger_spell_id = 37340;break;
+ case FORM_TREE: trigger_spell_id = 37342;break;
+ case FORM_MOONKIN: trigger_spell_id = 37343;break;
default:
return false;
}
-
- target = this;
- break;
}
- }
- break;
- }
- case SPELLFAMILY_ROGUE:
- {
- if(auraSpellInfo->SpellFamilyFlags == 0x0000000000000000LL)
- {
- switch(auraSpellInfo->SpellIconID)
+ //else if (auraSpellInfo->Id==40363)// Entangling Roots ()
+ // trigger_spell_id = ????;
+ // Leader of the Pack
+ else if (auraSpellInfo->Id == 24932)
{
- // Combat Potency
- case 2260:
- {
- // skip non offhand attacks
- if(attackType!=OFF_ATTACK)
- return false;
- break; // fall through to normal cast
- }
+ if (triggerAmount == 0)
+ return false;
+ basepoints0 = triggerAmount * GetMaxHealth() / 100;
+ trigger_spell_id = 34299;
}
+ break;
}
- break;
- }
- case SPELLFAMILY_PALADIN:
- {
- if(auraSpellInfo->SpellFamilyFlags == 0x00000000LL)
+ case SPELLFAMILY_HUNTER:
+ break;
+ case SPELLFAMILY_PALADIN:
{
- switch(auraSpellInfo->Id)
+ /*
+ // Blessed Life
+ if (auraSpellInfo->SpellIconID == 2137)
{
- // Lightning Capacitor
- case 37657:
- {
- // trinket ProcTriggerSpell but for safe checks for player
- if(!castItem || !pVictim || !pVictim->isAlive() || GetTypeId()!=TYPEID_PLAYER)
- return false;
-
- if(((Player*)this)->HasSpellCooldown(37657))
- return false;
-
- // stacking
- CastSpell(this, 37658, true, castItem, triggeredByAura);
- // 2.5s cooldown before it can stack again, current system allow 1 sec step in cooldown
- ((Player*)this)->AddSpellCooldown(37657,0,time(NULL)+(roll_chance_i(50) ? 2 : 3));
-
- // counting
- Aura * dummy = GetDummyAura(37658);
- if (!dummy)
- return false;
-
- // release at 3 aura in stack
- if(dummy->GetStackAmount() <= 2)
- return true; // main triggered spell casted anyway
-
- RemoveAurasDueToSpell(37658);
- CastSpell(pVictim, 37661, true, castItem, triggeredByAura);
- return true;
- }
- // Healing Discount
- case 37705:
- // Healing Trance (instead non-existed triggered spell)
- triggered_spell_id = 37706;
- target = this;
- break;
- // HoTs on Heals (Fel Reaver's Piston trinket)
- case 38299:
+ switch (auraSpellInfo->Id)
{
- // at direct heal effect
- if(!procSpell || !IsSpellHaveEffect(procSpell,SPELL_EFFECT_HEAL))
+ case 31828: // Rank 1
+ case 31829: // Rank 2
+ case 31830: // Rank 3
+ break;
+ default:
+ sLog.outError("Unit::HandleProcTriggerSpell: Spell %u miss posibly Blessed Life", auraSpellInfo->Id);
return false;
-
- // single proc at time
- AuraList const& scAuras = GetSingleCastAuras();
- for(AuraList::const_iterator itr = scAuras.begin(); itr != scAuras.end(); ++itr)
- if((*itr)->GetId()==triggered_spell_id)
- return false;
-
- // positive cast at victim instead self
- target = pVictim;
- break;
}
}
- switch(auraSpellInfo->SpellIconID)
+ */
+ // Healing Discount
+ if (auraSpellInfo->Id==37705)
{
- case 241:
- {
- switch(auraSpellInfo->EffectTriggerSpell[0])
- {
- //Illumination
- case 18350:
- {
- if(!procSpell)
- return false;
-
- // procspell is triggered spell but we need mana cost of original casted spell
- uint32 originalSpellId = procSpell->Id;
-
- // Holy Shock
- if(procSpell->SpellFamilyName == SPELLFAMILY_PALADIN)
- {
- if(procSpell->SpellFamilyFlags & 0x0001000000000000LL)
- {
- 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;
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in HShock",procSpell->Id);
- return false;
- }
- }
- }
-
- SpellEntry const *originalSpell = sSpellStore.LookupEntry(originalSpellId);
- if(!originalSpell)
- {
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u unknown but selected as original in Illu",originalSpellId);
- return false;
- }
-
- // percent stored in effect 1 (class scripts) base points
- int32 percent = auraSpellInfo->EffectBasePoints[1]+1;
-
- basepoints0 = originalSpell->manaCost*percent/100;
- triggered_spell_id = 20272;
- target = this;
- break;
- }
- }
- break;
- }
+ trigger_spell_id = 37706;
+ target = this;
}
- }
- if(auraSpellInfo->SpellFamilyFlags & 0x00080000)
- {
- switch(auraSpellInfo->SpellIconID)
+ // Soul Preserver
+ if (auraSpellInfo->Id==60510)
+ {
+ trigger_spell_id = 60515;
+ target = this;
+ }
+ // Illumination
+ else if (auraSpellInfo->SpellIconID==241)
{
- //Judgement of Wisdom (overwrite non existing triggered spell call in spell.dbc
- case 206:
+ if(!procSpell)
+ return false;
+ // procspell is triggered spell but we need mana cost of original casted spell
+ uint32 originalSpellId = procSpell->Id;
+ // Holy Shock heal
+ if(procSpell->SpellFamilyFlags[1] & 0x00010000)
{
- if(!pVictim || !pVictim->isAlive())
- return false;
-
- switch(triggeredByAura->GetSpellProto()->Id)
+ switch(procSpell->Id)
{
- case 20186:
- triggered_spell_id = 20268; // Rank 1
- break;
- case 20354:
- triggered_spell_id = 20352; // Rank 2
- break;
- case 20355:
- triggered_spell_id = 20353; // Rank 3
- break;
- case 27164:
- triggered_spell_id = 27165; // Rank 4
- break;
+ 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:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in JoW",triggeredByAura->GetSpellProto()->Id);
- return false;
+ sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in HShock",procSpell->Id);
+ return false;
}
-
- pVictim->CastSpell(pVictim,triggered_spell_id,true,castItem,triggeredByAura,GetGUID());
- return true; // no hidden cooldown
}
- //Judgement of Light
- case 299:
+ SpellEntry const *originalSpell = sSpellStore.LookupEntry(originalSpellId);
+ if(!originalSpell)
{
- if(!pVictim || !pVictim->isAlive())
- return false;
-
- // overwrite non existing triggered spell call in spell.dbc
- switch(triggeredByAura->GetSpellProto()->Id)
- {
- case 20185:
- triggered_spell_id = 20267; // Rank 1
- break;
- case 20344:
- triggered_spell_id = 20341; // Rank 2
- break;
- case 20345:
- triggered_spell_id = 20342; // Rank 3
- break;
- case 20346:
- triggered_spell_id = 20343; // Rank 4
- break;
- case 27162:
- triggered_spell_id = 27163; // Rank 5
- break;
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in JoL",triggeredByAura->GetSpellProto()->Id);
- return false;
- }
- pVictim->CastSpell(pVictim,triggered_spell_id,true,castItem,triggeredByAura,GetGUID());
- return true; // no hidden cooldown
+ sLog.outError("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 = originalSpell->manaCost + originalSpell->ManaCostPercentage * GetCreateMana() / 100;
+ basepoints0 = cost*(auraSpellInfo->EffectBasePoints[1]+1)/100;
+ trigger_spell_id = 20272;
+ target = this;
}
- }
- // custom check for proc spell
- switch(auraSpellInfo->Id)
- {
- // Bonus Healing (item spell)
- case 40971:
+ // Lightning Capacitor
+ else if (auraSpellInfo->Id==37657)
{
if(!pVictim || !pVictim->isAlive())
return false;
+ // stacking
+ CastSpell(this, 37658, true, NULL, triggeredByAura);
- // bonus if health < 50%
- if(pVictim->GetHealth() >= pVictim->GetMaxHealth()*triggeredByAura->GetModifier()->m_amount/100)
+ Aura * dummy = GetDummyAura(37658);
+ // release at 3 aura in stack (cont contain in basepoint of trigger aura)
+ if(!dummy || dummy->GetStackAmount() < triggerAmount)
return false;
- // cast at target positive spell
+ RemoveAurasDueToSpell(37658);
+ trigger_spell_id = 37661;
target = pVictim;
- break;
}
- }
- switch(triggered_spell_id)
- {
- // Seal of Command
- case 20424:
- // prevent chain of triggered spell from same triggered spell
- if(procSpell && procSpell->Id==20424)
+ // Thunder Capacitor
+ else if (auraSpellInfo->Id == 54841)
+ {
+ if(!pVictim || !pVictim->isAlive())
return false;
- break;
+ // stacking
+ CastSpell(this, 54842, true, NULL, triggeredByAura);
+
+ // counting
+ Aura * dummy = GetDummyAura(54842);
+ // release at 3 aura in stack (cont contain in basepoint of trigger aura)
+ if(!dummy || dummy->GetStackAmount() < triggerAmount)
+ return false;
+
+ RemoveAurasDueToSpell(54842);
+ trigger_spell_id = 54843;
+ target = pVictim;
+ }
+ break;
}
- break;
- }
- case SPELLFAMILY_SHAMAN:
- {
- if(auraSpellInfo->SpellFamilyFlags == 0x0000000000000000)
+ case SPELLFAMILY_SHAMAN:
{
- switch(auraSpellInfo->SpellIconID)
+ // Lightning Shield (overwrite non existing triggered spell call in spell.dbc
+ if(auraSpellInfo->SpellFamilyFlags[0] & 0x400)
{
- case 19:
- {
- switch(auraSpellInfo->Id)
- {
- case 23551: // Lightning Shield - Tier2: 8 pieces proc shield
- {
- // Lightning Shield (overwrite non existing triggered spell call in spell.dbc)
- triggered_spell_id = 23552;
- target = pVictim;
- break;
- }
- case 23552: // Lightning Shield - trigger shield damage
- {
- // Lightning Shield (overwrite non existing triggered spell call in spell.dbc)
- triggered_spell_id = 27635;
- target = pVictim;
- break;
- }
- }
- break;
- }
- // Mana Surge (Shaman T1 bonus)
- case 87:
+ switch(auraSpellInfo->Id)
{
- if(!procSpell)
- return false;
-
- basepoints0 = procSpell->manaCost * 35/100;
- triggered_spell_id = 23571;
- target = this;
- break;
+ case 324: // Rank 1
+ trigger_spell_id = 26364; break;
+ case 325: // Rank 2
+ trigger_spell_id = 26365; break;
+ case 905: // Rank 3
+ trigger_spell_id = 26366; break;
+ case 945: // Rank 4
+ trigger_spell_id = 26367; break;
+ case 8134: // Rank 5
+ trigger_spell_id = 26369; break;
+ case 10431: // Rank 6
+ trigger_spell_id = 26370; break;
+ case 10432: // Rank 7
+ trigger_spell_id = 26363; break;
+ case 25469: // Rank 8
+ trigger_spell_id = 26371; break;
+ case 25472: // Rank 9
+ trigger_spell_id = 26372; break;
+ case 49280: // Rank 10
+ trigger_spell_id = 49278; break;
+ case 49281: // Rank 11
+ trigger_spell_id = 49279; break;
+ default:
+ sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in LShield", auraSpellInfo->Id);
+ return false;
}
- //Nature's Guardian
- case 2013:
- {
- if(GetTypeId()!=TYPEID_PLAYER)
- return false;
-
- // damage taken that reduces below 30% health
- // does NOT mean you must have been >= 30% before
- if (10*(int32(GetHealth())-int32(damage)) >= 3*GetMaxHealth())
- return false;
-
- triggered_spell_id = 31616;
+ }
+ // Lightning Shield (The Ten Storms set)
+ else if (auraSpellInfo->Id == 23551)
+ {
+ trigger_spell_id = 23552;
+ target = pVictim;
+ }
+ // Damage from Lightning Shield (The Ten Storms set)
+ else if (auraSpellInfo->Id == 23552)
+ trigger_spell_id = 27635;
+ // Mana Surge (The Earthfury set)
+ else if (auraSpellInfo->Id == 23572)
+ {
+ if(!procSpell)
+ return false;
+ basepoints0 = procSpell->manaCost * 35 / 100;
+ trigger_spell_id = 23571;
+ target = this;
+ }
+ // Nature's Guardian
+ else if (auraSpellInfo->SpellIconID == 2013)
+ {
+ // Check health condition - should drop to less 30% (damage deal after this!)
+ if (!(10*(int32(GetHealth() - damage)) < 3 * GetMaxHealth()))
+ return false;
- // need check cooldown now
- if( cooldown && ((Player*)this)->HasSpellCooldown(triggered_spell_id))
- return false;
+ if(pVictim && pVictim->isAlive())
+ pVictim->getThreatManager().modifyThreatPercent(this,-10);
- basepoints0 = triggeredByAura->GetModifier()->m_amount * GetMaxHealth() / 100;
- target = this;
- if(pVictim && pVictim->isAlive())
- pVictim->getThreatManager().modifyThreatPercent(this,-10);
- break;
- }
+ basepoints0 = triggerAmount * GetMaxHealth() / 100;
+ trigger_spell_id = 31616;
+ target = this;
}
- }
-
- // Water Shield (we can't set cooldown for main spell - it's player casted spell
- if((auraSpellInfo->SpellFamilyFlags & 0x0000002000000000LL) && auraSpellInfo->SpellVisual==7358)
- {
- target = this;
break;
}
-
- // Lightning Shield
- if((auraSpellInfo->SpellFamilyFlags & 0x00000400) && auraSpellInfo->SpellVisual==37)
- {
- // overwrite non existing triggered spell call in spell.dbc
- switch(triggeredByAura->GetSpellProto()->Id)
- {
- case 324:
- triggered_spell_id = 26364; break; // Rank 1
- case 325:
- triggered_spell_id = 26365; break; // Rank 2
- case 905:
- triggered_spell_id = 26366; break; // Rank 3
- case 945:
- triggered_spell_id = 26367; break; // Rank 4
- case 8134:
- triggered_spell_id = 26369; break; // Rank 5
- case 10431:
- triggered_spell_id = 26370; break; // Rank 6
- case 10432:
- triggered_spell_id = 26363; break; // Rank 7
- case 25469:
- triggered_spell_id = 26371; break; // Rank 8
- case 25472:
- triggered_spell_id = 26372; break; // Rank 9
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in LShield",triggeredByAura->GetSpellProto()->Id);
+ case SPELLFAMILY_DEATHKNIGHT:
+ {
+ // Acclimation
+ if (auraSpellInfo->SpellIconID == 1930)
+ {
+ if (!procSpell)
return false;
+ switch(GetFirstSchoolInMask(GetSpellSchoolMask(procSpell)))
+ {
+ 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 = 54373; break;
+ default:
+ return false;
+ }
+ }
+ // Blood Presence
+ else if (auraSpellInfo->Id == 48266)
+ {
+ if (GetTypeId() != TYPEID_PLAYER)
+ return false;
+ if (!((Player*)this)->isHonorOrXPTarget(pVictim))
+ return false;
+ trigger_spell_id = 50475;
+ basepoints0 = damage * triggerAmount / 100;
}
-
- target = pVictim;
break;
}
- break;
- }
- }
-
- // standard non-dummy case
- if(!triggered_spell_id)
- {
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u have 0 in EffectTriggered[%d], not handled custom case?",auraSpellInfo->Id,triggeredByAura->GetEffIndex());
- return false;
- }
-
- SpellEntry const* triggerEntry = sSpellStore.LookupEntry(triggered_spell_id);
-
- if(!triggerEntry)
- {
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u have not existed EffectTriggered[%d]=%u, not handled custom case?",auraSpellInfo->Id,triggeredByAura->GetEffIndex(),triggered_spell_id);
- return false;
- }
-
- // not allow proc extra attack spell at extra attack
- if( m_extraAttacks && IsSpellHaveEffect(triggerEntry,SPELL_EFFECT_ADD_EXTRA_ATTACKS) )
- return false;
-
- if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(triggered_spell_id))
- return false;
-
- // default case
- if(!target || target!=this && !target->isAlive())
- return false;
-
- if(basepoints0)
- CastCustomSpell(target,triggered_spell_id,&basepoints0,NULL,NULL,true,castItem,triggeredByAura);
- else
- CastSpell(target,triggered_spell_id,true,castItem,triggeredByAura);
-
- if( cooldown && GetTypeId()==TYPEID_PLAYER )
- ((Player*)this)->AddSpellCooldown(triggered_spell_id,0,time(NULL) + cooldown);
-
- return true;
-}
-*/
-
-bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlags, uint32 procEx, uint32 cooldown)
-{
- // Get triggered aura spell info
- SpellEntry const* auraSpellInfo = triggeredByAura->GetSpellProto();
-
- // Basepoints of trigger aura
- int32 triggerAmount = triggeredByAura->GetModifier()->m_amount;
-
- // Set trigger spell id, target, custom basepoints
- uint32 trigger_spell_id = auraSpellInfo->EffectTriggerSpell[triggeredByAura->GetEffIndex()];
- Unit* target = NULL;
- int32 basepoints0 = 0;
-
- Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER
- ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL;
-
- // Try handle uncnown trigger spells
- if (sSpellStore.LookupEntry(trigger_spell_id)==NULL)
- switch (auraSpellInfo->SpellFamilyName)
- {
- //=====================================================================
- // Generic class
- // ====================================================================
- // .....
- //=====================================================================
- case SPELLFAMILY_GENERIC:
-// if (auraSpellInfo->Id==34082) // Advantaged State (DND)
-// trigger_spell_id = ???;
- if (auraSpellInfo->Id == 23780) // Aegis of Preservation (Aegis of Preservation trinket)
- trigger_spell_id = 23781;
-// else if (auraSpellInfo->Id==43504) // Alterac Valley OnKill Proc Aura
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==37030) // Chaotic Temperament
-// trigger_spell_id = ;
- else if (auraSpellInfo->Id==43820) // Charm of the Witch Doctor (Amani Charm of the Witch Doctor trinket)
- {
- // Pct value stored in dummy
- basepoints0 = pVictim->GetCreateHealth() * auraSpellInfo->EffectBasePoints[1] / 100;
- target = pVictim;
- break;
- }
-// else if (auraSpellInfo->Id==41248) // Consuming Strikes
-// trigger_spell_id = 41249;
-// else if (auraSpellInfo->Id==41054) // Copy Weapon
-// trigger_spell_id = 41055;
-// else if (auraSpellInfo->Id==31255) // Deadly Swiftness (Rank 1)
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==5301) // Defensive State (DND)
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==13358) // Defensive State (DND)
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==16092) // Defensive State (DND)
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==24949) // Defensive State 2 (DND)
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==40329) // Demo Shout Sensor
-// trigger_spell_id = ;
- // Desperate Defense (Stonescythe Whelp, Stonescythe Alpha, Stonescythe Ambusher)
- else if (auraSpellInfo->Id == 33896)
- trigger_spell_id = 33898;
-// else if (auraSpellInfo->Id==18943) // Double Attack
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==19194) // Double Attack
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==19817) // Double Attack
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==19818) // Double Attack
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==22835) // Drunken Rage
-// trigger_spell_id = 14822;
- /*
- else if (auraSpellInfo->SpellIconID==191) // Elemental Response
- {
- switch (auraSpellInfo->Id && auraSpellInfo->AttributesEx==0)
- {
- case 34191:
- case 34329:
- case 34524:
- case 34582:
- case 36733:break;
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u miss posibly Elemental Response",auraSpellInfo->Id);
- return false;
- }
- //This generic aura self-triggers a different spell for each school of magic that lands on the wearer:
- switch (procSpell->School)
- {
- case SPELL_SCHOOL_FIRE: trigger_spell_id = 34192;break;//Fire: 34192
- case SPELL_SCHOOL_FROST: trigger_spell_id = 34193;break;//Frost: 34193
- case SPELL_SCHOOL_ARCANE: trigger_spell_id = 34194;break;//Arcane: 34194
- case SPELL_SCHOOL_NATURE: trigger_spell_id = 34195;break;//Nature: 34195
- case SPELL_SCHOOL_SHADOW: trigger_spell_id = 34196;break;//Shadow: 34196
- case SPELL_SCHOOL_HOLY: trigger_spell_id = 34197;break;//Holy: 34197
- case SPELL_SCHOOL_NORMAL: trigger_spell_id = 34198;break;//Physical: 34198
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u Elemental Response wrong school",auraSpellInfo->Id);
- return false;
- }
- }*/
-// else if (auraSpellInfo->Id==6542) // Enraged Defense
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==40364) // Entangling Roots Sensor
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==33207) // Gossip NPC Periodic - Fidget
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==35321) // Gushing Wound
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==38363) // Gushing Wound
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==39215) // Gushing Wound
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==40250) // Improved Duration
-// trigger_spell_id = ;
- else if (auraSpellInfo->Id==27522) // Mana Drain Trigger
- {
- // On successful melee or ranged attack gain $29471s1 mana and if possible drain $27526s1 mana from the target.
- if (this && this->isAlive())
- CastSpell(this, 29471, true, castItem, triggeredByAura);
- if (pVictim && pVictim->isAlive())
- CastSpell(pVictim, 27526, true, castItem, triggeredByAura);
- return true;
- }
- else if (auraSpellInfo->Id==24905) // Moonkin Form (Passive)
- {
- // Elune's Touch (instead non-existed triggered spell) 30% from AP
- trigger_spell_id = 33926;
- basepoints0 = GetTotalAttackPowerValue(BASE_ATTACK) * 30 / 100;
- target = this;
- }
-// else if (auraSpellInfo->Id==43453) // Rune Ward
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==7137) // Shadow Charge (Rank 1)
-// trigger_spell_id = ;
- // Shaleskin (Shaleskin Flayer, Shaleskin Ripper) 30023 trigger
-// else if (auraSpellInfo->Id==36576)
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==34783) // Spell Reflection
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==36096) // Spell Reflection
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==36207) // Steal Weapon
-// trigger_spell_id = ;
-// else if (auraSpellInfo->Id==35205) // Vanish
- break;
- //=====================================================================
- // Mage
- //=====================================================================
- // Blazing Speed (Rank 1,2) trigger = 18350
- //=====================================================================
- case SPELLFAMILY_MAGE:
- // Blazing Speed
- if (auraSpellInfo->SpellIconID == 2127)
- {
- switch (auraSpellInfo->Id)
- {
- case 31641: // Rank 1
- case 31642: // Rank 2
- trigger_spell_id = 31643;
- break;
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u miss posibly Blazing Speed",auraSpellInfo->Id);
- return false;
- }
- }
- break;
- //=====================================================================
- // Warrior
- //=====================================================================
- // Rampage (Rank 1-3) trigger = 18350
- //=====================================================================
- case SPELLFAMILY_WARRIOR:
- // Rampage
- if (auraSpellInfo->SpellIconID == 2006 && auraSpellInfo->SpellFamilyFlags==0x100000)
- {
- switch(auraSpellInfo->Id)
- {
- case 29801: trigger_spell_id = 30029; break; // Rank 1
- case 30030: trigger_spell_id = 30031; break; // Rank 2
- case 30033: trigger_spell_id = 30032; break; // Rank 3
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in Rampage",auraSpellInfo->Id);
- return false;
- }
- }
- break;
- //=====================================================================
- // Warlock
- //=====================================================================
- // Pyroclasm trigger = 18350
- // Drain Soul (Rank 1-5) trigger = 0
- //=====================================================================
- case SPELLFAMILY_WARLOCK:
- {
- // Pyroclasm
- if (auraSpellInfo->SpellIconID == 1137)
- {
- if(!pVictim || !pVictim->isAlive() || pVictim == this || procSpell == NULL)
- return false;
- // Calculate spell tick count for spells
- uint32 tick = 1; // Default tick = 1
-
- // Hellfire have 15 tick
- if (procSpell->SpellFamilyFlags&0x0000000000000040LL)
- tick = 15;
- // Rain of Fire have 4 tick
- else if (procSpell->SpellFamilyFlags&0x0000000000000020LL)
- tick = 4;
- else
- return false;
-
- // Calculate chance = baseChance / tick
- float chance = 0;
- switch (auraSpellInfo->Id)
- {
- case 18096: chance = 13.0f / tick; break;
- case 18073: chance = 26.0f / tick; break;
- }
- // Roll chance
- if (!roll_chance_f(chance))
- return false;
-
- trigger_spell_id = 18093;
- }
- // Drain Soul
- else if (auraSpellInfo->SpellFamilyFlags & 0x0000000000004000LL)
- {
- Unit::AuraList const& mAddFlatModifier = GetAurasByType(SPELL_AURA_ADD_FLAT_MODIFIER);
- for(Unit::AuraList::const_iterator i = mAddFlatModifier.begin(); i != mAddFlatModifier.end(); ++i)
- {
- if ((*i)->GetModifier()->m_miscvalue == SPELLMOD_CHANCE_OF_SUCCESS && (*i)->GetSpellProto()->SpellIconID == 113)
- {
- int32 value2 = CalculateSpellDamage((*i)->GetSpellProto(),2,(*i)->GetSpellProto()->EffectBasePoints[2],this);
- basepoints0 = value2 * GetMaxPower(POWER_MANA) / 100;
- }
- }
- if ( basepoints0 == 0 )
- return false;
- trigger_spell_id = 18371;
- }
- break;
- }
- //=====================================================================
- // Priest
- //=====================================================================
- // Greater Heal Refund trigger = 18350
- // Blessed Recovery (Rank 1-3) trigger = 18350
- // Shadowguard (1-7) trigger = 28376
- //=====================================================================
- case SPELLFAMILY_PRIEST:
- {
- // Greater Heal Refund
- if (auraSpellInfo->Id==37594)
- trigger_spell_id = 37595;
- // Shadowguard
- else if(auraSpellInfo->SpellFamilyFlags==0x100080000000LL && auraSpellInfo->SpellVisual==7958)
- {
- switch(auraSpellInfo->Id)
- {
- case 18137: trigger_spell_id = 28377; break; // Rank 1
- case 19308: trigger_spell_id = 28378; break; // Rank 2
- case 19309: trigger_spell_id = 28379; break; // Rank 3
- case 19310: trigger_spell_id = 28380; break; // Rank 4
- case 19311: trigger_spell_id = 28381; break; // Rank 5
- case 19312: trigger_spell_id = 28382; break; // Rank 6
- case 25477: trigger_spell_id = 28385; break; // Rank 7
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in SG", auraSpellInfo->Id);
- return false;
- }
- }
- // Blessed Recovery
- else 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:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in BR", auraSpellInfo->Id);
- return false;
- }
- basepoints0 = damage * triggerAmount / 100 / 3;
- target = this;
- }
- break;
- }
- //=====================================================================
- // Druid
- // ====================================================================
- // Druid Forms Trinket trigger = 18350
- // Entangling Roots trigger = 30023
- // Leader of the Pack trigger = 18350
- //=====================================================================
- case SPELLFAMILY_DRUID:
- {
- // Druid Forms Trinket
- if (auraSpellInfo->Id==37336)
- {
- switch(m_form)
- {
- case 0: 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_TREE: trigger_spell_id = 37342;break;
- case FORM_MOONKIN: trigger_spell_id = 37343;break;
- default:
- return false;
- }
- }
-// else if (auraSpellInfo->Id==40363)// Entangling Roots ()
-// trigger_spell_id = ????;
- // Leader of the Pack
- else if (auraSpellInfo->Id == 24932)
- {
- if (triggerAmount == 0)
- return false;
- basepoints0 = triggerAmount * GetMaxHealth() / 100;
- trigger_spell_id = 34299;
- }
- break;
- }
- //=====================================================================
- // Hunter
- // ====================================================================
- // ......
- //=====================================================================
- case SPELLFAMILY_HUNTER:
- break;
- //=====================================================================
- // Paladin
- // ====================================================================
- // Blessed Life trigger = 31934
- // Healing Discount trigger = 18350
- // Illumination (Rank 1-5) trigger = 18350
- // Judgement of Light (Rank 1-5) trigger = 5373
- // Judgement of Wisdom (Rank 1-4) trigger = 1826
- // Lightning Capacitor trigger = 18350
- //=====================================================================
- case SPELLFAMILY_PALADIN:
- {
- /* // Blessed Life
- if (auraSpellInfo->SpellIconID == 2137)
- {
- switch (auraSpellInfo->Id)
- {
- case 31828: // Rank 1
- case 31829: // Rank 2
- case 31830: // Rank 3
+ default:
break;
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u miss posibly Blessed Life", auraSpellInfo->Id);
- return false;
- }
- }*/
- // Healing Discount
- if (auraSpellInfo->Id==37705)
- {
- trigger_spell_id = 37706;
- target = this;
- }
- // Judgement of Light and Judgement of Wisdom
- else if (auraSpellInfo->SpellFamilyFlags & 0x0000000000080000LL)
- {
- switch (auraSpellInfo->Id)
- {
- // Judgement of Light
- case 20185: trigger_spell_id = 20267;break; // Rank 1
- case 20344: trigger_spell_id = 20341;break; // Rank 2
- case 20345: trigger_spell_id = 20342;break; // Rank 3
- case 20346: trigger_spell_id = 20343;break; // Rank 4
- case 27162: trigger_spell_id = 27163;break; // Rank 5
- // Judgement of Wisdom
- case 20186: trigger_spell_id = 20268;break; // Rank 1
- case 20354: trigger_spell_id = 20352;break; // Rank 2
- case 20355: trigger_spell_id = 20353;break; // Rank 3
- case 27164: trigger_spell_id = 27165;break; // Rank 4
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u miss posibly Judgement of Light/Wisdom", auraSpellInfo->Id);
- return false;
- }
- pVictim->CastSpell(pVictim, trigger_spell_id, true, castItem, triggeredByAura);
- return true; // no hidden cooldown
- }
- // Illumination
- else if (auraSpellInfo->SpellIconID==241)
- {
- if(!procSpell)
- return false;
- // procspell is triggered spell but we need mana cost of original casted spell
- uint32 originalSpellId = procSpell->Id;
- // Holy Shock
- if(procSpell->SpellFamilyFlags & 0x00200000)
- {
- 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;
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in HShock",procSpell->Id);
- return false;
- }
- }
- SpellEntry const *originalSpell = sSpellStore.LookupEntry(originalSpellId);
- if(!originalSpell)
- {
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u unknown but selected as original in Illu",originalSpellId);
- return false;
- }
- // percent stored in effect 1 (class scripts) base points
- basepoints0 = originalSpell->manaCost*(auraSpellInfo->EffectBasePoints[1]+1)/100;
- trigger_spell_id = 20272;
- target = this;
- }
- // Lightning Capacitor
- else if (auraSpellInfo->Id==37657)
- {
- if(!pVictim || !pVictim->isAlive())
- return false;
- // stacking
- CastSpell(this, 37658, true, NULL, triggeredByAura);
- // counting
- Aura * dummy = GetDummyAura(37658);
- if (!dummy)
- return false;
- // release at 3 aura in stack (cont contain in basepoint of trigger aura)
- if(dummy->GetStackAmount() <= 2)
- return false;
-
- RemoveAurasDueToSpell(37658);
- trigger_spell_id = 37661;
- target = pVictim;
- }
- break;
- }
- //=====================================================================
- // Shaman
- //====================================================================
- // Lightning Shield trigger = 18350
- // Mana Surge trigger = 18350
- // Nature's Guardian (Rank 1-5) trigger = 18350
- //=====================================================================
- case SPELLFAMILY_SHAMAN:
- {
- //Lightning Shield (overwrite non existing triggered spell call in spell.dbc
- if(auraSpellInfo->SpellFamilyFlags==0x00000400 && auraSpellInfo->SpellVisual==37)
- {
- switch(auraSpellInfo->Id)
- {
- case 324: trigger_spell_id = 26364; break; // Rank 1
- case 325: trigger_spell_id = 26365; break; // Rank 2
- case 905: trigger_spell_id = 26366; break; // Rank 3
- case 945: trigger_spell_id = 26367; break; // Rank 4
- case 8134: trigger_spell_id = 26369; break; // Rank 5
- case 10431: trigger_spell_id = 26370; break; // Rank 6
- case 10432: trigger_spell_id = 26363; break; // Rank 7
- case 25469: trigger_spell_id = 26371; break; // Rank 8
- case 25472: trigger_spell_id = 26372; break; // Rank 9
- default:
- sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in LShield", auraSpellInfo->Id);
- return false;
- }
- }
- // Lightning Shield (The Ten Storms set)
- else if (auraSpellInfo->Id == 23551)
- {
- trigger_spell_id = 23552;
- target = pVictim;
- }
- // Damage from Lightning Shield (The Ten Storms set)
- else if (auraSpellInfo->Id == 23552)
- trigger_spell_id = 27635;
- // Mana Surge (The Earthfury set)
- else if (auraSpellInfo->Id == 23572)
- {
- if(!procSpell)
- return false;
- basepoints0 = procSpell->manaCost * 35 / 100;
- trigger_spell_id = 23571;
- target = this;
- }
- else if (auraSpellInfo->SpellIconID == 2013) //Nature's Guardian
- {
- // Check health condition - should drop to less 30% (damage deal after this!)
- if (!(10*(int32(GetHealth() - damage)) < 3 * GetMaxHealth()))
- return false;
-
- if(pVictim && pVictim->isAlive())
- pVictim->getThreatManager().modifyThreatPercent(this,-10);
-
- basepoints0 = triggerAmount * GetMaxHealth() / 100;
- trigger_spell_id = 31616;
- target = this;
- }
- break;
- }
- // default
- default:
- break;
+ }
}
// All ok. Check current trigger spell
@@ -7695,6 +6828,15 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
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;
+ }
}
// Costum basepoints/target for exist spell
@@ -7724,11 +6866,16 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
// Need add combopoint AFTER finish movie (or they dropped in finish phase)
break;
}
+ // Bloodthirst (($m/100)% of max health)
+ case 23880:
+ {
+ basepoints0 = int32(GetMaxHealth() * triggerAmount / 10000);
+ break;
+ }
// Shamanistic Rage triggered spell
case 30824:
{
basepoints0 = int32(GetTotalAttackPowerValue(BASE_ATTACK) * triggerAmount / 100);
- trigger_spell_id = 30824;
break;
}
// Enlightenment (trigger only from mana cost spells)
@@ -7738,6 +6885,59 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
return false;
break;
}
+ // Brain Freeze
+ case 57761:
+ {
+ if(!procSpell)
+ return false;
+ // For trigger from Blizzard need exist Improved Blizzard
+ if (procSpell->SpellFamilyName==SPELLFAMILY_MAGE && procSpell->SpellFamilyFlags[0] & 0x80)
+ {
+ bool found = false;
+ AuraList const& mOverrideClassScript = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
+ for(AuraList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
+ {
+ int32 script = (*i)->GetModifier()->m_miscvalue;
+ if(script==836 || script==988 || script==989)
+ {
+ found=true;
+ break;
+ }
+ }
+ if(!found)
+ return false;
+ }
+ break;
+ }
+ // Astral Shift
+ case 52179:
+ {
+ if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) || this == pVictim)
+ return false;
+
+ // Need stun, fear or silence mechanic
+ if (!(GetAllSpellMechanicMask(procSpell) & ((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 (!(GetAllSpellMechanicMask(procSpell) & ((1<<MECHANIC_INTERRUPT)|(1<<MECHANIC_SILENCE))))
+ return false;
+ break;
+ }
+ // Lock and Load
+ case 56453:
+ {
+ // Proc only from trap activation (from periodic proc another aura of this spell)
+ if (!(procFlags & PROC_FLAG_ON_TRAP_ACTIVATION) || !roll_chance_i(triggerAmount))
+ return false;
+ break;
+ }
}
if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(trigger_spell_id))
@@ -7764,7 +6964,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
return true;
}
-bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, Aura *triggeredByAura, SpellEntry const *procSpell, uint32 cooldown)
+bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, uint32 damage, Aura *triggeredByAura, SpellEntry const *procSpell, uint32 cooldown)
{
int32 scriptId = triggeredByAura->GetModifier()->m_miscvalue;
@@ -7780,21 +6980,21 @@ bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, Aura *triggeredByAur
{
case 836: // Improved Blizzard (Rank 1)
{
- if (!procSpell || procSpell->SpellVisual!=9487)
+ if (!procSpell || procSpell->SpellVisual[0]!=9487)
return false;
triggered_spell_id = 12484;
break;
}
case 988: // Improved Blizzard (Rank 2)
{
- if (!procSpell || procSpell->SpellVisual!=9487)
+ if (!procSpell || procSpell->SpellVisual[0]!=9487)
return false;
triggered_spell_id = 12485;
break;
}
case 989: // Improved Blizzard (Rank 3)
{
- if (!procSpell || procSpell->SpellVisual!=9487)
+ if (!procSpell || procSpell->SpellVisual[0]!=9487)
return false;
triggered_spell_id = 12486;
break;
@@ -7831,6 +7031,16 @@ bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, Aura *triggeredByAur
case 5497: // Improved Mana Gems (Serpent-Coil Braid)
triggered_spell_id = 37445; // Mana Surge
break;
+ case 8152: // Serendipity
+ {
+ // if heal your target over maximum health
+ if (pVictim->GetHealth() + damage < pVictim->GetMaxHealth())
+ return false;
+ int32 cost = procSpell->manaCost + procSpell->ManaCostPercentage * GetCreateMana() / 100;
+ int32 basepoints0 = cost * triggeredByAura->GetModifier()->m_amount/100;
+ CastCustomSpell(this, 47762, &basepoints0, 0, 0, true, 0, triggeredByAura);
+ return true;
+ }
}
// not processed
@@ -7972,11 +7182,11 @@ bool Unit::IsHostileTo(Unit const* unit) const
return false;
// Sanctuary
- if(pTarget->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_SANCTUARY) && pTester->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_SANCTUARY))
+ if(pTarget->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY) && pTester->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY))
return false;
// PvP FFA state
- if(pTester->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP) && pTarget->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP))
+ if(pTester->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP) && pTarget->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
return true;
//= PvP states
@@ -8081,11 +7291,11 @@ bool Unit::IsFriendlyTo(Unit const* unit) const
return true;
// Sanctuary
- if(pTarget->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_SANCTUARY) && pTester->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_SANCTUARY))
+ if(pTarget->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY) && pTester->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY))
return true;
// PvP FFA state
- if(pTester->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP) && pTarget->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP))
+ if(pTester->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP) && pTarget->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
return false;
//= PvP states
@@ -8214,6 +7424,11 @@ bool Unit::Attack(Unit *victim, bool meleeAttack)
if(meleeAttack)
addUnitState(UNIT_STAT_MELEE_ATTACKING);
+
+ // set position before any AI calls/assistance
+ //if(GetTypeId()==TYPEID_UNIT)
+ // ((Creature*)this)->SetCombatStartPosition(GetPositionX(), GetPositionY(), GetPositionZ());
+
m_attacking = victim;
m_attacking->_addAttacker(this);
@@ -8222,18 +7437,18 @@ bool Unit::Attack(Unit *victim, bool meleeAttack)
if(GetTypeId()==TYPEID_UNIT)
{
+ // should not let player enter combat by right clicking target
+ SetInCombatWith(victim);
+ if(victim->GetTypeId() == TYPEID_PLAYER)
+ victim->SetInCombatWith(this);
+ AddThreat(victim, 0.0f);
+
WorldPacket data(SMSG_AI_REACTION, 12);
data << uint64(GetGUID());
data << uint32(AI_REACTION_AGGRO); // Aggro sound
((WorldObject*)this)->SendMessageToSet(&data, true);
((Creature*)this)->CallAssistance();
-
- // should not let player enter combat by right clicking target
- SetInCombatWith(victim);
- if(victim->GetTypeId() == TYPEID_PLAYER)
- victim->SetInCombatWith(this);
- AddThreat(victim, 0.0f);
}
// delay offhand weapon attack to next attack time
@@ -8343,51 +7558,7 @@ void Unit::RemoveAllAttackers()
void Unit::ModifyAuraState(AuraState flag, bool apply)
{
- if (apply)
- {
- if (!HasFlag(UNIT_FIELD_AURASTATE, 1<<(flag-1)))
- {
- SetFlag(UNIT_FIELD_AURASTATE, 1<<(flag-1));
- if(GetTypeId() == TYPEID_PLAYER)
- {
- const PlayerSpellMap& sp_list = ((Player*)this)->GetSpellMap();
- for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
- {
- if(itr->second->state == PLAYERSPELL_REMOVED) continue;
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first);
- if (!spellInfo || !IsPassiveSpell(itr->first)) continue;
- if (spellInfo->CasterAuraState == flag)
- CastSpell(this, itr->first, true, NULL);
- }
- }
- }
- }
- else
- {
- if (HasFlag(UNIT_FIELD_AURASTATE,1<<(flag-1)))
- {
- RemoveFlag(UNIT_FIELD_AURASTATE, 1<<(flag-1));
- Unit::AuraMap& tAuras = GetAuras();
- for (Unit::AuraMap::iterator itr = tAuras.begin(); itr != tAuras.end();)
- {
- SpellEntry const* spellProto = (*itr).second->GetSpellProto();
- if (spellProto->CasterAuraState == flag)
- {
- // exceptions (applied at state but not removed at state change)
- // Rampage
- if(spellProto->SpellIconID==2006 && spellProto->SpellFamilyName==SPELLFAMILY_WARRIOR && spellProto->SpellFamilyFlags==0x100000)
- {
- ++itr;
- continue;
- }
-
- RemoveAura(itr);
- }
- else
- ++itr;
- }
- }
- }
+ ApplyModFlag(UNIT_FIELD_AURASTATE, 1<<(flag-1), apply);
}
Unit *Unit::GetOwner() const
@@ -8437,6 +7608,7 @@ Unit* Unit::GetCharm() const
sLog.outError("Unit::GetCharm: Charmed creature %u not exist.",GUID_LOPART(charm_guid));
const_cast<Unit*>(this)->SetCharm(0);
+ //const_cast<Unit*>(this)->SetMover(0);
}
return NULL;
@@ -8519,6 +7691,7 @@ void Unit::SendHealSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, bool c
data.append(GetPackGUID());
data << uint32(SpellID);
data << uint32(Damage);
+ data << uint32(0); // over healing?
data << uint8(critical ? 1 : 0);
data << uint8(0); // unused in client?
SendMessageToSet(&data, true);
@@ -8535,76 +7708,29 @@ void Unit::SendEnergizeSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, Po
SendMessageToSet(&data, true);
}
-uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 pdamage, DamageEffectType damagetype)
+uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack)
{
if(!spellProto || !pVictim || damagetype==DIRECT_DAMAGE )
return pdamage;
- //if(spellProto->SchoolMask == SPELL_SCHOOL_MASK_NORMAL)
- // return pdamage;
- //damage = CalcArmorReducedDamage(pVictim, damage);
-
- int32 BonusDamage = 0;
- if( GetTypeId()==TYPEID_UNIT )
- {
- // Pets just add their bonus damage to their spell damage
- // note that their spell damage is just gain of their own auras
- if (((Creature*)this)->isPet())
- {
- BonusDamage = ((Pet*)this)->GetBonusDamage();
- }
- // For totems get damage bonus from owner (statue isn't totem in fact)
- else if (((Creature*)this)->isTotem() && ((Totem*)this)->GetTotemType()!=TOTEM_STATUE)
- {
- if(Unit* owner = GetOwner())
- return owner->SpellDamageBonus(pVictim, spellProto, pdamage, damagetype);
- }
- }
-
- // Damage Done
- uint32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto);
-
- // Taken/Done fixed damage bonus auras
- int32 DoneAdvertisedBenefit = SpellBaseDamageBonus(GetSpellSchoolMask(spellProto))+BonusDamage;
- int32 TakenAdvertisedBenefit = SpellBaseDamageBonusForVictim(GetSpellSchoolMask(spellProto), pVictim);
-
- // Damage over Time spells bonus calculation
- float DotFactor = 1.0f;
- if(damagetype == DOT)
+ // For totems get damage bonus from owner (statue isn't totem in fact)
+ if( GetTypeId()==TYPEID_UNIT && ((Creature*)this)->isTotem() && ((Totem*)this)->GetTotemType()!=TOTEM_STATUE)
{
- int32 DotDuration = GetSpellDuration(spellProto);
- // 200% limit
- if(DotDuration > 0)
- {
- if(DotDuration > 30000) DotDuration = 30000;
- if(!IsChanneledSpell(spellProto)) DotFactor = DotDuration / 15000.0f;
- int x = 0;
- for(int j = 0; j < 3; j++)
- {
- if( spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && (
- spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_DAMAGE ||
- spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH) )
- {
- x = j;
- break;
- }
- }
- int DotTicks = 6;
- if(spellProto->EffectAmplitude[x] != 0)
- DotTicks = DotDuration / spellProto->EffectAmplitude[x];
- if(DotTicks)
- {
- DoneAdvertisedBenefit /= DotTicks;
- TakenAdvertisedBenefit /= DotTicks;
- }
- }
+ if(Unit* owner = GetOwner())
+ return owner->SpellDamageBonus(pVictim, spellProto, pdamage, damagetype);
}
// Taken/Done total percent damage auras
float DoneTotalMod = 1.0f;
float TakenTotalMod = 1.0f;
+ int32 DoneTotal = 0;
+ int32 TakenTotal = 0;
// ..done
+ // Pet damage
+ if( GetTypeId() == TYPEID_UNIT && !((Creature*)this)->isPet() )
+ DoneTotalMod *= ((Creature*)this)->GetSpellDamageMod(((Creature*)this)->GetCreatureInfo()->rank);
+
AuraList const& mModDamagePercentDone = GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
for(AuraList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i)
{
@@ -8614,84 +7740,133 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
(*i)->GetSpellProto()->EquippedItemInventoryTypeMask == 0 )
// 0 == any inventory type (not wand then)
{
- DoneTotalMod *= ((*i)->GetModifierValue() +100.0f)/100.0f;
+ DoneTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
}
}
uint32 creatureTypeMask = pVictim->GetCreatureTypeMask();
+ // Add flat bonus from spell damage versus
+ DoneTotal += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS, creatureTypeMask);
AuraList const& mDamageDoneVersus = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS);
for(AuraList::const_iterator i = mDamageDoneVersus.begin();i != mDamageDoneVersus.end(); ++i)
if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue))
- DoneTotalMod *= ((*i)->GetModifierValue() +100.0f)/100.0f;
-
- // ..taken
- AuraList const& mModDamagePercentTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN);
- for(AuraList::const_iterator i = mModDamagePercentTaken.begin(); i != mModDamagePercentTaken.end(); ++i)
- if( (*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto) )
- TakenTotalMod *= ((*i)->GetModifierValue() +100.0f)/100.0f;
+ DoneTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
- // .. taken pct: scripted (increases damage of * against targets *)
- AuraList const& mOverrideClassScript = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
+ // done scripted mod (take it from owner)
+ Unit *owner = GetOwner();
+ if (!owner) owner = this;
+ AuraList const& mOverrideClassScript= owner->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
for(AuraList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
{
+ if (!(*i)->isAffectedOnSpell(spellProto))
+ continue;
switch((*i)->GetModifier()->m_miscvalue)
{
- //Molten Fury
- case 4920: case 4919:
- if(pVictim->HasAuraState(AURA_STATE_HEALTHLESS_20_PERCENT))
- TakenTotalMod *= (100.0f+(*i)->GetModifier()->m_amount)/100.0f; break;
- }
- }
-
- // .. taken pct: dummy auras
- AuraList const& mDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY);
- for(AuraList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i)
- {
- switch((*i)->GetSpellProto()->SpellIconID)
- {
- //Cheat Death
- case 2109:
- if( ((*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto)) )
- {
- if(pVictim->GetTypeId() != TYPEID_PLAYER)
- continue;
- float mod = -((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_SPELL)*2*4;
- if (mod < (*i)->GetModifier()->m_amount)
- mod = (*i)->GetModifier()->m_amount;
- TakenTotalMod *= (mod+100.0f)/100.0f;
- }
+ case 4920: // Molten Fury
+ case 4919:
+ case 6917: // Death's Embrace
+ case 6926:
+ case 6928:
+ {
+ if(pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT))
+ DoneTotalMod *= (100.0f+(*i)->GetModifier()->m_amount)/100.0f;
break;
- //This is changed in WLK, using aura 255
- //Mangle
- case 2312:
- case 44955:
- for(int j=0;j<3;j++)
- {
- if(GetEffectMechanic(spellProto, j)==MECHANIC_BLEED)
+ }
+ // Soul Siphon
+ case 4992:
+ case 4993:
+ {
+ // effect 1 m_amount
+ int32 maxPercent = (*i)->GetModifier()->m_amount;
+ // effect 0 m_amount
+ int32 stepPercent = CalculateSpellDamage((*i)->GetSpellProto(), 0, (*i)->GetSpellProto()->EffectBasePoints[0], this);
+ // count affliction effects and calc additional damage in percentage
+ int32 modPercent = 0;
+ AuraMap const& victimAuras = pVictim->GetAuras();
+ for (AuraMap::const_iterator itr = victimAuras.begin(); itr != victimAuras.end(); ++itr)
+ {
+ SpellEntry const* m_spell = itr->second->GetSpellProto();
+ if (m_spell->SpellFamilyName != SPELLFAMILY_WARLOCK || !(m_spell->SpellFamilyFlags[1] & 0x0004071B || m_spell->SpellFamilyFlags[0] & 0x8044C402))
+ continue;
+ modPercent += stepPercent * itr->second->GetStackAmount();
+ if (modPercent >= maxPercent)
{
- TakenTotalMod *= (100.0f+(*i)->GetModifier()->m_amount)/100.0f;
+ modPercent = maxPercent;
break;
}
}
+ DoneTotalMod *= (modPercent+100.0f)/100.0f;
break;
+ }
+ case 6916: // Death's Embrace
+ case 6925:
+ case 6927:
+ if (HasAuraState(AURA_STATE_HEALTHLESS_20_PERCENT))
+ DoneTotalMod *= (100.0f+(*i)->GetModifier()->m_amount)/100.0f;
+ break;
+ case 5481: // Starfire Bonus
+ {
+ if (pVictim->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DRUID, 0x200002))
+ DoneTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
+ break;
+ }
+ case 4418: // Increased Shock Damage
+ case 4554: // Increased Lightning Damage
+ case 4555: // Improved Moonfire
+ case 5142: // Increased Lightning Damage
+ case 5147: // Improved Consecration / Libram of Resurgence
+ case 5148: // Idol of the Shooting Star
+ case 6008: // Increased Lightning Damage / Totem of Hex
+ {
+ DoneTotal+=(*i)->GetModifier()->m_amount;
+ break;
+ }
+ // Tundra Stalker
+ // Merciless Combat
+ case 7277:
+ {
+ // Merciless Combat
+ if ((*i)->GetSpellProto()->SpellIconID == 2656)
+ {
+ if(pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT))
+ DoneTotalMod *= (100.0f+(*i)->GetModifier()->m_amount)/100.0f;
+ }
+ else // Tundra Stalker
+ {
+ if (pVictim->GetAura(SPELL_AURA_DUMMY, SPELLFAMILY_DEATHKNIGHT,0, 0x04000000,0))
+ DoneTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
+ break;
+ }
+ break;
+ }
+ case 7293: // Rage of Rivendare
+ {
+ if (pVictim->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DEATHKNIGHT, 0,0x02000000,0))
+ DoneTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
+ break;
+ }
+ // Twisted Faith
+ case 7377:
+ {
+ if (pVictim->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, 0x8000, 0,0, GetGUID()))
+ DoneTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
+ break;
+ }
+ // Marked for Death
+ case 7598:
+ case 7599:
+ case 7600:
+ case 7601:
+ case 7602:
+ {
+ if (pVictim->GetAura(SPELL_AURA_MOD_STALKED, SPELLFAMILY_HUNTER, 0x400))
+ DoneTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
+ break;
+ }
}
}
- // Distribute Damage over multiple effects, reduce by AoE
- CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime );
-
- // 50% for damage and healing spells for leech spells from damage bonus and 0% from healing
- for(int j = 0; j < 3; ++j)
- {
- if( spellProto->Effect[j] == SPELL_EFFECT_HEALTH_LEECH ||
- spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH )
- {
- CastingTime /= 2;
- break;
- }
- }
-
- switch(spellProto->SpellFamilyName)
+ /*switch(spellProto->SpellFamilyName)
{
case SPELLFAMILY_GENERIC:
// Siphon Essence - 0%
@@ -8705,7 +7880,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
CastingTime = 0;
}
// Darkmoon Card: Vengeance - 0.1%
- else if (spellProto->SpellVisual == 9850 && spellProto->SpellIconID == 2230)
+ else if (spellProto->SpellVisual[0] == 9850 && spellProto->SpellIconID == 2230)
{
CastingTime = 3.5;
}
@@ -8808,21 +7983,10 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
DotFactor = 0.95f;
CastingTime = 3500;
}
- // Seal of Righteousness - 10.2%/9.8% ( based on weapon type ) of Holy Damage, multiplied by weapon speed
- else if((spellProto->SpellFamilyFlags & 0x8000000LL) && spellProto->SpellIconID == 25)
+ // Judgement of Righteousness - 32%
+ else if (spellProto->SpellFamilyFlags & 0x0000000000000400LL)
{
- Item *item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
- float wspeed = GetAttackTime(BASE_ATTACK)/1000.0f;
-
- if( item && item->GetProto()->InventoryType == INVTYPE_2HWEAPON)
- CastingTime = uint32(wspeed*3500*0.102f);
- else
- CastingTime = uint32(wspeed*3500*0.098f);
- }
- // Judgement of Righteousness - 73%
- else if ((spellProto->SpellFamilyFlags & 1024) && spellProto->SpellIconID == 25)
- {
- CastingTime = 2555;
+ CastingTime = 1120;
}
// Seal of Vengeance - 17% per Fully Stacked Tick - 5 Applications
else if ((spellProto->SpellFamilyFlags & 0x80000000000LL) && spellProto->SpellIconID == 2292)
@@ -8840,11 +8004,6 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
{
CastingTime = 0;
}
- // Seal of Righteousness trigger - already computed for parent spell
- else if ( spellProto->SpellFamilyName==SPELLFAMILY_PALADIN && spellProto->SpellIconID==25 && spellProto->AttributesEx4 & 0x00800000LL )
- {
- return pdamage;
- }
break;
case SPELLFAMILY_SHAMAN:
// totem attack
@@ -8898,58 +8057,148 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
{
CastingTime = 500;
}
- break;
- case SPELLFAMILY_DRUID:
- // Hurricane triggered spell
- if((spellProto->SpellFamilyFlags & 0x400000LL) && spellProto->SpellIconID == 220)
- {
- CastingTime = 500;
- }
- break;
- case SPELLFAMILY_WARRIOR:
- case SPELLFAMILY_HUNTER:
- case SPELLFAMILY_ROGUE:
- CastingTime = 0;
- break;
- default:
- break;
- }
+ break;*/
- float LvlPenalty = CalculateLevelPenalty(spellProto);
+ // Custom scripted damage
+ // Ice Lance
+ if (spellProto->SpellFamilyName == SPELLFAMILY_MAGE && spellProto->SpellIconID == 186)
+ {
+ if (pVictim->isFrozen())
+ DoneTotalMod *= 3.0f;
+ }
- // Spellmod SpellDamage
- //float SpellModSpellDamage = 100.0f;
- float CoefficientPtc = DotFactor * 100.0f;
- if(spellProto->SchoolMask != SPELL_SCHOOL_MASK_NORMAL)
- CoefficientPtc *= ((float)CastingTime/3500.0f);
+ // ..taken
+ AuraList const& mModDamagePercentTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN);
+ for(AuraList::const_iterator i = mModDamagePercentTaken.begin(); i != mModDamagePercentTaken.end(); ++i)
+ if( (*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto) )
+ TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
- if(Player* modOwner = GetSpellModOwner())
- //modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_SPELL_BONUS_DAMAGE,SpellModSpellDamage);
- modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_SPELL_BONUS_DAMAGE,CoefficientPtc);
+ // .. taken pct: dummy auras
+ if (pVictim->GetTypeId() == TYPEID_PLAYER)
+ {
+ //Cheat Death
+ if (Aura *dummy = pVictim->GetDummyAura(45182))
+ {
+ float mod = -((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_SPELL)*2*4;
+ if (mod < dummy->GetModifier()->m_amount)
+ mod = dummy->GetModifier()->m_amount;
+ TakenTotalMod *= (mod+100.0f)/100.0f;
+ }
+ }
- //SpellModSpellDamage /= 100.0f;
- CoefficientPtc /= 100.0f;
+ // From caster spells
+ AuraList const& mOwnerTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER);
+ for(AuraList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i)
+ if( (*i)->GetCasterGUID() == GetGUID() && (*i)->isAffectedOnSpell(spellProto))
+ TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
- //float DoneActualBenefit = DoneAdvertisedBenefit * (CastingTime / 3500.0f) * DotFactor * SpellModSpellDamage * LvlPenalty;
+ // Mod damage from spell mechanic
+ uint32 mechanicMask = GetAllSpellMechanicMask(spellProto);
+ if (mechanicMask)
+ {
+ AuraList const& mDamageDoneMechanic = pVictim->GetAurasByType(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT);
+ for(AuraList::const_iterator i = mDamageDoneMechanic.begin();i != mDamageDoneMechanic.end(); ++i)
+ if(mechanicMask & uint32(1<<((*i)->GetModifier()->m_miscvalue)))
+ TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
+ }
- float DoneActualBenefit = DoneAdvertisedBenefit * CoefficientPtc * LvlPenalty;
- float TakenActualBenefit = TakenAdvertisedBenefit * DotFactor * LvlPenalty;
- if(spellProto->SpellFamilyName && spellProto->SchoolMask != SPELL_SCHOOL_MASK_NORMAL)
- TakenActualBenefit *= ((float)CastingTime / 3500.0f);
+ // Taken/Done fixed damage bonus auras
+ int32 DoneAdvertisedBenefit = SpellBaseDamageBonus(GetSpellSchoolMask(spellProto));
+ int32 TakenAdvertisedBenefit = SpellBaseDamageBonusForVictim(GetSpellSchoolMask(spellProto), pVictim);
+ // Pets just add their bonus damage to their spell damage
+ // note that their spell damage is just gain of their own auras
+ if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isPet())
+ DoneAdvertisedBenefit += ((Pet*)this)->GetBonusDamage();
+
+ // Check for table values
+ float coeff;
+ SpellBonusEntry const* bonus = spellmgr.GetSpellBonusData(spellProto->Id);
+ if (bonus)
+ {
+ if (damagetype == DOT)
+ coeff = bonus->dot_damage;
+ else
+ coeff = bonus->direct_damage;
+ if (bonus->ap_bonus)
+ DoneTotal+=bonus->ap_bonus * GetTotalAttackPowerValue(BASE_ATTACK) * stack;
+ }
+ // Default calculation
+ else if (DoneAdvertisedBenefit || TakenAdvertisedBenefit)
+ {
+ // Damage Done from spell damage bonus
+ int32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto);
+ if (IsChanneledSpell(spellProto))
+ ModSpellCastTime(spellProto, CastingTime);
+ // Damage over Time spells bonus calculation
+ float DotFactor = 1.0f;
+ if(damagetype == DOT)
+ {
+ int32 DotDuration = GetSpellDuration(spellProto);
+ //apply casting time mods for channeled spells
+ if (IsChanneledSpell(spellProto))
+ ModSpellCastTime(spellProto, DotDuration);
+ // 200% limit
+ if(DotDuration > 0)
+ {
+ if(DotDuration > 30000) DotDuration = 30000;
+ if(!IsChanneledSpell(spellProto)) DotFactor = DotDuration / 15000.0f;
+ int x = 0;
+ for(int j = 0; j < 3; j++)
+ {
+ if( spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && (
+ spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_DAMAGE ||
+ spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH) )
+ {
+ x = j;
+ break;
+ }
+ }
+ int32 DotTicks = 6;
+ if(spellProto->EffectAmplitude[x] != 0)
+ DotTicks = DotDuration / spellProto->EffectAmplitude[x];
+ if(DotTicks)
+ {
+ DoneAdvertisedBenefit /= DotTicks;
+ TakenAdvertisedBenefit /= DotTicks;
+ }
+ }
+ }
+ // Distribute Damage over multiple effects, reduce by AoE
+ CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime );
- float tmpDamage = (float(pdamage)+DoneActualBenefit)*DoneTotalMod;
+ // 50% for damage and healing spells for leech spells from damage bonus and 0% from healing
+ for(int j = 0; j < 3; ++j)
+ {
+ if( spellProto->Effect[j] == SPELL_EFFECT_HEALTH_LEECH ||
+ spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH )
+ {
+ CastingTime /= 2;
+ break;
+ }
+ }
+ if(spellProto->SchoolMask != SPELL_SCHOOL_MASK_NORMAL)
+ coeff = (CastingTime / 3500.0f) * DotFactor;
+ else
+ coeff = DotFactor;
+ }
- // Add flat bonus from spell damage versus
- tmpDamage += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS, creatureTypeMask);
+ float coeff2 = CalculateLevelPenalty(spellProto) * stack;
+ if(spellProto->SpellFamilyName) //TODO: fix this
+ TakenTotal+= TakenAdvertisedBenefit * coeff * coeff2;
+ if(Player* modOwner = GetSpellModOwner())
+ {
+ coeff *= 100.0f;
+ modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_SPELL_BONUS_DAMAGE, coeff);
+ coeff /= 100.0f;
+ }
+ DoneTotal += DoneAdvertisedBenefit * coeff * coeff2;
- // apply spellmod to Done damage
+ float tmpDamage = (pdamage + DoneTotal) * DoneTotalMod;
+ // apply spellmod to Done damage (flat and pct)
if(Player* modOwner = GetSpellModOwner())
modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, tmpDamage);
- tmpDamage = (tmpDamage+TakenActualBenefit)*TakenTotalMod;
-
- if( GetTypeId() == TYPEID_UNIT && !((Creature*)this)->isPet() )
- tmpDamage *= ((Creature*)this)->GetSpellDamageMod(((Creature*)this)->GetCreatureInfo()->rank);
+ tmpDamage = (tmpDamage + TakenTotal) * TakenTotalMod;
return tmpDamage > 0 ? uint32(tmpDamage) : 0;
}
@@ -8966,32 +8215,29 @@ int32 Unit::SpellBaseDamageBonus(SpellSchoolMask schoolMask)
// -1 == any item class (not wand then)
(*i)->GetSpellProto()->EquippedItemInventoryTypeMask == 0 )
// 0 == any inventory type (not wand then)
- DoneAdvertisedBenefit += (*i)->GetModifierValue();
+ DoneAdvertisedBenefit += (*i)->GetModifier()->m_amount;
if (GetTypeId() == TYPEID_PLAYER)
{
+ // Base value
+ DoneAdvertisedBenefit +=((Player*)this)->GetBaseSpellDamageBonus();
+
// Damage bonus from stats
AuraList const& mDamageDoneOfStatPercent = GetAurasByType(SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT);
for(AuraList::const_iterator i = mDamageDoneOfStatPercent.begin();i != mDamageDoneOfStatPercent.end(); ++i)
{
if((*i)->GetModifier()->m_miscvalue & schoolMask)
{
- SpellEntry const* iSpellProto = (*i)->GetSpellProto();
- uint8 eff = (*i)->GetEffIndex();
-
- // stat used dependent from next effect aura SPELL_AURA_MOD_SPELL_HEALING presence and misc value (stat index)
- Stats usedStat = STAT_INTELLECT;
- if(eff < 2 && iSpellProto->EffectApplyAuraName[eff+1]==SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT)
- usedStat = Stats(iSpellProto->EffectMiscValue[eff+1]);
-
- DoneAdvertisedBenefit += int32(GetStat(usedStat) * (*i)->GetModifierValue() / 100.0f);
+ // stat used stored in miscValueB for this aura
+ Stats usedStat = Stats((*i)->GetMiscBValue());
+ DoneAdvertisedBenefit += int32(GetStat(usedStat) * (*i)->GetModifier()->m_amount / 100.0f);
}
}
// ... and attack power
AuraList const& mDamageDonebyAP = GetAurasByType(SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER);
for(AuraList::const_iterator i =mDamageDonebyAP.begin();i != mDamageDonebyAP.end(); ++i)
if ((*i)->GetModifier()->m_miscvalue & schoolMask)
- DoneAdvertisedBenefit += int32(GetTotalAttackPowerValue(BASE_ATTACK) * (*i)->GetModifierValue() / 100.0f);
+ DoneAdvertisedBenefit += int32(GetTotalAttackPowerValue(BASE_ATTACK) * (*i)->GetModifier()->m_amount / 100.0f);
}
return DoneAdvertisedBenefit;
@@ -9006,13 +8252,13 @@ int32 Unit::SpellBaseDamageBonusForVictim(SpellSchoolMask schoolMask, Unit *pVic
AuraList const& mDamageDoneCreature = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE);
for(AuraList::const_iterator i = mDamageDoneCreature.begin();i != mDamageDoneCreature.end(); ++i)
if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue))
- TakenAdvertisedBenefit += (*i)->GetModifierValue();
+ TakenAdvertisedBenefit += (*i)->GetModifier()->m_amount;
// ..taken
AuraList const& mDamageTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_TAKEN);
for(AuraList::const_iterator i = mDamageTaken.begin();i != mDamageTaken.end(); ++i)
if(((*i)->GetModifier()->m_miscvalue & schoolMask) != 0)
- TakenAdvertisedBenefit += (*i)->GetModifierValue();
+ TakenAdvertisedBenefit += (*i)->GetModifier()->m_amount;
return TakenAdvertisedBenefit;
}
@@ -9041,30 +8287,77 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM
crit_chance += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL, schoolMask);
}
// taken
- if (pVictim && !IsPositiveSpell(spellProto->Id))
- {
- // Modify critical chance by victim SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE
- crit_chance += pVictim->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 += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE);
- // Modify by player victim resilience
- if (pVictim->GetTypeId() == TYPEID_PLAYER)
- crit_chance -= ((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_SPELL);
+ if (pVictim)
+ {
+ if (!IsPositiveSpell(spellProto->Id))
+ {
+ // Modify critical chance by victim SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE
+ crit_chance += pVictim->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 += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE);
+ // Modify by player victim resilience
+ if (pVictim->GetTypeId() == TYPEID_PLAYER)
+ crit_chance -= ((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_SPELL);
+ }
+
// scripted (increase crit chance ... against ... target by x%
- if(pVictim->isFrozen()) // Shatter
+ AuraList const& mOverrideClassScript = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
+ for(AuraList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
{
- AuraList const& mOverrideClassScript = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
- for(AuraList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
+ if (!((*i)->isAffectedOnSpell(spellProto)))
+ continue;
+ switch((*i)->GetModifier()->m_miscvalue)
{
- switch((*i)->GetModifier()->m_miscvalue)
+ case 849: if (pVictim->isFrozen()) crit_chance+= 17.0f; break; //Shatter Rank 1
+ case 910: if (pVictim->isFrozen()) crit_chance+= 34.0f; break; //Shatter Rank 2
+ case 911: if (pVictim->isFrozen()) crit_chance+= 50.0f; break; //Shatter Rank 3
+ case 7917: // Glyph of Shadowburn
+ if (pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT))
+ crit_chance+=(*i)->GetModifier()->m_amount;
+ break;
+ case 7997: // Renewed Hope
+ case 7998:
+ if (pVictim->HasAura(6788))
+ crit_chance+=(*i)->GetModifier()->m_amount;
+ break;
+ case 21: // Test of Faith
+ case 6935:
+ case 6918:
+ if (pVictim->GetHealth() < pVictim->GetMaxHealth()/2)
+ crit_chance+=(*i)->GetModifier()->m_amount;
+ break;
+ default:
+ break;
+ }
+ }
+ // Custom crit by class
+ switch(spellProto->SpellFamilyName)
+ {
+ case SPELLFAMILY_PALADIN:
+ // Sacred Shield
+ if (spellProto->SpellFamilyFlags[0] & 0x40000000)
{
- case 849: crit_chance+= 10.0f; break; //Shatter Rank 1
- case 910: crit_chance+= 20.0f; break; //Shatter Rank 2
- case 911: crit_chance+= 30.0f; break; //Shatter Rank 3
- case 912: crit_chance+= 40.0f; break; //Shatter Rank 4
- case 913: crit_chance+= 50.0f; break; //Shatter Rank 5
+ Aura *aura = pVictim->GetDummyAura(58597);
+ if (aura && aura->GetCasterGUID() == GetGUID())
+ crit_chance+=aura->GetModifier()->m_amount;
+ break;
}
- }
+ break;
+ case SPELLFAMILY_SHAMAN:
+ // Lava Burst
+ if (spellProto->SpellFamilyFlags[1] & 0x00001000)
+ {
+ if (Aura *flameShock = pVictim->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_SHAMAN, 10000000, 0,0, GetGUID()))
+ {
+ // Consume shock aura if not have Glyph of Flame Shock
+ if (!GetAura(55447, 0))
+ pVictim->RemoveAurasByCasterSpell(flameShock->GetId(), GetGUID());
+ return true;
+ }
+ break;
+ }
+ break;
+
}
}
break;
@@ -9075,7 +8368,6 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM
if (pVictim)
{
crit_chance = GetUnitCriticalChance(attackType, pVictim);
- crit_chance+= (int32(GetMaxSkillValueForLevel(pVictim)) - int32(pVictim->GetDefenseSkillValue(this))) * 0.04f;
crit_chance+= GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL, schoolMask);
}
break;
@@ -9094,7 +8386,7 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM
return false;
}
-uint32 Unit::SpellCriticalBonus(SpellEntry const *spellProto, uint32 damage, Unit *pVictim)
+uint32 Unit::SpellCriticalDamageBonus(SpellEntry const *spellProto, uint32 damage, Unit *pVictim)
{
// Calculate critical bonus
int32 crit_bonus;
@@ -9126,15 +8418,49 @@ uint32 Unit::SpellCriticalBonus(SpellEntry const *spellProto, uint32 damage, Uni
return damage;
}
-uint32 Unit::SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount, DamageEffectType damagetype, Unit *pVictim)
+uint32 Unit::SpellCriticalHealingBonus(SpellEntry const *spellProto, uint32 damage, Unit *pVictim)
+{
+ // 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(pVictim)
+ {
+ uint32 creatureTypeMask = pVictim->GetCreatureTypeMask();
+ crit_bonus = int32(crit_bonus * GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CRIT_PERCENT_VERSUS, creatureTypeMask));
+ }
+
+ if(crit_bonus > 0)
+ damage += crit_bonus;
+
+ damage = int32(float(damage) * GetTotalAuraMultiplier(SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT));
+
+ return damage;
+}
+
+uint32 Unit::SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack)
{
+ // No heal amount for this class spells
+ if (spellProto->DmgClass == SPELL_DAMAGE_CLASS_NONE)
+ return healamount;
+
// For totems get healing bonus from owner (statue isn't totem in fact)
if( GetTypeId()==TYPEID_UNIT && ((Creature*)this)->isTotem() && ((Totem*)this)->GetTotemType()!=TOTEM_STATUE)
if(Unit* owner = GetOwner())
- return owner->SpellHealingBonus(spellProto, healamount, damagetype, pVictim);
-
- // Healing Done
+ return owner->SpellHealingBonus(pVictim, spellProto, healamount, damagetype, stack);
+ // TODO: to be deleted
// These Spells are doing fixed amount of healing (TODO found less hack-like check)
if (spellProto->Id == 15290 || spellProto->Id == 39373 ||
spellProto->Id == 33778 || spellProto->Id == 379 ||
@@ -9143,86 +8469,91 @@ uint32 Unit::SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount,
spellProto->Id == 34299)
return healamount;
- int32 AdvertisedBenefit = SpellBaseHealingBonus(GetSpellSchoolMask(spellProto));
- uint32 CastingTime = GetSpellCastTime(spellProto);
+ // Healing Done
+ // Taken/Done total percent damage auras
+ float DoneTotalMod = 1.0f;
+ float TakenTotalMod = 1.0f;
+ int32 DoneTotal = 0;
+ int32 TakenTotal = 0;
- // Healing Taken
- AdvertisedBenefit += SpellBaseHealingBonusForVictim(GetSpellSchoolMask(spellProto), pVictim);
+ // Healing done percent
+ AuraList const& mHealingDonePct = GetAurasByType(SPELL_AURA_MOD_HEALING_DONE_PERCENT);
+ for(AuraList::const_iterator i = mHealingDonePct.begin();i != mHealingDonePct.end(); ++i)
+ DoneTotalMod *= (100.0f + (*i)->GetModifier()->m_amount) / 100.0f;
- // Blessing of Light dummy effects healing taken from Holy Light and Flash of Light
- if (spellProto->SpellFamilyName == SPELLFAMILY_PALADIN && (spellProto->SpellFamilyFlags & 0x00000000C0000000LL))
+ // done scripted mod (take it from owner)
+ Unit *owner = GetOwner();
+ if (!owner) owner = this;
+ AuraList const& mOverrideClassScript= owner->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
+ for(AuraList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
{
- AuraList const& mDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY);
- for(AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i)
+ if (!(*i)->isAffectedOnSpell(spellProto))
+ continue;
+ switch((*i)->GetModifier()->m_miscvalue)
{
- if((*i)->GetSpellProto()->SpellVisual == 9180)
+ case 4415: // Increased Rejuvenation Healing
+ case 4953:
+ case 3736: // Hateful Totem of the Third Wind / Increased Lesser Healing Wave / LK Arena (4/5/6) Totem of the Third Wind / Savage Totem of the Third Wind
+ DoneTotal+=(*i)->GetModifier()->m_amount;
+ break;
+ case 7997: // Renewed Hope
+ case 7998:
+ if (pVictim->HasAura(6788))
+ DoneTotalMod *=((*i)->GetModifier()->m_amount + 100.0f)/100.0f;
+ break;
+ case 21: // Test of Faith
+ case 6935:
+ case 6918:
+ if (pVictim->GetHealth() < pVictim->GetMaxHealth()/2)
+ DoneTotalMod *=((*i)->GetModifier()->m_amount + 100.0f)/100.0f;
+ break;
+ case 7798: // Glyph of Regrowth
{
- // Flash of Light
- if ((spellProto->SpellFamilyFlags & 0x0000000040000000LL) && (*i)->GetEffIndex() == 1)
- AdvertisedBenefit += (*i)->GetModifier()->m_amount;
- // Holy Light
- else if ((spellProto->SpellFamilyFlags & 0x0000000080000000LL) && (*i)->GetEffIndex() == 0)
- AdvertisedBenefit += (*i)->GetModifier()->m_amount;
+ if (pVictim->GetAura(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_DRUID, 0x40))
+ DoneTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
+ break;
}
- }
- }
-
- float ActualBenefit = 0.0f;
-
- if (AdvertisedBenefit != 0)
- {
- // Healing over Time spells
- float DotFactor = 1.0f;
- if(damagetype == DOT)
- {
- int32 DotDuration = GetSpellDuration(spellProto);
- if(DotDuration > 0)
+ case 8477: // Nourish Heal Boost
{
- // 200% limit
- if(DotDuration > 30000) DotDuration = 30000;
- if(!IsChanneledSpell(spellProto)) DotFactor = DotDuration / 15000.0f;
- int x = 0;
- for(int j = 0; j < 3; j++)
+ int32 stepPercent = (*i)->GetModifier()->m_amount;
+ int32 modPercent = 0;
+ AuraMap const& victimAuras = pVictim->GetAuras();
+ for (AuraMap::const_iterator itr = victimAuras.begin(); itr != victimAuras.end(); ++itr)
{
- if( spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && (
- spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_HEAL ||
- spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH) )
- {
- x = j;
- break;
- }
+ if (itr->second->GetCasterGUID()!=GetGUID())
+ continue;
+ SpellEntry const* m_spell = itr->second->GetSpellProto();
+ if ( m_spell->SpellFamilyName != SPELLFAMILY_DRUID ||
+ !(m_spell->SpellFamilyFlags[1] & 0x00000010 || m_spell->SpellFamilyFlags[0] & 0x50))
+ continue;
+ modPercent += stepPercent * itr->second->GetStackAmount();
}
- int DotTicks = 6;
- if(spellProto->EffectAmplitude[x] != 0)
- DotTicks = DotDuration / spellProto->EffectAmplitude[x];
- if(DotTicks)
- AdvertisedBenefit /= DotTicks;
+ DoneTotalMod *= (modPercent+100.0f)/100.0f;
+ break;
}
- }
-
- // distribute healing to all effects, reduce AoE damage
- CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime );
-
- // 0% bonus for damage and healing spells for leech spells from healing bonus
- for(int j = 0; j < 3; ++j)
- {
- if( spellProto->Effect[j] == SPELL_EFFECT_HEALTH_LEECH ||
- spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH )
+ case 7871: // Glyph of Lesser Healing Wave
{
- CastingTime = 0;
+ if (pVictim->GetAura(SPELL_AURA_DUMMY, SPELLFAMILY_SHAMAN, 0 , 0x00000400, 0, GetGUID()))
+ DoneTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
break;
}
+ default:
+ break;
}
+ }
- // Exception
+ /*// Exception
switch (spellProto->SpellFamilyName)
{
- case SPELLFAMILY_SHAMAN:
+ case SPELLFAMILY_GENERIC:
// Healing stream from totem (add 6% per tick from hill bonus owner)
- if (spellProto->SpellFamilyFlags & 0x000000002000LL)
+ // Possibly need do it on apply dummy aura
+ if (spellProto->Id == 52042)
CastingTime = 210;
+ break;
+ case SPELLFAMILY_SHAMAN:
// Earth Shield 30% per charge
- else if (spellProto->SpellFamilyFlags & 0x40000000000LL)
+ if (spellProto->SpellFamilyFlags & 0x40000000000LL)
CastingTime = 1050;
break;
case SPELLFAMILY_DRUID:
@@ -9266,64 +8597,136 @@ uint32 Unit::SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount,
case SPELLFAMILY_HUNTER:
CastingTime = 0;
break;
- }
-
- float LvlPenalty = CalculateLevelPenalty(spellProto);
-
- // Spellmod SpellDamage
- //float SpellModSpellDamage = 100.0f;
- float CoefficientPtc = ((float)CastingTime/3500.0f)*DotFactor*100.0f;
+ }*/
- if(Player* modOwner = GetSpellModOwner())
- //modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_SPELL_BONUS_DAMAGE,SpellModSpellDamage);
- modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_SPELL_BONUS_DAMAGE,CoefficientPtc);
+ // Taken/Done fixed damage bonus auras
+ int32 DoneAdvertisedBenefit = SpellBaseHealingBonus(GetSpellSchoolMask(spellProto));
+ int32 TakenAdvertisedBenefit = SpellBaseHealingBonusForVictim(GetSpellSchoolMask(spellProto), pVictim);
- //SpellModSpellDamage /= 100.0f;
- CoefficientPtc /= 100.0f;
+ // Check for table values
+ SpellBonusEntry const* bonus = spellmgr.GetSpellBonusData(spellProto->Id);
+ float coeff;
+ if (bonus)
+ {
+ if (damagetype == DOT)
+ coeff = bonus->dot_damage;
+ else
+ coeff = bonus->direct_damage;
+ if (bonus->ap_bonus)
+ DoneTotal+=bonus->ap_bonus * GetTotalAttackPowerValue(BASE_ATTACK) * stack;
+ }
+ // Default calculation
+ else if (DoneAdvertisedBenefit || TakenAdvertisedBenefit)
+ {
+ // Damage Done from spell damage bonus
+ int32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto);
+ if (IsChanneledSpell(spellProto))
+ ModSpellCastTime(spellProto, CastingTime);
+ // Damage over Time spells bonus calculation
+ float DotFactor = 1.0f;
+ if(damagetype == DOT)
+ {
+ int32 DotDuration = GetSpellDuration(spellProto);
+ //apply casting time mods for channeled spells
+ if (IsChanneledSpell(spellProto))
+ ModSpellCastTime(spellProto, DotDuration);
+ // 200% limit
+ if(DotDuration > 0)
+ {
+ if(DotDuration > 30000) DotDuration = 30000;
+ if(!IsChanneledSpell(spellProto)) DotFactor = DotDuration / 15000.0f;
+ int x = 0;
+ for(int j = 0; j < 3; j++)
+ {
+ if( spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && (
+ spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_DAMAGE ||
+ spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH) )
+ {
+ x = j;
+ break;
+ }
+ }
+ int32 DotTicks = 6;
+ if(spellProto->EffectAmplitude[x] != 0)
+ DotTicks = DotDuration / spellProto->EffectAmplitude[x];
+ if(DotTicks)
+ {
+ DoneAdvertisedBenefit /= DotTicks*int32(stack);
+ TakenAdvertisedBenefit /= DotTicks*int32(stack);
+ }
+ }
+ }
+ // Distribute Damage over multiple effects, reduce by AoE
+ CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime );
+ // 50% for damage and healing spells for leech spells from damage bonus and 0% from healing
+ for(int j = 0; j < 3; ++j)
+ {
+ if( spellProto->Effect[j] == SPELL_EFFECT_HEALTH_LEECH ||
+ spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH )
+ {
+ CastingTime /= 2;
+ break;
+ }
+ }
+ coeff = (CastingTime / 3500.0f) * DotFactor;
+ }
- //ActualBenefit = (float)AdvertisedBenefit * ((float)CastingTime / 3500.0f) * DotFactor * SpellModSpellDamage * LvlPenalty;
- ActualBenefit = (float)AdvertisedBenefit * CoefficientPtc * LvlPenalty;
+ float coeff2 = CalculateLevelPenalty(spellProto) * 1.88f * stack;
+ TakenTotal+= TakenAdvertisedBenefit * coeff * coeff2;
+ if(Player* modOwner = GetSpellModOwner())
+ {
+ coeff *= 100.0f;
+ modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_SPELL_BONUS_DAMAGE, coeff);
+ coeff /= 100.0f;
}
+ DoneTotal += DoneAdvertisedBenefit * coeff * coeff2;
// use float as more appropriate for negative values and percent applying
- float heal = healamount + ActualBenefit;
-
- // TODO: check for ALL/SPELLS type
- // Healing done percent
- AuraList const& mHealingDonePct = GetAurasByType(SPELL_AURA_MOD_HEALING_DONE_PERCENT);
- for(AuraList::const_iterator i = mHealingDonePct.begin();i != mHealingDonePct.end(); ++i)
- heal *= (100.0f + (*i)->GetModifierValue()) / 100.0f;
-
+ float heal = (healamount + DoneTotal)*DoneTotalMod;
// apply spellmod to Done amount
if(Player* modOwner = GetSpellModOwner())
modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, heal);
+ // Taken mods
// Healing Wave cast
- if (spellProto->SpellFamilyName == SPELLFAMILY_SHAMAN && spellProto->SpellFamilyFlags & 0x0000000000000040LL)
+ if (spellProto->SpellFamilyName == SPELLFAMILY_SHAMAN && spellProto->SpellFamilyFlags[0] & 0x40)
{
- // Search for Healing Way on Victim (stack up to 3 time)
- int32 pctMod = 0;
+ // Search for Healing Way on Victim
Unit::AuraList const& auraDummy = pVictim->GetAurasByType(SPELL_AURA_DUMMY);
for(Unit::AuraList::const_iterator itr = auraDummy.begin(); itr!=auraDummy.end(); ++itr)
if((*itr)->GetId() == 29203)
- pctMod += (*itr)->GetModifier()->m_amount;
- // Apply bonus
- if (pctMod)
- heal = heal * (100 + pctMod) / 100;
+ TakenTotalMod *= ((*itr)->GetModifier()->m_amount+100.0f) / 100.0f;
}
// Healing taken percent
float minval = pVictim->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HEALING_PCT);
if(minval)
- heal *= (100.0f + minval) / 100.0f;
+ TakenTotalMod *= (100.0f + minval) / 100.0f;
float maxval = pVictim->GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HEALING_PCT);
if(maxval)
- heal *= (100.0f + maxval) / 100.0f;
+ TakenTotalMod *= (100.0f + maxval) / 100.0f;
+
+ if(damagetype==DOT)
+ {
+ // Healing over time taken percent
+ float minval_hot = GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HOT_PCT);
+ if(minval_hot)
+ TakenTotalMod *= (100.0f + minval_hot) / 100.0f;
+
+ float maxval_hot = GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HOT_PCT);
+ if(maxval_hot)
+ TakenTotalMod *= (100.0f + maxval_hot) / 100.0f;
+ }
+
+ AuraList const& mHealingGet= pVictim->GetAurasByType(SPELL_AURA_MOD_HEALING_RECEIVED);
+ for(AuraList::const_iterator i = mHealingGet.begin(); i != mHealingGet.end(); ++i)
+ if (GetGUID()==(*i)->GetCasterGUID() && (*i)->isAffectedOnSpell(spellProto) )
+ TakenTotalMod *= ((*i)->GetModifier()->m_amount + 100.0f) / 100.0f;
- if (heal < 0) heal = 0;
+ heal = (heal + TakenTotal) * TakenTotalMod;
- return uint32(heal);
+ return heal < 0 ? 0 : uint32(heal);
}
int32 Unit::SpellBaseHealingBonus(SpellSchoolMask schoolMask)
@@ -9333,25 +8736,28 @@ int32 Unit::SpellBaseHealingBonus(SpellSchoolMask schoolMask)
AuraList const& mHealingDone = GetAurasByType(SPELL_AURA_MOD_HEALING_DONE);
for(AuraList::const_iterator i = mHealingDone.begin();i != mHealingDone.end(); ++i)
if(((*i)->GetModifier()->m_miscvalue & schoolMask) != 0)
- AdvertisedBenefit += (*i)->GetModifierValue();
+ AdvertisedBenefit += (*i)->GetModifier()->m_amount;
// Healing bonus of spirit, intellect and strength
if (GetTypeId() == TYPEID_PLAYER)
{
+ // Base value
+ AdvertisedBenefit +=((Player*)this)->GetBaseSpellHealingBonus();
+
// Healing bonus from stats
AuraList const& mHealingDoneOfStatPercent = GetAurasByType(SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT);
for(AuraList::const_iterator i = mHealingDoneOfStatPercent.begin();i != mHealingDoneOfStatPercent.end(); ++i)
{
// stat used dependent from misc value (stat index)
Stats usedStat = Stats((*i)->GetSpellProto()->EffectMiscValue[(*i)->GetEffIndex()]);
- AdvertisedBenefit += int32(GetStat(usedStat) * (*i)->GetModifierValue() / 100.0f);
+ AdvertisedBenefit += int32(GetStat(usedStat) * (*i)->GetModifier()->m_amount / 100.0f);
}
// ... and attack power
AuraList const& mHealingDonebyAP = GetAurasByType(SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER);
for(AuraList::const_iterator i = mHealingDonebyAP.begin();i != mHealingDonebyAP.end(); ++i)
if ((*i)->GetModifier()->m_miscvalue & schoolMask)
- AdvertisedBenefit += int32(GetTotalAttackPowerValue(BASE_ATTACK) * (*i)->GetModifierValue() / 100.0f);
+ AdvertisedBenefit += int32(GetTotalAttackPowerValue(BASE_ATTACK) * (*i)->GetModifier()->m_amount / 100.0f);
}
return AdvertisedBenefit;
}
@@ -9362,11 +8768,11 @@ int32 Unit::SpellBaseHealingBonusForVictim(SpellSchoolMask schoolMask, Unit *pVi
AuraList const& mDamageTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_HEALING);
for(AuraList::const_iterator i = mDamageTaken.begin();i != mDamageTaken.end(); ++i)
if(((*i)->GetModifier()->m_miscvalue & schoolMask) != 0)
- AdvertisedBenefit += (*i)->GetModifierValue();
+ AdvertisedBenefit += (*i)->GetModifier()->m_amount;
return AdvertisedBenefit;
}
-bool Unit::IsImmunedToDamage(SpellSchoolMask shoolMask, bool useCharges)
+bool Unit::IsImmunedToDamage(SpellSchoolMask shoolMask)
{
//If m_immuneToSchool type contain this school type, IMMUNE damage.
SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
@@ -9383,7 +8789,7 @@ bool Unit::IsImmunedToDamage(SpellSchoolMask shoolMask, bool useCharges)
return false;
}
-bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo, bool useCharges)
+bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo)
{
if (!spellInfo)
return false;
@@ -9407,7 +8813,7 @@ bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo, bool useCharges)
SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC];
for(SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
{
- if(itr->type == spellInfo->Mechanic)
+ if(itr->type & (1<<spellInfo->Mechanic))
{
return true;
}
@@ -9425,18 +8831,39 @@ bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo, bool useCharges)
return false;
}
-bool Unit::IsImmunedToSpellEffect(uint32 effect, uint32 mechanic) const
+bool Unit::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const
{
+ if (!spellInfo)
+ return false;
//If m_immuneToEffect type contain this effect type, IMMUNE effect.
+ uint32 effect = spellInfo->Effect[index];
SpellImmuneList const& effectList = m_spellImmune[IMMUNITY_EFFECT];
for (SpellImmuneList::const_iterator itr = effectList.begin(); itr != effectList.end(); ++itr)
if(itr->type == effect)
return true;
- SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC];
- for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
- if(itr->type == mechanic)
- return true;
+ if(uint32 mechanic = spellInfo->EffectMechanic[index])
+ {
+ SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC];
+ for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
+ if(itr->type & 1<<(spellInfo->EffectMechanic[index]))
+ return true;
+ }
+
+ if(uint32 aura = spellInfo->EffectApplyAuraName[index])
+ {
+ SpellImmuneList const& list = m_spellImmune[IMMUNITY_STATE];
+ for(SpellImmuneList::const_iterator itr = list.begin(); itr != list.end(); ++itr)
+ if(itr->type == aura)
+ return true;
+ // Check for immune to application of harmful magical effects
+ AuraList const& immuneAuraApply = GetAurasByType(SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL);
+ for(AuraList::const_iterator iter = immuneAuraApply.begin(); iter != immuneAuraApply.end(); ++iter)
+ if (spellInfo->Dispel == DISPEL_MAGIC && // Magic debuff
+ ((*iter)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellInfo)) && // Check school
+ !IsPositiveEffect(spellInfo->Id, index)) // Harmful
+ return true;
+ }
return false;
}
@@ -9474,7 +8901,7 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage,WeaponAttackType attT
AuraList const& mDamageDoneCreature = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE);
for(AuraList::const_iterator i = mDamageDoneCreature.begin();i != mDamageDoneCreature.end(); ++i)
if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue))
- DoneFlatBenefit += (*i)->GetModifierValue();
+ DoneFlatBenefit += (*i)->GetModifier()->m_amount;
// ..done
// SPELL_AURA_MOD_DAMAGE_DONE included in weapon damage
@@ -9489,7 +8916,7 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage,WeaponAttackType attT
AuraList const& mCreatureAttackPower = GetAurasByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS);
for(AuraList::const_iterator i = mCreatureAttackPower.begin();i != mCreatureAttackPower.end(); ++i)
if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue))
- APbonus += (*i)->GetModifierValue();
+ APbonus += (*i)->GetModifier()->m_amount;
}
else
{
@@ -9499,7 +8926,7 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage,WeaponAttackType attT
AuraList const& mCreatureAttackPower = GetAurasByType(SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS);
for(AuraList::const_iterator i = mCreatureAttackPower.begin();i != mCreatureAttackPower.end(); ++i)
if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue))
- APbonus += (*i)->GetModifierValue();
+ APbonus += (*i)->GetModifier()->m_amount;
}
if (APbonus!=0) // Can be negative
@@ -9524,7 +8951,7 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage,WeaponAttackType attT
AuraList const& mDamageTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_TAKEN);
for(AuraList::const_iterator i = mDamageTaken.begin();i != mDamageTaken.end(); ++i)
if((*i)->GetModifier()->m_miscvalue & GetMeleeDamageSchoolMask())
- TakenFlatBenefit += (*i)->GetModifierValue();
+ TakenFlatBenefit += (*i)->GetModifier()->m_amount;
if(attType!=RANGED_ATTACK)
TakenFlatBenefit += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN);
@@ -9532,8 +8959,8 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage,WeaponAttackType attT
TakenFlatBenefit += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN);
// Done/Taken total percent damage auras
- float DoneTotalMod = 1;
- float TakenTotalMod = 1;
+ float DoneTotalMod = 1.0f;
+ float TakenTotalMod = 1.0f;
// ..done
// SPELL_AURA_MOD_DAMAGE_PERCENT_DONE included in weapon damage
@@ -9542,13 +8969,13 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage,WeaponAttackType attT
AuraList const& mDamageDoneVersus = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS);
for(AuraList::const_iterator i = mDamageDoneVersus.begin();i != mDamageDoneVersus.end(); ++i)
if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue))
- DoneTotalMod *= ((*i)->GetModifierValue()+100.0f)/100.0f;
+ DoneTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
// ..taken
AuraList const& mModDamagePercentTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN);
for(AuraList::const_iterator i = mModDamagePercentTaken.begin(); i != mModDamagePercentTaken.end(); ++i)
if((*i)->GetModifier()->m_miscvalue & GetMeleeDamageSchoolMask())
- TakenTotalMod *= ((*i)->GetModifierValue()+100.0f)/100.0f;
+ TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
// .. taken pct: dummy auras
AuraList const& mDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY);
@@ -9573,7 +9000,7 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage,WeaponAttackType attT
if(spellProto==NULL)
break;
// Should increase Shred (initial Damage of Lacerate and Rake handled in Spell::EffectSchoolDMG)
- if(spellProto->SpellFamilyName==SPELLFAMILY_DRUID && (spellProto->SpellFamilyFlags==0x00008000LL))
+ if(spellProto->SpellFamilyName==SPELLFAMILY_DRUID && spellProto->SpellFamilyFlags.IsEqual (0x00008000,0,0))
TakenTotalMod *= (100.0f+(*i)->GetModifier()->m_amount)/100.0f;
break;
}
@@ -9606,13 +9033,13 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage,WeaponAttackType attT
{
AuraList const& mModMeleeDamageTakenPercent = pVictim->GetAurasByType(SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT);
for(AuraList::const_iterator i = mModMeleeDamageTakenPercent.begin(); i != mModMeleeDamageTakenPercent.end(); ++i)
- TakenTotalMod *= ((*i)->GetModifierValue()+100.0f)/100.0f;
+ TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
}
else
{
AuraList const& mModRangedDamageTakenPercent = pVictim->GetAurasByType(SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT);
for(AuraList::const_iterator i = mModRangedDamageTakenPercent.begin(); i != mModRangedDamageTakenPercent.end(); ++i)
- TakenTotalMod *= ((*i)->GetModifierValue()+100.0f)/100.0f;
+ TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
}
float tmpDamage = float(int32(*pdamage) + DoneFlatBenefit) * DoneTotalMod;
@@ -9735,7 +9162,7 @@ void Unit::Unmount()
if(GetTypeId() == TYPEID_PLAYER && IsInWorld() && ((Player*)this)->GetTemporaryUnsummonedPetNumber() && isAlive())
{
Pet* NewPet = new Pet;
- if(!NewPet->LoadPetFromDB(this, 0, ((Player*)this)->GetTemporaryUnsummonedPetNumber(), true))
+ if(!NewPet->LoadPetFromDB((Player*)this, 0, ((Player*)this)->GetTemporaryUnsummonedPetNumber(), true))
delete NewPet;
((Player*)this)->SetTemporaryUnsummonedPetNumber(0);
@@ -9767,7 +9194,7 @@ void Unit::SetInCombatWith(Unit* enemy)
void Unit::CombatStart(Unit* target)
{
if(!target->IsStandState()/* && !target->hasUnitState(UNIT_STAT_STUNNED)*/)
- target->SetStandState(PLAYER_STATE_NONE);
+ target->SetStandState(UNIT_STAND_STATE_STAND);
if(!target->isInCombat() && target->GetTypeId() != TYPEID_PLAYER
&& !((Creature*)target)->HasReactState(REACT_PASSIVE) && ((Creature*)target)->AI())
@@ -10051,7 +9478,7 @@ void Unit::DestroyForNearbyPlayers()
std::list<Unit*> targets;
Trinity::AnyUnitInObjectRangeCheck check(this, World::GetMaxVisibleDistance());
- Trinity::UnitListSearcher<Trinity::AnyUnitInObjectRangeCheck> searcher(targets, check);
+ Trinity::UnitListSearcher<Trinity::AnyUnitInObjectRangeCheck> searcher(this, targets, check);
VisitNearbyWorldObject(World::GetMaxVisibleDistance(), searcher);
for(std::list<Unit*>::iterator iter = targets.begin(); iter != targets.end(); ++iter)
if(*iter != this && (*iter)->GetTypeId() == TYPEID_PLAYER
@@ -10175,38 +9602,37 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
propagateSpeedChange();
- // Send speed change packet only for player
- if (GetTypeId()!=TYPEID_PLAYER)
- return;
-
WorldPacket data;
if(!forced)
{
switch(mtype)
{
case MOVE_WALK:
- data.Initialize(MSG_MOVE_SET_WALK_SPEED, 8+4+1+4+4+4+4+4+4+4);
+ 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+1+4+4+4+4+4+4+4);
+ 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+1+4+4+4+4+4+4+4);
+ 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+1+4+4+4+4+4+4+4);
+ 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+1+4+4+4+4+4+4+4);
+ 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+1+4+4+4+4+4+4+4);
+ 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+1+4+4+4+4+4+4+4);
+ 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+1+4+4+4+4+4+4+4);
+ 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:
sLog.outError("Unit::SetSpeed: Unsupported move type (%d), data not sent to client.",mtype);
@@ -10214,22 +9640,26 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
}
data.append(GetPackGUID());
- data << uint32(0); //movement flags
- data << uint8(0); //unk
+ data << uint32(0); // movement flags
+ data << uint16(0); // unk flags
data << uint32(getMSTime());
data << float(GetPositionX());
data << float(GetPositionY());
data << float(GetPositionZ());
data << float(GetOrientation());
- data << uint32(0); //flag unk
+ data << uint32(0); // fall time
data << float(GetSpeed(mtype));
SendMessageToSet( &data, true );
}
else
{
- // register forced speed changes for WorldSession::HandleForceSpeedChangeAck
- // and do it only for real sent packets and use run for run/mounted as client expected
- ++((Player*)this)->m_forced_speed_changes[mtype];
+ 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
+ ++((Player*)this)->m_forced_speed_changes[mtype];
+ }
+
switch(mtype)
{
case MOVE_WALK:
@@ -10256,6 +9686,9 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
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:
sLog.outError("Unit::SetSpeed: Unsupported move type (%d), data not sent to client.",mtype);
return;
@@ -10345,6 +9778,10 @@ bool Unit::CanHaveThreatList() const
if( ((Creature*)this)->isTotem() )
return false;
+ // vehicles can not have threat list
+ if( ((Creature*)this)->isVehicle() )
+ return false;
+
// pets can not have a threat list, unless they are controlled by a creature
if( ((Creature*)this)->isPet() && IS_PLAYER_GUID(((Pet*)this)->GetOwnerGUID()) )
return false;
@@ -10449,18 +9886,44 @@ Unit* Creature::SelectVictim()
//or who does not have threat (totem/pet/critter)
//otherwise enterevademode every update
- Unit* target = NULL;
- if(!m_ThreatManager.isThreatListEmpty())
+
+ Unit* target = NULL;
+ // First checking if we have some taunt on us
+ const AuraList& tauntAuras = GetAurasByType(SPELL_AURA_MOD_TAUNT);
+ if ( !tauntAuras.empty() )
{
- if(!HasAuraType(SPELL_AURA_MOD_TAUNT))
+ Unit* caster;
+
+ // The last taunt aura caster is alive an we are happy to attack him
+ if ( (caster = tauntAuras.back()->GetCaster()) && caster->isAlive() )
+ return getVictim();
+ else if (tauntAuras.size() > 1)
{
- target = m_ThreatManager.getHostilTarget();
+ // We do not have last taunt aura caster but we have more taunt auras,
+ // so find first available target
+
+ // Auras are pushed_back, last caster will be on the end
+ AuraList::const_iterator aura = --tauntAuras.end();
+ do
+ {
+ --aura;
+ if ( (caster = (*aura)->GetCaster()) &&
+ caster->IsInMap(this) && canAttack(caster) && caster->isInAccessiblePlaceFor((Creature*)this) )
+ {
+ target = caster;
+ break;
+ }
+ }while (aura != tauntAuras.begin());
}
else
target = getVictim();
}
+ if ( !target && !m_ThreatManager.isThreatListEmpty() )
+ // No taunt aura or taunt aura caster is dead standart target selection
+ target = m_ThreatManager.getHostilTarget();
+
if(target)
{
if(!hasUnitState(UNIT_STAT_STUNNED))
@@ -10532,8 +9995,11 @@ int32 Unit::CalculateSpellDamage(SpellEntry const* spellProto, uint8 effect_inde
int32 randomPoints = int32(spellProto->EffectDieSides[effect_index] + level * randomPointsPerLevel);
float comboDamage = spellProto->EffectPointsPerComboPoint[effect_index];
- // prevent random generator from getting confused by spells casted with Unit::CastCustomSpell
- int32 randvalue = spellProto->EffectBaseDice[effect_index] >= randomPoints ? spellProto->EffectBaseDice[effect_index]:irand(spellProto->EffectBaseDice[effect_index], randomPoints);
+ // range can have possitive and negative values, so order its for irand
+ int32 randvalue = int32(spellProto->EffectBaseDice[effect_index]) >= randomPoints
+ ? irand(randomPoints, int32(spellProto->EffectBaseDice[effect_index]))
+ : irand(int32(spellProto->EffectBaseDice[effect_index]), randomPoints);
+
int32 value = basePoints + randvalue;
//random damage
if(comboDamage != 0 && unitPlayer /*&& target && (target->GetGUID() == unitPlayer->GetComboTarget())*/)
@@ -10566,7 +10032,7 @@ int32 Unit::CalculateSpellDamage(SpellEntry const* spellProto, uint8 effect_inde
return value;
}
-int32 Unit::CalculateSpellDuration(SpellEntry const* spellProto, uint8 effect_index, Unit const* target)
+int32 Unit::CalcSpellDuration(SpellEntry const* spellProto)
{
Player* unitPlayer = (GetTypeId() == TYPEID_PLAYER) ? (Player*)this : NULL;
@@ -10582,14 +10048,24 @@ int32 Unit::CalculateSpellDuration(SpellEntry const* spellProto, uint8 effect_in
else
duration = minduration;
- if (duration > 0)
+ return duration;
+}
+
+int32 Unit::ModSpellDuration(SpellEntry const* spellProto, uint8 effect_index, Unit const* target, int32 duration)
+{
+ //don't mod permament auras duration
+ if (duration<0)
+ return duration;
+
+ //cut duration only of negative effects
+ if (!IsPositiveEffect(spellProto->Id, effect_index) )
{
int32 mechanic = GetEffectMechanic(spellProto, effect_index);
+
// Find total mod value (negative bonus)
int32 durationMod_always = target->GetTotalAuraModifierByMiscValue(SPELL_AURA_MECHANIC_DURATION_MOD, mechanic);
// Find max mod (negative bonus)
int32 durationMod_not_stack = target->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK, mechanic);
-
int32 durationMod = 0;
// Select strongest negative mod
if (durationMod_always > durationMod_not_stack)
@@ -10598,12 +10074,41 @@ int32 Unit::CalculateSpellDuration(SpellEntry const* spellProto, uint8 effect_in
durationMod = durationMod_always;
if (durationMod != 0)
- duration = int32(int64(duration) * (100+durationMod) /100);
+ duration = int32( float (duration) * float(100.0f+durationMod) /100.0f);
+
+ // there are only negative mods currently
+ durationMod_always =target->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL, spellProto->Dispel);
+ durationMod_not_stack=target->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK, spellProto->Dispel);
+
+ durationMod=0;
+ if (durationMod_always > durationMod_not_stack)
+ durationMod += durationMod_not_stack;
+ else
+ durationMod += durationMod_always;
- if (duration < 0) duration = 0;
+ if (durationMod != 0)
+ duration = int32( float (duration) * float(100.0f+durationMod) /100.0f);
}
+ //else positive mods here, there are no currently
+ //when there will be, change GetTotalAuraModifierByMiscValue to GetTotalPositiveAuraModifierByMiscValue
+ return duration>0 ? duration : 0;
+}
- return duration;
+void Unit::ModSpellCastTime(SpellEntry const* spellProto, int32 & castTime)
+{
+ if (!spellProto || castTime<0)
+ return;
+ //called from caster
+ if(Player* modOwner = GetSpellModOwner())
+ modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CASTING_TIME, castTime);
+
+ if( !(spellProto->Attributes & (SPELL_ATTR_UNK4|SPELL_ATTR_UNK5)) )
+ castTime = int32( float(castTime) * GetFloatValue(UNIT_MOD_CAST_SPEED));
+ else
+ {
+ if (spellProto->Attributes & SPELL_ATTR_RANGED && !(spellProto->AttributesEx2 & SPELL_ATTR_EX2_AUTOREPEAT_FLAG))
+ castTime = int32 (float(castTime) * m_modAttackSpeedPct[RANGED_ATTACK]);
+ }
}
DiminishingLevels Unit::GetDiminishing(DiminishingGroup group)
@@ -10637,21 +10142,15 @@ DiminishingLevels Unit::GetDiminishing(DiminishingGroup group)
void Unit::IncrDiminishing(DiminishingGroup group)
{
// Checking for existing in the table
- bool IsExist = false;
for(Diminishing::iterator i = m_Diminishing.begin(); i != m_Diminishing.end(); ++i)
{
if(i->DRGroup != group)
continue;
-
- IsExist = true;
if(i->hitCount < DIMINISHING_LEVEL_IMMUNE)
i->hitCount += 1;
-
- break;
+ return;
}
-
- if(!IsExist)
- m_Diminishing.push_back(DiminishingReturn(group,getMSTime(),DIMINISHING_LEVEL_2));
+ m_Diminishing.push_back(DiminishingReturn(group,getMSTime(),DIMINISHING_LEVEL_2));
}
void Unit::ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration,Unit* caster,DiminishingLevels Level)
@@ -10700,13 +10199,15 @@ void Unit::ApplyDiminishingAura( DiminishingGroup group, bool apply )
if(i->DRGroup != group)
continue;
- i->hitTime = getMSTime();
-
if(apply)
i->stack += 1;
else if(i->stack)
+ {
i->stack -= 1;
-
+ // Remember time after last aura from group removed
+ if (i->stack == 0)
+ i->hitTime = getMSTime();
+ }
break;
}
}
@@ -10788,7 +10289,9 @@ bool Unit::HandleStatModifier(UnitMods unitMod, UnitModifierType modifierType, f
case UNIT_MOD_RAGE:
case UNIT_MOD_FOCUS:
case UNIT_MOD_ENERGY:
- case UNIT_MOD_HAPPINESS: UpdateMaxPower(GetPowerTypeByAuraGroup(unitMod)); break;
+ case UNIT_MOD_HAPPINESS:
+ case UNIT_MOD_RUNE:
+ case UNIT_MOD_RUNIC_POWER: UpdateMaxPower(GetPowerTypeByAuraGroup(unitMod)); break;
case UNIT_MOD_RESISTANCE_HOLY:
case UNIT_MOD_RESISTANCE_FIRE:
@@ -10901,32 +10404,36 @@ Stats Unit::GetStatByAuraGroup(UnitMods unitMod) const
Powers Unit::GetPowerTypeByAuraGroup(UnitMods unitMod) const
{
- Powers power = POWER_MANA;
-
switch(unitMod)
{
- case UNIT_MOD_MANA: power = POWER_MANA; break;
- case UNIT_MOD_RAGE: power = POWER_RAGE; break;
- case UNIT_MOD_FOCUS: power = POWER_FOCUS; break;
- case UNIT_MOD_ENERGY: power = POWER_ENERGY; break;
- case UNIT_MOD_HAPPINESS: power = POWER_HAPPINESS; break;
-
- default:
- break;
+ case UNIT_MOD_MANA: return POWER_MANA;
+ 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_RUNIC_POWER:return POWER_RUNIC_POWER;
}
- return power;
+ return POWER_MANA;
}
float Unit::GetTotalAttackPowerValue(WeaponAttackType attType) const
{
- UnitMods unitMod = (attType == RANGED_ATTACK) ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER;
-
- float val = GetTotalAuraModValue(unitMod);
- if(val < 0.0f)
- val = 0.0f;
-
- return val;
+ if (attType == RANGED_ATTACK)
+ {
+ int32 ap = GetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER) + GetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER_MODS);
+ 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);
+ if (ap < 0)
+ return 0.0f;
+ return ap * (1.0f + GetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER));
+ }
}
float Unit::GetWeaponDamageRange(WeaponAttackType attType ,WeaponDamageRange type) const
@@ -11014,6 +10521,12 @@ void Unit::SetPower(Powers power, uint32 val)
SetStatInt32Value(UNIT_FIELD_POWER1 + power, val);
+ WorldPacket data(SMSG_POWER_UPDATE);
+ data.append(GetPackGUID());
+ data << uint8(power);
+ data << uint32(val);
+ SendMessageToSet(&data, GetTypeId() == TYPEID_PLAYER ? true : false);
+
// group update
if(GetTypeId() == TYPEID_PLAYER)
{
@@ -11127,6 +10640,7 @@ uint32 Unit::GetCreatePowers( Powers power ) const
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;
}
return 0;
@@ -11214,7 +10728,7 @@ void CharmInfo::InitEmptyActionBar(bool withAttack)
for(uint32 x = 0; x < 10; ++x)
{
- PetActionBar[x].Type = ACT_CAST;
+ PetActionBar[x].Type = ACT_PASSIVE;
PetActionBar[x].SpellOrAction = 0;
}
if (withAttack)
@@ -11230,13 +10744,20 @@ void CharmInfo::InitPossessCreateSpells()
InitEmptyActionBar();
if(m_unit->GetTypeId() == TYPEID_UNIT)
{
- for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i)
+ /*for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i)
{
uint32 spellid = ((Creature*)m_unit)->m_spells[i];
if(IsPassiveSpell(spellid))
m_unit->CastSpell(m_unit, spellid, true);
else
AddSpellToAB(0, spellid, ACT_CAST);
+ }*/
+ for(uint32 x = 0; x < CREATURE_MAX_SPELLS; ++x)
+ {
+ if (IsPassiveSpell(((Creature*)m_unit)->m_spells[x]))
+ m_unit->CastSpell(m_unit, ((Creature*)m_unit)->m_spells[x], true);
+ else
+ AddSpellToAB(0, ((Creature*)m_unit)->m_spells[x], ACT_PASSIVE);
}
}
}
@@ -11280,7 +10801,7 @@ void CharmInfo::InitCharmCreateSpells()
if(onlyselfcast || !IsPositiveSpell(spellId)) //only self cast and spells versus enemies are autocastable
newstate = ACT_DISABLED;
else
- newstate = ACT_CAST;
+ newstate = ACT_PASSIVE;
AddSpellToAB(0, spellId, newstate);
}
@@ -11291,7 +10812,7 @@ bool CharmInfo::AddSpellToAB(uint32 oldid, uint32 newid, ActiveStates newstate)
{
for(uint8 i = 0; i < 10; i++)
{
- if((PetActionBar[i].Type == ACT_DISABLED || PetActionBar[i].Type == ACT_ENABLED || PetActionBar[i].Type == ACT_CAST) && PetActionBar[i].SpellOrAction == oldid)
+ if((PetActionBar[i].Type == ACT_DISABLED || PetActionBar[i].Type == ACT_ENABLED || PetActionBar[i].Type == ACT_PASSIVE) && PetActionBar[i].SpellOrAction == oldid)
{
PetActionBar[i].SpellOrAction = newid;
if(!oldid)
@@ -11333,188 +10854,9 @@ void CharmInfo::SetPetNumber(uint32 petnumber, bool statwindow)
bool Unit::isFrozen() const
{
- AuraList const& mRoot = GetAurasByType(SPELL_AURA_MOD_ROOT);
- for(AuraList::const_iterator i = mRoot.begin(); i != mRoot.end(); ++i)
- if( GetSpellSchoolMask((*i)->GetSpellProto()) & SPELL_SCHOOL_MASK_FROST)
- return true;
- return false;
+ return HasAuraState(AURA_STATE_FROZEN);
}
-/*
-struct ProcTriggeredData
-{
- ProcTriggeredData(Aura* _triggeredByAura, uint32 _cooldown)
- : triggeredByAura(_triggeredByAura),
- triggeredByAura_SpellPair(Unit::spellEffectPair(triggeredByAura->GetId(),triggeredByAura->GetEffIndex())),
- cooldown(_cooldown)
- {}
-
- Aura* triggeredByAura; // triggred aura, can be invalidate at triggered aura proccessing
- Unit::spellEffectPair triggeredByAura_SpellPair; // spell pair, used for re-find aura (by pointer comparison in range)
- uint32 cooldown; // possible hidden cooldown
-};
-
-typedef std::list< ProcTriggeredData > ProcTriggeredList;
-
-void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag, AuraTypeSet const& procAuraTypes, WeaponAttackType attType, SpellEntry const * procSpell, uint32 damage, SpellSchoolMask damageSchoolMask )
-{
- for(AuraTypeSet::const_iterator aur = procAuraTypes.begin(); aur != procAuraTypes.end(); ++aur)
- {
- // List of spells (effects) that proceed. Spell prototype and aura-specific value (damage for TRIGGER_DAMAGE)
- ProcTriggeredList procTriggered;
-
- AuraList const& auras = GetAurasByType(*aur);
- for(AuraList::const_iterator i = auras.begin(), next; i != auras.end(); i = next)
- {
- next = i; ++next;
-
- Aura* i_aura = *i;
-
- uint32 cooldown; // returned at next line
- if(!IsTriggeredAtSpellProcEvent(i_aura->GetSpellProto(), procSpell, procFlag,attType,isVictim,cooldown))
- continue;
-
- procTriggered.push_back( ProcTriggeredData(i_aura, cooldown) );
- }
-
- // Handle effects proceed this time
- for(ProcTriggeredList::iterator i = procTriggered.begin(); i != procTriggered.end(); ++i)
- {
- // Some auras can be deleted in function called in this loop (except first, ofc)
- // Until storing auras in std::multimap to hard check deleting by another way
- if(i != procTriggered.begin())
- {
- bool found = false;
- AuraMap::const_iterator lower = GetAuras().lower_bound(i->triggeredByAura_SpellPair);
- AuraMap::const_iterator upper = GetAuras().upper_bound(i->triggeredByAura_SpellPair);
- for(AuraMap::const_iterator itr = lower; itr!= upper; ++itr)
- {
- if(itr->second==i->triggeredByAura)
- {
- found = true;
- break;
- }
- }
-
- if(!found)
- {
- sLog.outError("Spell aura %u (id:%u effect:%u) has been deleted before call spell proc event handler",*aur,i->triggeredByAura_SpellPair.first,i->triggeredByAura_SpellPair.second);
- sLog.outError("It can be deleted one from early processed auras:");
- for(ProcTriggeredList::iterator i2 = procTriggered.begin(); i != i2; ++i2)
- sLog.outError(" Spell aura %u (id:%u effect:%u)",*aur,i2->triggeredByAura_SpellPair.first,i2->triggeredByAura_SpellPair.second);
- sLog.outError(" <end of list>");
- continue;
- }
- }
-
- /// this is aura triggering code call
- Aura* triggeredByAura = i->triggeredByAura;
-
- /// save charges existence before processing to prevent crash at access to deleted triggered aura after
- /// used in speedup code check before check aura existance.
- bool triggeredByAuraWithCharges = triggeredByAura->m_procCharges > 0;
-
- /// success in event proccesing
- /// used in speedup code check before check aura existance.
- bool casted = false;
-
- /// process triggered code
- switch(*aur)
- {
- case SPELL_AURA_PROC_TRIGGER_SPELL:
- {
- sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s proc aura of spell %u)",
- (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId());
- casted = HandleProcTriggerSpell(pTarget, damage, triggeredByAura, procSpell, procFlag, attType, i->cooldown);
- break;
- }
- case SPELL_AURA_PROC_TRIGGER_DAMAGE:
- {
- uint32 triggered_damage = triggeredByAura->GetModifier()->m_amount;
- sLog.outDebug("ProcDamageAndSpell: doing %u damage (triggered by %s aura of spell %u)",
- triggered_damage, (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId());
- SpellNonMeleeDamageLog(pTarget, triggeredByAura->GetId(), triggered_damage, true, true);
- casted = true;
- break;
- }
- case SPELL_AURA_DUMMY:
- {
- uint32 effect = triggeredByAura->GetEffIndex();
- sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s dummy aura of spell %u)",
- (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId());
- casted = HandleDummyAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag,i->cooldown);
- break;
- }
- case SPELL_AURA_PRAYER_OF_MENDING:
- {
- sLog.outDebug("ProcDamageAndSpell: casting mending (triggered by %s dummy aura of spell %u)",
- (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId());
-
- casted = HandleMeandingAuraProc(triggeredByAura);
- break;
- }
- case SPELL_AURA_MOD_HASTE:
- {
- sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s haste aura of spell %u)",
- (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId());
- casted = HandleHasteAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag,i->cooldown);
- break;
- }
- case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN:
- {
- // nothing do, just charges counter
- // but count only in case appropriate school damage
- casted = triggeredByAura->GetModifier()->m_miscvalue & damageSchoolMask;
- break;
- }
- case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS:
- {
- sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s class script aura of spell %u)",
- (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId());
- casted = HandleOverrideClassScriptAuraProc(pTarget, triggeredByAura, procSpell,i->cooldown);
- break;
- }
- default:
- {
- // nothing do, just charges counter
- casted = true;
- break;
- }
- }
-
- /// Update charge (aura can be removed by triggers)
- if(casted && triggeredByAuraWithCharges)
- {
- /// need re-found aura (can be dropped by triggers)
- AuraMap::const_iterator lower = GetAuras().lower_bound(i->triggeredByAura_SpellPair);
- AuraMap::const_iterator upper = GetAuras().upper_bound(i->triggeredByAura_SpellPair);
- for(AuraMap::const_iterator itr = lower; itr!= upper; ++itr)
- {
- if(itr->second == triggeredByAura) // pointer still valid
- {
- if(triggeredByAura->m_procCharges > 0)
- triggeredByAura->m_procCharges -= 1;
-
- triggeredByAura->UpdateAuraCharges();
- break;
- }
- }
- }
- }
-
- /// Safely remove auras with zero charges
- for(AuraList::const_iterator i = auras.begin(), next; i != auras.end(); i = next)
- {
- next = i; ++next;
- if((*i)->m_procCharges == 0)
- {
- RemoveAurasDueToSpell((*i)->GetId());
- next = auras.begin();
- }
- }
- }
-}
-*/
struct ProcTriggeredData
{
ProcTriggeredData(SpellProcEventEntry const * _spellProcEvent, Aura* _triggeredByAura)
@@ -11533,9 +10875,7 @@ typedef std::list< uint32> RemoveSpellList;
// in most case need for drop charges
// in some types of aura need do additional check
// for example SPELL_AURA_MECHANIC_IMMUNITY - need check for mechanic
-static bool isTriggerAura[TOTAL_AURAS];
-static bool isNonTriggerAura[TOTAL_AURAS];
-void InitTriggerAuraData()
+bool InitTriggerAuraData()
{
for (int i=0;i<TOTAL_AURAS;i++)
{
@@ -11554,7 +10894,7 @@ void InitTriggerAuraData()
isTriggerAura[SPELL_AURA_DAMAGE_IMMUNITY] = true;
isTriggerAura[SPELL_AURA_PROC_TRIGGER_SPELL] = true;
isTriggerAura[SPELL_AURA_PROC_TRIGGER_DAMAGE] = true;
- isTriggerAura[SPELL_AURA_MOD_CASTING_SPEED] = true;
+ isTriggerAura[SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK] = true;
isTriggerAura[SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT] = true;
isTriggerAura[SPELL_AURA_MOD_POWER_COST_SCHOOL] = true;
isTriggerAura[SPELL_AURA_REFLECT_SPELLS_SCHOOL] = true;
@@ -11569,9 +10909,13 @@ void InitTriggerAuraData()
isTriggerAura[SPELL_AURA_MOD_HASTE] = true;
isTriggerAura[SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE]=true;
isTriggerAura[SPELL_AURA_PRAYER_OF_MENDING] = true;
+ isTriggerAura[SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE] = true;
+ isTriggerAura[SPELL_AURA_MOD_DAMAGE_FROM_CASTER] = true;
isNonTriggerAura[SPELL_AURA_MOD_POWER_REGEN]=true;
- isNonTriggerAura[SPELL_AURA_RESIST_PUSHBACK]=true;
+ isNonTriggerAura[SPELL_AURA_REDUCE_PUSHBACK]=true;
+
+ return true;
}
uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missCondition)
@@ -11612,18 +10956,8 @@ uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missC
return procEx;
}
-static int deep = 0;
void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, SpellEntry const * procSpell, uint32 damage )
{
- deep ++;
- if (deep > 5)
- {
- sLog.outError("Prevent possible stack owerflow in Unit::ProcDamageAndSpellFor");
- if (procSpell)
- sLog.outError(" Spell %u", procSpell->Id);
- deep--;
- return;
- }
// For melee/ranged based attack need update skills and set some Aura states
if (procFlag & MELEE_BASED_TRIGGER_MASK)
{
@@ -11634,7 +10968,7 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
if (procExtra&(PROC_EX_NORMAL_HIT|PROC_EX_MISS|PROC_EX_RESIST))
{
if (pTarget->GetTypeId() != TYPEID_PLAYER && pTarget->GetCreatureType() != CREATURE_TYPE_CRITTER)
- ((Player*)this)->UpdateCombatSkills(pTarget, attType, MELEE_HIT_MISS, isVictim);
+ ((Player*)this)->UpdateCombatSkills(pTarget, attType, isVictim);
}
// Update defence if player is victim and parry/dodge/block
if (isVictim && procExtra&(PROC_EX_DODGE|PROC_EX_PARRY|PROC_EX_BLOCK))
@@ -11686,17 +11020,6 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
((Player*)this)->AddComboPoints(pTarget, 1);
StartReactiveTimer( REACTIVE_OVERPOWER );
}
- // Enable AURA_STATE_CRIT on crit
- if (procExtra & PROC_EX_CRITICAL_HIT)
- {
- ModifyAuraState(AURA_STATE_CRIT, true);
- StartReactiveTimer( REACTIVE_CRIT );
- if(getClass()==CLASS_HUNTER)
- {
- ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE, true);
- StartReactiveTimer( REACTIVE_HUNTER_CRIT );
- }
- }
}
}
}
@@ -11707,11 +11030,16 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
for(AuraMap::const_iterator itr = GetAuras().begin(); itr!= GetAuras().end(); ++itr)
{
SpellProcEventEntry const* spellProcEvent = NULL;
- if(!IsTriggeredAtSpellProcEvent(itr->second, procSpell, procFlag, procExtra, attType, isVictim, (damage > 0), spellProcEvent))
+ if(!IsTriggeredAtSpellProcEvent(pTarget, itr->second, procSpell, procFlag, procExtra, attType, isVictim, (damage > 0), spellProcEvent))
continue;
procTriggered.push_back( ProcTriggeredData(spellProcEvent, itr->second) );
}
+
+ // Nothing found
+ if (procTriggered.empty())
+ return;
+
// Handle effects proceed this time
for(ProcTriggeredList::iterator i = procTriggered.begin(); i != procTriggered.end(); ++i)
{
@@ -11746,7 +11074,7 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
Modifier *auraModifier = triggeredByAura->GetModifier();
SpellEntry const *spellInfo = triggeredByAura->GetSpellProto();
uint32 effIndex = triggeredByAura->GetEffIndex();
- bool useCharges = triggeredByAura->m_procCharges > 0;
+ bool useCharges = triggeredByAura->GetAuraCharges() > 0;
// For players set spell cooldown if need
uint32 cooldown = 0;
if (GetTypeId() == TYPEID_PLAYER && spellProcEvent && spellProcEvent->cooldown)
@@ -11790,7 +11118,7 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS:
{
sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
- if (!HandleOverrideClassScriptAuraProc(pTarget, triggeredByAura, procSpell, cooldown))
+ if (!HandleOverrideClassScriptAuraProc(pTarget, damage, triggeredByAura, procSpell, cooldown))
continue;
break;
}
@@ -11802,23 +11130,15 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
HandleMeandingAuraProc(triggeredByAura);
break;
}
- case SPELL_AURA_MOD_STUN:
- // Remove by default, but if charge exist drop it
- if (triggeredByAura->m_procCharges == 0)
- removedSpells.push_back(triggeredByAura->GetId());
- break;
- case SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS:
- case SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS:
- // Hunter's Mark (1-4 Rangs)
- if (spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && (spellInfo->SpellFamilyFlags&0x0000000000000400LL))
- {
- uint32 basevalue = triggeredByAura->GetBasePoints();
- auraModifier->m_amount += basevalue/10;
- if (auraModifier->m_amount > basevalue*4)
- auraModifier->m_amount = basevalue*4;
- }
+ case SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE:
+ {
+ sLog.outDebug("ProcDamageAndSpell: casting spell %u (triggered with value by %s aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+
+ if (!HandleProcTriggerSpell(pTarget, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
+ continue;
break;
- case SPELL_AURA_MOD_CASTING_SPEED:
+ }
+ case SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK:
// Skip melee hits or instant cast spells
if (procSpell == NULL || GetSpellCastTime(procSpell) == 0)
continue;
@@ -11846,6 +11166,11 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
if (procSpell==NULL || procSpell->Mechanic != auraModifier->m_miscvalue)
continue;
break;
+ case SPELL_AURA_MOD_DAMAGE_FROM_CASTER:
+ // Compare casters
+ if (triggeredByAura->GetCasterGUID() != pTarget->GetGUID())
+ continue;
+ break;
default:
// nothing do, just charges counter
break;
@@ -11858,18 +11183,16 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
AuraMap::const_iterator upper = GetAuras().upper_bound(i->triggeredByAura_SpellPair);
for(AuraMap::const_iterator itr = lower; itr!= upper; ++itr)
{
- if(itr->second == i->triggeredByAura)
+ // If last charge dropped add spell to remove list
+ if(itr->second == i->triggeredByAura && triggeredByAura->DropAuraCharge())
{
- triggeredByAura->m_procCharges -=1;
- triggeredByAura->UpdateAuraCharges();
- if (triggeredByAura->m_procCharges <= 0)
- removedSpells.push_back(triggeredByAura->GetId());
+ removedSpells.push_back(triggeredByAura->GetId());
break;
}
}
}
}
- if (removedSpells.size())
+ if (!removedSpells.empty())
{
// Sort spells and remove dublicates
removedSpells.sort();
@@ -11878,7 +11201,6 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
for(RemoveSpellList::const_iterator i = removedSpells.begin(); i != removedSpells.end();i++)
RemoveAurasDueToSpell(*i);
}
- deep--;
}
SpellSchoolMask Unit::GetMeleeDamageSchoolMask() const
@@ -11907,8 +11229,11 @@ void Unit::SendPetCastFail(uint32 spellid, uint8 msg)
return;
WorldPacket data(SMSG_PET_CAST_FAILED, (4+1));
+ data << uint8(0); // cast count?
data << uint32(spellid);
data << uint8(msg);
+ // uint32 for some reason
+ // uint32 for some reason
((Player*)owner)->GetSession()->SendPacket(&data);
}
@@ -12068,15 +11393,16 @@ void Unit::SetConfused(bool apply, uint64 casterGUID, uint32 spellID)
bool Unit::IsSitState() const
{
uint8 s = getStandState();
- return s == PLAYER_STATE_SIT_CHAIR || s == PLAYER_STATE_SIT_LOW_CHAIR ||
- s == PLAYER_STATE_SIT_MEDIUM_CHAIR || s == PLAYER_STATE_SIT_HIGH_CHAIR ||
- s == PLAYER_STATE_SIT;
+ return
+ s == UNIT_STAND_STATE_SIT_CHAIR || s == UNIT_STAND_STATE_SIT_LOW_CHAIR ||
+ s == UNIT_STAND_STATE_SIT_MEDIUM_CHAIR || s == UNIT_STAND_STATE_SIT_HIGH_CHAIR ||
+ s == UNIT_STAND_STATE_SIT;
}
bool Unit::IsStandState() const
{
uint8 s = getStandState();
- return !IsSitState() && s != PLAYER_STATE_SLEEP && s != PLAYER_STATE_KNEEL;
+ return !IsSitState() && s != UNIT_STAND_STATE_SLEEP && s != UNIT_STAND_STATE_KNEEL;
}
void Unit::SetStandState(uint8 state)
@@ -12130,7 +11456,6 @@ void Unit::ClearComboPointHolders()
void Unit::ClearAllReactives()
{
-
for(int i=0; i < MAX_REACTIVE; ++i)
m_reactiveTimer[i] = 0;
@@ -12138,11 +11463,6 @@ void Unit::ClearAllReactives()
ModifyAuraState(AURA_STATE_DEFENSE, false);
if (getClass() == CLASS_HUNTER && HasAuraState( AURA_STATE_HUNTER_PARRY))
ModifyAuraState(AURA_STATE_HUNTER_PARRY, false);
- if (HasAuraState( AURA_STATE_CRIT))
- ModifyAuraState(AURA_STATE_CRIT, false);
- if (getClass() == CLASS_HUNTER && HasAuraState( AURA_STATE_HUNTER_CRIT_STRIKE) )
- ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE, false);
-
if(getClass() == CLASS_WARRIOR && GetTypeId() == TYPEID_PLAYER)
((Player*)this)->ClearComboPoints();
}
@@ -12170,14 +11490,6 @@ void Unit::UpdateReactives( uint32 p_time )
if ( getClass() == CLASS_HUNTER && HasAuraState(AURA_STATE_HUNTER_PARRY))
ModifyAuraState(AURA_STATE_HUNTER_PARRY, false);
break;
- case REACTIVE_CRIT:
- if (HasAuraState(AURA_STATE_CRIT))
- ModifyAuraState(AURA_STATE_CRIT, false);
- break;
- case REACTIVE_HUNTER_CRIT:
- if ( getClass() == CLASS_HUNTER && HasAuraState(AURA_STATE_HUNTER_CRIT_STRIKE) )
- ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE, false);
- break;
case REACTIVE_OVERPOWER:
if(getClass() == CLASS_WARRIOR && GetTypeId() == TYPEID_PLAYER)
((Player*)this)->ClearComboPoints();
@@ -12197,7 +11509,7 @@ Unit* Unit::SelectNearbyTarget(float dist) const
{
std::list<Unit *> targets;
Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(this, this, dist);
- Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(targets, u_check);
+ Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(this, targets, u_check);
VisitNearbyObject(dist, searcher);
// remove current target
@@ -12230,6 +11542,16 @@ Unit* Unit::SelectNearbyTarget(float dist) const
return *tcIter;
}
+bool Unit::hasNegativeAuraWithInterruptFlag(uint32 flag)
+{
+ for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); ++iter)
+ {
+ if (!iter->second->IsPositive() && iter->second->GetSpellProto()->AuraInterruptFlags & flag)
+ return true;
+ }
+ return false;
+}
+
void Unit::ApplyAttackTimePercentMod( WeaponAttackType att,float val, bool apply )
{
float remainingTimePct = (float)m_attackTimer[att] / (GetAttackTime(att) * m_modAttackSpeedPct[att]);
@@ -12291,6 +11613,8 @@ uint32 Unit::GetCastingTimeForBonus( SpellEntry const *spellProto, DamageEffectT
case SPELL_AURA_PERIODIC_LEECH:
if ( GetSpellDuration(spellProto) )
overTime = GetSpellDuration(spellProto);
+ if (IsChanneledSpell(spellProto))
+ ModSpellCastTime(spellProto, overTime);
break;
default:
// -5% per additional effect
@@ -12346,13 +11670,15 @@ uint32 Unit::GetCastingTimeForBonus( SpellEntry const *spellProto, DamageEffectT
void Unit::UpdateAuraForGroup(uint8 slot)
{
+ if(slot >= MAX_AURAS) // slot not found, return
+ return;
if(GetTypeId() == TYPEID_PLAYER)
{
Player* player = (Player*)this;
if(player->GetGroup())
{
player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_AURAS);
- player->SetAuraUpdateMask(slot);
+ player->SetAuraUpdateMaskForRaid(slot);
}
}
else if(GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isPet())
@@ -12364,10 +11690,11 @@ void Unit::UpdateAuraForGroup(uint8 slot)
if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
{
((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_AURAS);
- pet->SetAuraUpdateMask(slot);
+ pet->SetAuraUpdateMaskForRaid(slot);
}
}
}
+ SetAuraUpdateMask(slot);
}
float Unit::GetAPMultiplier(WeaponAttackType attType, bool normalized)
@@ -12462,7 +11789,12 @@ Pet* Unit::CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id)
pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, getFaction());
pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, spell_id);
- if(!pet->InitStatsForLevel(creatureTarget->getLevel()))
+ if(GetTypeId()==TYPEID_PLAYER)
+ pet->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
+
+ uint32 level = (creatureTarget->getLevel() < (getLevel() - 5)) ? (getLevel() - 5) : creatureTarget->getLevel();
+
+ if(!pet->InitStatsForLevel(level))
{
sLog.outError("ERROR: Pet::InitStatsForLevel() failed for creature (Entry: %u)!",creatureTarget->GetEntry());
delete pet;
@@ -12473,12 +11805,13 @@ Pet* Unit::CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id)
// this enables pet details window (Shift+P)
pet->AIM_Initialize();
pet->InitPetCreateSpells();
+ pet->InitTalentForLevel();
pet->SetHealth(pet->GetMaxHealth());
return pet;
}
-bool Unit::IsTriggeredAtSpellProcEvent(Aura* aura, SpellEntry const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent )
+bool Unit::IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura* aura, SpellEntry const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent )
{
SpellEntry const* spellProto = aura->GetSpellProto ();
@@ -12508,7 +11841,17 @@ bool Unit::IsTriggeredAtSpellProcEvent(Aura* aura, SpellEntry const* procSpell,
if(!SpellMgr::IsSpellProcEventCanTriggeredBy(spellProcEvent, EventProcFlag, procSpell, procFlag, procExtra, active))
return false;
- // Aura added by spell can`t trogger from self (prevent drop cahres/do triggers)
+ // In most cases req get honor or XP from kill
+ if (EventProcFlag & PROC_FLAG_KILL && GetTypeId() == TYPEID_PLAYER)
+ {
+ bool allow = ((Player*)this)->isHonorOrXPTarget(pVictim);
+ // Shadow Word: Death - can trigger from every kill
+ if (aura->GetId() == 32409)
+ allow = true;
+ if (!allow)
+ return false;
+ }
+ // Aura added by spell can`t trogger from self (prevent drop charges/do triggers)
// But except periodic triggers (can triggered from self)
if(procSpell && procSpell->Id == spellProto->Id && !(spellProto->procFlags&PROC_FLAG_ON_TAKE_PERIODIC))
return false;
@@ -12520,13 +11863,13 @@ bool Unit::IsTriggeredAtSpellProcEvent(Aura* aura, SpellEntry const* procSpell,
{
Item *item = NULL;
if(attType == BASE_ATTACK)
- item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
+ item = ((Player*)this)->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
else if (attType == OFF_ATTACK)
- item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
+ item = ((Player*)this)->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
else
- item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED);
+ item = ((Player*)this)->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED);
- if (!((Player*)this)->IsUseEquipedWeapon(attType==BASE_ATTACK))
+ if (((Player*)this)->IsInFeralForm())
return false;
if(!item || item->IsBroken() || item->GetProto()->Class != ITEM_CLASS_WEAPON || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask))
@@ -12535,7 +11878,7 @@ bool Unit::IsTriggeredAtSpellProcEvent(Aura* aura, SpellEntry const* procSpell,
else if(spellProto->EquippedItemClass == ITEM_CLASS_ARMOR)
{
// Check if player is wearing shield
- Item *item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
+ Item *item = ((Player*)this)->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
if(!item || item->IsBroken() || item->GetProto()->Class != ITEM_CLASS_ARMOR || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask))
return false;
}
@@ -12553,7 +11896,10 @@ bool Unit::IsTriggeredAtSpellProcEvent(Aura* aura, SpellEntry const* procSpell,
}
// Apply chance modifer aura
if(Player* modOwner = GetSpellModOwner())
+ {
modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_CHANCE_OF_SUCCESS,chance);
+ modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_PROC_CHANCE,chance);
+ }
return roll_chance_f(chance);
}
@@ -12567,10 +11913,10 @@ bool Unit::HandleMeandingAuraProc( Aura* triggeredByAura )
uint64 caster_guid = triggeredByAura->GetCasterGUID();
// jumps
- int32 jumps = triggeredByAura->m_procCharges-1;
+ int32 jumps = triggeredByAura->GetAuraCharges()-1;
// current aura expire
- triggeredByAura->m_procCharges = 1; // will removed at next charges decrease
+ triggeredByAura->SetAuraCharges(1); // will removed at next charges decrease
// next target selection
if(jumps > 0 && GetTypeId()==TYPEID_PLAYER && IS_PLAYER_GUID(caster_guid))
@@ -12593,10 +11939,7 @@ bool Unit::HandleMeandingAuraProc( Aura* triggeredByAura )
mod->value = jumps-5; // negative
mod->type = SPELLMOD_FLAT;
mod->spellId = spellProto->Id;
- mod->effectId = effIdx;
- mod->lastAffected = NULL;
- mod->mask = spellProto->SpellFamilyFlags;
- mod->charges = 0;
+ mod->mask = spellProto->SpellFamilyFlags;
caster->AddSpellMod(mod, true);
CastCustomSpell(target,spellProto->Id,&heal,NULL,NULL,true,NULL,triggeredByAura,caster->GetGUID());
@@ -12654,7 +11997,7 @@ void Unit::Kill(Unit *pVictim, bool durabilityLoss)
if(player && player!=pVictim)
{
if(player->RewardPlayerAndGroupAtKill(pVictim))
- player->ProcDamageAndSpell(pVictim, PROC_FLAG_KILL_AND_GET_XP, PROC_FLAG_KILLED, PROC_EX_NONE, 0);
+ player->ProcDamageAndSpell(pVictim, PROC_FLAG_KILL, PROC_FLAG_KILLED, PROC_EX_NONE, 0);
else
player->ProcDamageAndSpell(pVictim, PROC_FLAG_NONE, PROC_FLAG_KILLED,PROC_EX_NONE, 0);
}
@@ -12786,6 +12129,15 @@ void Unit::Kill(Unit *pVictim, bool durabilityLoss)
bg->HandleKillUnit((Creature*)pVictim, player);
}
}
+
+ // achievement stuff
+ if ( pVictim->GetTypeId() == TYPEID_PLAYER)
+ {
+ if(GetTypeId() == TYPEID_UNIT)
+ ((Player*)pVictim)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE, GetEntry());
+ else if(GetTypeId() == TYPEID_PLAYER)
+ ((Player*)pVictim)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER, 1);
+ }
}
void Unit::SetControlled(bool apply, UnitState state)
@@ -12855,7 +12207,7 @@ void Unit::SetStunned(bool apply)
if(apply)
{
SetUInt64Value(UNIT_FIELD_TARGET, 0);
- SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
+ SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
CastStop();
// Creature specific
@@ -12873,7 +12225,7 @@ void Unit::SetStunned(bool apply)
{
if(isAlive() && getVictim())
SetUInt64Value(UNIT_FIELD_TARGET, getVictim()->GetGUID());
- RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
+ RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
if(!hasUnitState(UNIT_STAT_ROOT)) // prevent allow move if have also root effect
{
@@ -13008,7 +12360,7 @@ void Unit::SetCharmedOrPossessedBy(Unit* charmer, bool possess)
{
if(((Player*)this)->isAFK())
((Player*)this)->ToggleAFK();
- ((Player*)this)->SetViewport(GetGUID(), false);
+ ((Player*)this)->SetClientControl(this, 0);
}
// Pets already have a properly initialized CharmInfo, don't overwrite it.
@@ -13026,9 +12378,10 @@ void Unit::SetCharmedOrPossessedBy(Unit* charmer, bool possess)
if(possess)
{
addUnitState(UNIT_STAT_POSSESSED);
- SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5);
+ SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
AddPlayerToVision((Player*)charmer);
- ((Player*)charmer)->SetViewport(GetGUID(), true);
+ ((Player*)charmer)->SetClientControl(this, 1);
+ ((Player*)charmer)->SetMover(this);
charmer->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
}
// Charm demon
@@ -13077,7 +12430,7 @@ void Unit::RemoveCharmedOrPossessedBy(Unit *charmer)
if(possess)
{
clearUnitState(UNIT_STAT_POSSESSED);
- RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5);
+ RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
}
if(GetTypeId() == TYPEID_UNIT)
@@ -13098,7 +12451,7 @@ void Unit::RemoveCharmedOrPossessedBy(Unit *charmer)
}
}
else
- ((Player*)this)->SetViewport(GetGUID(), true);
+ ((Player*)this)->SetClientControl(this, 1);
// If charmer still exists
if(!charmer)
@@ -13110,7 +12463,8 @@ void Unit::RemoveCharmedOrPossessedBy(Unit *charmer)
if(possess)
{
RemovePlayerFromVision((Player*)charmer);
- ((Player*)charmer)->SetViewport(charmer->GetGUID(), true);
+ ((Player*)charmer)->SetClientControl(charmer, 1);
+ ((Player*)charmer)->SetMover(charmer);
charmer->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
}
// restore UNIT_FIELD_BYTES_0
@@ -13251,6 +12605,55 @@ void Unit::GetPartyMember(std::list<Unit*> &TagUnitMap, float radius)
}
}
+void Unit::SendAuraUpdate(uint8 slot)
+{
+ WorldPacket data(SMSG_AURA_UPDATE);
+
+ Aura * ptr=NULL;
+ VisibleAuraMap const *visibleAuras = GetVisibleAuras();
+ AuraSlotEntry * entry=GetVisibleAura(slot);
+ if (!entry)
+ return;
+
+ //Get pointer to first aura-it doesn't matter which one we use (at least it shouldn't)
+ for (uint8 i=0 ; i<3; i++)
+ {
+ if (entry->m_slotAuras[i])
+ {
+ ptr=entry->m_slotAuras[i];
+ break;
+ }
+ }
+
+ data.append(GetPackGUID());
+ data << uint8(slot);
+ data << uint32(ptr ? ptr->GetId() : 0);
+
+ if(!ptr)
+ {
+ RemoveVisibleAura(slot);
+ SendMessageToSet(&data, true);
+ return;
+ }
+
+ data << uint8(entry->m_Flags);
+ data << uint8(entry->m_Level);
+ data << uint8(ptr->GetAuraCharges()? ptr->GetAuraCharges() : ptr->GetStackAmount());
+
+ if(!(entry->m_Flags & AFLAG_NOT_CASTER))
+ {
+ data << uint8(0); // pguid
+ }
+
+ if(entry->m_Flags & AFLAG_DURATION)
+ {
+ data << uint32(ptr->GetAuraMaxDuration());
+ data << uint32(ptr->GetAuraDuration());
+ }
+
+ SendMessageToSet(&data, true);
+}
+
void Unit::AddAura(uint32 spellId, Unit* target)
{
if(!target || !target->isAlive())
@@ -13267,7 +12670,7 @@ void Unit::AddAura(uint32 spellId, Unit* target)
{
if(spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA)
{
- if(target->IsImmunedToSpellEffect(spellInfo->Effect[i], spellInfo->EffectMechanic[i]))
+ if(target->IsImmunedToSpellEffect(spellInfo, i))
continue;
/*if(spellInfo->EffectImplicitTargetA[i] == TARGET_UNIT_CASTER)
@@ -13282,4 +12685,70 @@ void Unit::AddAura(uint32 spellId, Unit* target)
}
}
}
-} \ No newline at end of file
+}
+
+// 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 *pVictim, WeaponAttackType attType, int32 skillDiff, uint32 spellId) const
+{
+ // Calculate hit chance (more correct for chance mod)
+ int32 HitChance;
+
+ // PvP - PvE melee chances
+ /*int32 lchance = pVictim->GetTypeId() == TYPEID_PLAYER ? 5 : 7;
+ int32 leveldif = pVictim->getLevelForTarget(this) - getLevelForTarget(pVictim);
+ if(leveldif < 3)
+ HitChance = 95 - leveldif;
+ else
+ HitChance = 93 - (leveldif - 2) * lchance;*/
+ if (spellId || attType == RANGED_ATTACK || !haveOffhandWeapon())
+ HitChance = 95.0f;
+ else
+ HitChance = 76.0f;
+
+ // Hit chance depends from victim auras
+ if(attType == RANGED_ATTACK)
+ HitChance += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE);
+ else
+ HitChance += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE);
+
+ // Spellmod from SPELLMOD_RESIST_MISS_CHANCE
+ if(spellId)
+ {
+ if(Player *modOwner = GetSpellModOwner())
+ modOwner->ApplySpellMod(spellId, SPELLMOD_RESIST_MISS_CHANCE, HitChance);
+ }
+
+ // Miss = 100 - hit
+ float miss_chance= 100.0f - HitChance;
+
+ // Bonuses from attacker aura and ratings
+ if (attType == RANGED_ATTACK)
+ miss_chance -= m_modRangedHitChance;
+ else
+ miss_chance -= m_modMeleeHitChance;
+
+ // bonus from skills is 0.04%
+ //miss_chance -= skillDiff * 0.04f;
+ int32 diff = -skillDiff;
+ if(pVictim->GetTypeId()==TYPEID_PLAYER)
+ miss_chance += diff > 0 ? diff * 0.04 : diff * 0.02;
+ else
+ miss_chance += diff > 10 ? 2 + (diff - 10) * 0.4 : diff * 0.1;
+
+ // Limit miss chance from 0 to 60%
+ if (miss_chance < 0.0f)
+ return 0.0f;
+ if (miss_chance > 60.0f)
+ return 60.0f;
+ return miss_chance;
+}
+
+void Unit::SetPhaseMask(uint32 newPhaseMask, bool update)
+{
+ WorldObject::SetPhaseMask(newPhaseMask,update);
+
+ if(IsInWorld())
+ if(Pet* pet = GetPet())
+ pet->SetPhaseMask(newPhaseMask,true);
+}
diff --git a/src/game/Unit.h b/src/game/Unit.h
index 7050121c5bb..9ed85ca9cc3 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -45,7 +45,8 @@ enum SpellInterruptFlags
SPELL_INTERRUPT_FLAG_PUSH_BACK = 0x02, // push back
SPELL_INTERRUPT_FLAG_INTERRUPT = 0x04, // interrupt
SPELL_INTERRUPT_FLAG_AUTOATTACK = 0x08, // no
- SPELL_INTERRUPT_FLAG_DAMAGE = 0x10 // _complete_ interrupt on direct damage?
+ SPELL_INTERRUPT_FLAG_ABORT_ON_DMG = 0x10, // _complete_ interrupt on direct damage
+ //SPELL_INTERRUPT_UNK = 0x20 // unk, 564 of 727 spells having this spell start with "Glyph"
};
enum SpellChannelInterruptFlags
@@ -101,7 +102,7 @@ enum SpellModOp
SPELLMOD_CASTING_TIME = 10,
SPELLMOD_COOLDOWN = 11,
SPELLMOD_EFFECT2 = 12,
- // spellmod 13 unused
+ SPELLMOD_IGNORE_ARMOR = 13,
SPELLMOD_COST = 14,
SPELLMOD_CRIT_DAMAGE_BONUS = 15,
SPELLMOD_RESIST_MISS_CHANCE = 16,
@@ -109,13 +110,16 @@ enum SpellModOp
SPELLMOD_CHANCE_OF_SUCCESS = 18,
SPELLMOD_ACTIVATION_TIME = 19,
SPELLMOD_EFFECT_PAST_FIRST = 20,
- SPELLMOD_CASTING_TIME_OLD = 21,
+ SPELLMOD_GLOBAL_COOLDOWN = 21, //TODO: GCD is not checked by server currently
SPELLMOD_DOT = 22,
SPELLMOD_EFFECT3 = 23,
SPELLMOD_SPELL_BONUS_DAMAGE = 24,
- // spellmod 25, 26 unused
+ // spellmod 25
+ SPELLMOD_PROC_CHANCE = 26,
SPELLMOD_MULTIPLE_VALUE = 27,
- SPELLMOD_RESIST_DISPEL_CHANCE = 28
+ SPELLMOD_RESIST_DISPEL_CHANCE = 28,
+ SPELLMOD_CRIT_DAMAGE_BONUS_2 = 29, //one not used spell
+ SPELLMOD_SPELL_COST_REFUND_ON_FAIL = 30
};
#define MAX_SPELLMOD 32
@@ -129,6 +133,35 @@ enum SpellFacingFlags
#define BASE_MAXDAMAGE 2.0f
#define BASE_ATTACK_TIME 2000
+// byte value (UNIT_FIELD_BYTES_1,0)
+enum UnitStandStateType
+{
+ UNIT_STAND_STATE_STAND = 0,
+ UNIT_STAND_STATE_SIT = 1,
+ UNIT_STAND_STATE_SIT_CHAIR = 2,
+ UNIT_STAND_STATE_SLEEP = 3,
+ UNIT_STAND_STATE_SIT_LOW_CHAIR = 4,
+ UNIT_STAND_STATE_SIT_MEDIUM_CHAIR = 5,
+ UNIT_STAND_STATE_SIT_HIGH_CHAIR = 6,
+ UNIT_STAND_STATE_DEAD = 7,
+ UNIT_STAND_STATE_KNEEL = 8
+};
+
+// byte flag value (UNIT_FIELD_BYTES_1,2)
+enum UnitStandFlags
+{
+ UNIT_STAND_FLAGS_CREEP = 0x02,
+ UNIT_STAND_FLAGS_ALL = 0xFF
+};
+
+// byte flags value (UNIT_FIELD_BYTES_1,3)
+enum UnitBytes1_Flags
+{
+ UNIT_BYTE1_FLAG_ALWAYS_STAND = 0x01,
+ UNIT_BYTE1_FLAG_UNTRACKABLE = 0x04,
+ UNIT_BYTE1_FLAG_ALL = 0xFF
+};
+
// high byte (3 from 0..3) of UNIT_FIELD_BYTES_2
enum ShapeshiftForm
{
@@ -149,6 +182,7 @@ enum ShapeshiftForm
FORM_BERSERKERSTANCE = 0x13,
FORM_TEST = 0x14,
FORM_ZOMBIE = 0x15,
+ FORM_METAMORPHOSIS = 0x16,
FORM_FLIGHT_EPIC = 0x1B,
FORM_SHADOW = 0x1C,
FORM_FLIGHT = 0x1D,
@@ -168,14 +202,14 @@ enum SheathState
// byte (1 from 0..3) of UNIT_FIELD_BYTES_2
enum UnitBytes2_Flags
{
- UNIT_BYTE2_FLAG_UNK0 = 0x01,
- UNIT_BYTE2_FLAG_UNK1 = 0x02,
- UNIT_BYTE2_FLAG_UNK2 = 0x04,
+ UNIT_BYTE2_FLAG_PVP = 0x01,
+ UNIT_BYTE2_FLAG_UNK1 = 0x02,
+ UNIT_BYTE2_FLAG_FFA_PVP = 0x04,
UNIT_BYTE2_FLAG_SANCTUARY = 0x08,
- UNIT_BYTE2_FLAG_AURAS = 0x10, // show possitive auras as positive, and allow its dispel
- UNIT_BYTE2_FLAG_UNK5 = 0x20,
- UNIT_BYTE2_FLAG_UNK6 = 0x40,
- UNIT_BYTE2_FLAG_UNK7 = 0x80
+ UNIT_BYTE2_FLAG_UNK4 = 0x10,
+ UNIT_BYTE2_FLAG_UNK5 = 0x20,
+ UNIT_BYTE2_FLAG_UNK6 = 0x40,
+ UNIT_BYTE2_FLAG_UNK7 = 0x80
};
// byte (2 from 0..3) of UNIT_FIELD_BYTES_2
@@ -185,7 +219,7 @@ enum UnitRename
UNIT_RENAME_ALLOWED = 0x03
};
-#define CREATURE_MAX_SPELLS 4
+#define CREATURE_MAX_SPELLS 8
enum Swing
{
@@ -213,16 +247,27 @@ enum HitInfo
HITINFO_UNK1 = 0x00000001, // req correct packet structure
HITINFO_NORMALSWING2 = 0x00000002,
HITINFO_LEFTSWING = 0x00000004,
+ HITINFO_UNK2 = 0x00000008,
HITINFO_MISS = 0x00000010,
- HITINFO_ABSORB = 0x00000020, // plays absorb sound
- HITINFO_RESIST = 0x00000040, // resisted at least some damage
- HITINFO_CRITICALHIT = 0x00000080,
- HITINFO_UNK2 = 0x00000100, // wotlk?
- HITINFO_UNK3 = 0x00002000, // wotlk?
- HITINFO_GLANCING = 0x00004000,
- HITINFO_CRUSHING = 0x00008000,
- HITINFO_NOACTION = 0x00010000,
- HITINFO_SWINGNOHITSOUND = 0x00080000
+ HITINFO_ABSORB = 0x00000020, // absorbed damage
+ HITINFO_ABSORB2 = 0x00000040, // absorbed damage
+ HITINFO_RESIST = 0x00000080, // resisted atleast some damage
+ HITINFO_RESIST2 = 0x00000100, // resisted atleast some damage
+ HITINFO_CRITICALHIT = 0x00000200, // critical hit
+ // 0x00000400
+ // 0x00000800
+ // 0x00001000
+ HITINFO_BLOCK = 0x00002000, // blocked damage
+ // 0x00004000
+ // 0x00008000
+ HITINFO_GLANCING = 0x00010000,
+ HITINFO_CRUSHING = 0x00020000,
+ HITINFO_NOACTION = 0x00040000, // guessed
+ // 0x00080000
+ // 0x00100000
+ HITINFO_SWINGNOHITSOUND = 0x00200000, // guessed
+ // 0x00400000
+ HITINFO_UNK3 = 0x00800000
};
//i would like to remove this: (it is defined in item.h
@@ -294,11 +339,13 @@ enum UnitMods
UNIT_MOD_STAT_INTELLECT,
UNIT_MOD_STAT_SPIRIT,
UNIT_MOD_HEALTH,
- UNIT_MOD_MANA, // UNIT_MOD_MANA..UNIT_MOD_HAPPINESS must be in existed order, it's accessed by index values of Powers enum.
+ UNIT_MOD_MANA, // UNIT_MOD_MANA..UNIT_MOD_RUNIC_POWER must be in existed order, it's accessed by index values of Powers enum.
UNIT_MOD_RAGE,
UNIT_MOD_FOCUS,
UNIT_MOD_ENERGY,
UNIT_MOD_HAPPINESS,
+ UNIT_MOD_RUNE,
+ UNIT_MOD_RUNIC_POWER,
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,
@@ -318,7 +365,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_HAPPINESS + 1
+ UNIT_MOD_POWER_END = UNIT_MOD_RUNIC_POWER + 1
};
enum BaseModGroup
@@ -385,9 +432,10 @@ enum UnitMoveType
MOVE_TURN_RATE = 5,
MOVE_FLIGHT = 6,
MOVE_FLIGHT_BACK = 7,
+ MOVE_PITCH_RATE = 8
};
-#define MAX_MOVE_TYPE 8
+#define MAX_MOVE_TYPE 9
extern float baseMoveSpeed[MAX_MOVE_TYPE];
// assume it is 25 yard per 0.6 second
@@ -397,11 +445,10 @@ enum WeaponAttackType
{
BASE_ATTACK = 0,
OFF_ATTACK = 1,
- RANGED_ATTACK = 2
+ RANGED_ATTACK = 2,
+ MAX_ATTACK
};
-#define MAX_ATTACK 3
-
enum CombatRating
{
CR_WEAPON_SKILL = 0,
@@ -427,10 +474,11 @@ enum CombatRating
CR_WEAPON_SKILL_MAINHAND = 20,
CR_WEAPON_SKILL_OFFHAND = 21,
CR_WEAPON_SKILL_RANGED = 22,
- CR_EXPERTISE = 23
+ CR_EXPERTISE = 23,
+ CR_ARMOR_PENETRATION = 24
};
-#define MAX_COMBAT_RATING 24
+#define MAX_COMBAT_RATING 25
enum DamageEffectType
{
@@ -455,45 +503,50 @@ enum UnitVisibility
// Value masks for UNIT_FIELD_FLAGS
enum UnitFlags
{
- UNIT_FLAG_UNKNOWN7 = 0x00000001,
+ UNIT_FLAG_UNK_0 = 0x00000001,
UNIT_FLAG_NON_ATTACKABLE = 0x00000002, // not attackable
UNIT_FLAG_DISABLE_MOVE = 0x00000004,
UNIT_FLAG_PVP_ATTACKABLE = 0x00000008, // allow apply pvp rules to attackable state in addition to faction dependent state
UNIT_FLAG_RENAME = 0x00000010,
UNIT_FLAG_PREPARATION = 0x00000020, // don't take reagents for spells with SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP
- UNIT_FLAG_UNKNOWN9 = 0x00000040,
+ UNIT_FLAG_UNK_6 = 0x00000040,
UNIT_FLAG_NOT_ATTACKABLE_1 = 0x00000080, // ?? (UNIT_FLAG_PVP_ATTACKABLE | UNIT_FLAG_NOT_ATTACKABLE_1) is NON_PVP_ATTACKABLE
UNIT_FLAG_NOT_ATTACKABLE_2 = 0x00000100, // 2.0.8
- UNIT_FLAG_UNKNOWN11 = 0x00000200,
+ UNIT_FLAG_UNK_9 = 0x00000200, // 3.0.3 - makes you unable to attack everything
UNIT_FLAG_LOOTING = 0x00000400, // loot animation
UNIT_FLAG_PET_IN_COMBAT = 0x00000800, // in combat?, 2.0.8
- UNIT_FLAG_PVP = 0x00001000,
+ UNIT_FLAG_PVP = 0x00001000, // changed in 3.0.3
UNIT_FLAG_SILENCED = 0x00002000, // silenced, 2.1.1
- UNIT_FLAG_UNKNOWN4 = 0x00004000, // 2.0.8
- UNIT_FLAG_UNKNOWN13 = 0x00008000,
- UNIT_FLAG_UNKNOWN14 = 0x00010000,
- UNIT_FLAG_PACIFIED = 0x00020000,
- UNIT_FLAG_DISABLE_ROTATE = 0x00040000, // stunned, 2.1.1
+ UNIT_FLAG_UNK_14 = 0x00004000, // 2.0.8
+ UNIT_FLAG_UNK_15 = 0x00008000,
+ UNIT_FLAG_UNK_16 = 0x00010000,
+ UNIT_FLAG_PACIFIED = 0x00020000, // 3.0.3 ok
+ UNIT_FLAG_STUNNED = 0x00040000, // 3.0.3 ok
UNIT_FLAG_IN_COMBAT = 0x00080000,
UNIT_FLAG_TAXI_FLIGHT = 0x00100000, // disable casting at client side spell not allowed by taxi flight (mounted?), probably used with 0x4 flag
- UNIT_FLAG_DISARMED = 0x00200000, // disable melee spells casting..., "Required melee weapon" added to melee spells tooltip.
+ UNIT_FLAG_DISARMED = 0x00200000, // 3.0.3, disable melee spells casting..., "Required melee weapon" added to melee spells tooltip.
UNIT_FLAG_CONFUSED = 0x00400000,
UNIT_FLAG_FLEEING = 0x00800000,
- UNIT_FLAG_UNKNOWN5 = 0x01000000, // used in spell Eyes of the Beast for pet...
+ UNIT_FLAG_UNK_24 = 0x01000000, // used in spell Eyes of the Beast for pet...
UNIT_FLAG_NOT_SELECTABLE = 0x02000000,
UNIT_FLAG_SKINNABLE = 0x04000000,
UNIT_FLAG_MOUNT = 0x08000000,
- UNIT_FLAG_UNKNOWN17 = 0x10000000,
- UNIT_FLAG_UNKNOWN6 = 0x20000000, // used in Feing Death spell
- UNIT_FLAG_SHEATHE = 0x40000000
+ UNIT_FLAG_UNK_28 = 0x10000000,
+ UNIT_FLAG_UNK_29 = 0x20000000, // used in Feing Death spell
+ UNIT_FLAG_SHEATHE = 0x40000000,
+ UNIT_FLAG_UNK_31 = 0x80000000
};
// Value masks for UNIT_FIELD_FLAGS_2
enum UnitFlags2
{
- UNIT_FLAG2_FEIGN_DEATH = 0x00000001,
- UNIT_FLAG2_COMPREHEND_LANG= 0x00000008,
- UNIT_FLAG2_FORCE_MOVE = 0x00000040
+ UNIT_FLAG2_FEIGN_DEATH = 0x00000001,
+ UNIT_FLAG2_UNK1 = 0x00000002, // Hide unit model (show only player equip)
+ UNIT_FLAG2_COMPREHEND_LANG = 0x00000008,
+ UNIT_FLAG2_FORCE_MOVE = 0x00000040,
+ UNIT_FLAG2_DISARM_OFFHAND = 0x00000080,
+ UNIT_FLAG2_DISARM_RANGED = 0x00000400, //this does not disable ranged weapon display (maybe additional flag needed?)
+ UNIT_FLAG2_REGENERATE_POWER = 0x00000800
};
/// Non Player Character flags
@@ -581,8 +634,9 @@ struct DiminishingReturn
enum MeleeHitOutcome
{
MELEE_HIT_EVADE, MELEE_HIT_MISS, MELEE_HIT_DODGE, MELEE_HIT_BLOCK, MELEE_HIT_PARRY,
- MELEE_HIT_GLANCING, MELEE_HIT_CRIT, MELEE_HIT_CRUSHING, MELEE_HIT_NORMAL, MELEE_HIT_BLOCK_CRIT
+ MELEE_HIT_GLANCING, MELEE_HIT_CRIT, MELEE_HIT_CRUSHING, MELEE_HIT_NORMAL
};
+
struct CleanDamage
{
CleanDamage(uint32 _damage, WeaponAttackType _attackType, MeleeHitOutcome _hitOutCome) :
@@ -639,8 +693,20 @@ uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missC
struct UnitActionBarEntry
{
- uint32 Type;
- uint32 SpellOrAction;
+ UnitActionBarEntry() : Raw(0) {}
+
+ union
+ {
+ struct
+ {
+ uint16 SpellOrAction;
+ uint16 Type;
+ };
+ struct
+ {
+ uint32 Raw;
+ };
+ };
};
#define MAX_DECLINED_NAME_CASES 5
@@ -662,13 +728,12 @@ enum CurrentSpellTypes
enum ActiveStates
{
- ACT_ENABLED = 0xC100,
- ACT_DISABLED = 0x8100,
- ACT_COMMAND = 0x0700,
- ACT_REACTION = 0x0600,
- ACT_CAST = 0x0100,
- ACT_PASSIVE = 0x0000,
- ACT_DECIDE = 0x0001
+ ACT_PASSIVE = 0x0100, // 0x0100 - passive
+ ACT_DISABLED = 0x8100, // 0x8000 - castable
+ ACT_ENABLED = 0xC100, // 0x4000 | 0x8000 - auto cast + castable
+ ACT_COMMAND = 0x0700, // 0x0100 | 0x0200 | 0x0400
+ ACT_REACTION = 0x0600, // 0x0200 | 0x0400
+ ACT_DECIDE = 0x0001 // what is it?
};
enum ReactStates
@@ -733,16 +798,22 @@ struct TRINITY_DLL_SPEC CharmInfo
enum ReactiveType
{
- REACTIVE_DEFENSE = 1,
- REACTIVE_HUNTER_PARRY = 2,
- REACTIVE_CRIT = 3,
- REACTIVE_HUNTER_CRIT = 4,
- REACTIVE_OVERPOWER = 5
+ REACTIVE_DEFENSE = 0,
+ REACTIVE_HUNTER_PARRY = 1,
+ REACTIVE_OVERPOWER = 2
};
-#define MAX_REACTIVE 6
+#define MAX_REACTIVE 3
#define MAX_TOTEM 4
+struct AuraSlotEntry
+{
+ uint8 m_Flags;
+ uint8 m_Level;
+ uint32 m_spellId;
+ Aura * m_slotAuras[3];
+};
+
// delay time next attack to prevent client attack animation problems
#define ATTACK_DISPLAY_DELAY 200
@@ -756,9 +827,10 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
typedef std::multimap< spellEffectPair, Aura*> AuraMap;
typedef std::list<Aura *> AuraList;
typedef std::list<DiminishingReturn> Diminishing;
- typedef std::set<AuraType> AuraTypeSet;
typedef std::set<uint32> ComboPointHolderSet;
+ typedef std::map<uint8, AuraSlotEntry> VisibleAuraMap;
+
virtual ~Unit ( );
void AddToWorld();
@@ -797,9 +869,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
}
void _removeAttacker(Unit *pAttacker) // must be called only from Unit::AttackStop()
{
- AttackerSet::iterator itr = m_attackers.find(pAttacker);
- if(itr != m_attackers.end())
- m_attackers.erase(itr);
+ m_attackers.erase(pAttacker);
}
Unit * getAttackerForHelper() // If someone wants to help, who to give them
{
@@ -821,6 +891,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void CombatStop(bool cast = false);
void CombatStopWithPets(bool cast = false);
Unit* SelectNearbyTarget(float dist = NOMINAL_MELEE_RANGE) const;
+ bool hasNegativeAuraWithInterruptFlag(uint32 flag);
void addUnitState(uint32 f) { m_state |= f; }
bool hasUnitState(const uint32 f) const { return (m_state & f); }
@@ -888,8 +959,14 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
return false;
}
- bool IsPvP() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP); }
- void SetPvP(bool state) { if(state) SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP); else RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP); }
+ bool IsPvP() const { return HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP); }
+ void SetPvP(bool state)
+ {
+ if(state)
+ SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP);
+ else
+ RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP);
+ }
uint32 GetCreatureType() const;
uint32 GetCreatureTypeMask() const
{
@@ -902,6 +979,9 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
bool IsStandState() const;
void SetStandState(uint8 state);
+ void SetStandFlags(uint8 flags) { SetByteFlag(UNIT_FIELD_BYTES_1, 2,flags); }
+ void RemoveStandFlags(uint8 flags) { RemoveByteFlag(UNIT_FIELD_BYTES_1, 2,flags); }
+
bool IsMounted() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT ); }
uint32 GetMountID() const { return GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID); }
void Mount(uint32 mount);
@@ -924,6 +1004,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss);
void CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellEntry const *spellInfo, WeaponAttackType attackType = BASE_ATTACK);
+ int32 GetIgnoredArmorMultiplier(SpellEntry const *spellInfo, WeaponAttackType attackType);
void DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss);
float MeleeSpellMissChance(const Unit *pVictim, WeaponAttackType attType, int32 skillDiff, uint32 spellId) const;
@@ -935,6 +1016,16 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
float GetUnitParryChance() const;
float GetUnitBlockChance() const;
float GetUnitCriticalChance(WeaponAttackType attackType, const Unit *pVictim) const;
+ bool CanUseAttackType( uint8 attacktype ) const
+ {
+ switch(attacktype)
+ {
+ case BASE_ATTACK: return !HasFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISARMED);
+ case OFF_ATTACK: return !HasFlag(UNIT_FIELD_FLAGS_2,UNIT_FLAG2_DISARM_OFFHAND);
+ case RANGED_ATTACK: return !HasFlag(UNIT_FIELD_FLAGS_2,UNIT_FLAG2_DISARM_RANGED);
+ }
+ return true;
+ }
virtual uint32 GetShieldBlockValue() const =0;
uint32 GetUnitMeleeSkill(Unit const* target = NULL) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; }
@@ -944,7 +1035,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
float GetPPMProcChance(uint32 WeaponSpeed, float PPM) const;
MeleeHitOutcome RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType) const;
- MeleeHitOutcome RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType, int32 crit_chance, int32 miss_chance, int32 dodge_chance, int32 parry_chance, int32 block_chance, bool SpellCasted ) const;
+ MeleeHitOutcome RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType, int32 crit_chance, int32 miss_chance, int32 dodge_chance, int32 parry_chance, int32 block_chance) const;
bool isVendor() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_VENDOR ); }
bool isTrainer() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_TRAINER ); }
@@ -984,7 +1075,10 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
bool HasAuraType(AuraType auraType) const;
bool HasAura(uint32 spellId, uint32 effIndex) const
- { return m_Auras.find(spellEffectPair(spellId, effIndex)) != m_Auras.end(); }
+ {
+ return m_Auras.find(spellEffectPair(spellId, effIndex)) != m_Auras.end();
+ }
+ bool HasAura(uint32 spellId) const;
bool virtual HasSpell(uint32 /*spellID*/) const { return false; }
@@ -1104,11 +1198,11 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
void RemoveAura(uint32 spellId, uint32 effindex, Aura* except = NULL);
- void RemoveSingleAuraFromStackByDispel(uint32 spellId);
+ void RemoveSingleSpellAurasFromStack(uint32 spellId);
void RemoveSingleAuraFromStack(uint32 spellId, uint32 effindex);
void RemoveAurasDueToSpell(uint32 spellId, Aura* except = NULL);
void RemoveAurasDueToItemSpell(Item* castItem,uint32 spellId);
- void RemoveAurasDueToCasterSpell(uint32 spellId, uint64 guid);
+ void RemoveAurasByCasterSpell(uint32 spellId, uint64 casterGUID);
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler);
void RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer);
void RemoveAurasDueToSpellByCancel(uint32 spellId);
@@ -1224,13 +1318,13 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
bool isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList = false, bool is3dDistance = true) const;
bool canDetectInvisibilityOf(Unit const* u) const;
bool canDetectStealthOf(Unit const* u, float distance) const;
+ void SetPhaseMask(uint32 newPhaseMask, bool update);// overwrite WorldObject::SetPhaseMask
// virtual functions for all world objects types
bool isVisibleForInState(Player const* u, bool inVisibleList) const;
// function for low level grid visibility checks in player/creature cases
virtual bool IsVisibleInGridForPlayer(Player const* pl) const = 0;
- bool waterbreath;
AuraList & GetSingleCastAuras() { return m_scAuras; }
AuraList const& GetSingleCastAuras() const { return m_scAuras; }
SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY];
@@ -1247,12 +1341,32 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void removeHatedBy(HostilReference* /*pHostilReference*/ ) { /* nothing to do yet */ }
HostilRefManager& getHostilRefManager() { return m_HostilRefManager; }
+ VisibleAuraMap const *GetVisibleAuras() { return &m_visibleAuras; }
+ uint8 GetVisibleAurasCount() { return m_visibleAuras.size(); }
+ AuraSlotEntry * GetVisibleAura(uint8 slot)
+ {
+ VisibleAuraMap::iterator itr = m_visibleAuras.find(slot);
+ if(itr != m_visibleAuras.end())
+ return &itr->second;
+ return 0;
+ }
+ void SetVisibleAura(uint8 slot, AuraSlotEntry entry) { m_visibleAuras[slot] = entry; }
+ void RemoveVisibleAura(uint8 slot) { m_visibleAuras.erase(slot); }
+
+ const uint64& GetAuraUpdateMask() const { return m_auraUpdateMask; }
+ void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); }
+ void ResetAuraUpdateMask() { m_auraUpdateMask = 0; }
+ void SendAuraUpdate(uint8 slot);
+
Aura* GetAura(uint32 spellId, uint32 effindex);
+ Aura* GetAura(AuraType type, uint32 family, uint32 familyFlag1 = 0, uint32 familyFlag2 = 0, uint32 familyFlag3 = 0, uint64 casterGUID = 0);
+
AuraMap & GetAuras() { return m_Auras; }
AuraMap const& GetAuras() const { return m_Auras; }
AuraList const& GetAurasByType(AuraType type) const { return m_modAuras[type]; }
void ApplyAuraProcTriggerDamage(Aura* aura, bool apply);
+ bool HasAuraTypeWithMiscvalue(AuraType auratype, uint32 miscvalue) const;
int32 GetTotalAuraModifier(AuraType auratype) const;
float GetTotalAuraMultiplier(AuraType auratype) const;
int32 GetMaxPositiveAuraModifier(AuraType auratype) const;
@@ -1298,11 +1412,13 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
int32 SpellBaseHealingBonus(SpellSchoolMask schoolMask);
int32 SpellBaseDamageBonusForVictim(SpellSchoolMask schoolMask, Unit *pVictim);
int32 SpellBaseHealingBonusForVictim(SpellSchoolMask schoolMask, Unit *pVictim);
- uint32 SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 damage, DamageEffectType damagetype);
- uint32 SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount, DamageEffectType damagetype, Unit *pVictim);
+ uint32 SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 damage, DamageEffectType damagetype, uint32 stack = 1);
+ uint32 SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack = 1);
bool isSpellBlocked(Unit *pVictim, SpellEntry const *spellProto, WeaponAttackType attackType = BASE_ATTACK);
+ bool isBlockCritical();
bool isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType = BASE_ATTACK);
- uint32 SpellCriticalBonus(SpellEntry const *spellProto, uint32 damage, Unit *pVictim);
+ uint32 SpellCriticalDamageBonus(SpellEntry const *spellProto, uint32 damage, Unit *pVictim);
+ uint32 SpellCriticalHealingBonus(SpellEntry const *spellProto, uint32 damage, Unit *pVictim);
void SetLastManaUse(uint32 spellCastTime) { m_lastManaUse = spellCastTime; }
bool IsUnderLastManaUseEffect() const;
@@ -1314,14 +1430,14 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply);
void ApplySpellDispelImmunity(const SpellEntry * spellProto, DispelType type, bool apply);
- virtual bool IsImmunedToSpell(SpellEntry const* spellInfo, bool useCharges = false);
+ virtual bool IsImmunedToSpell(SpellEntry const* spellInfo);
// redefined in Creature
- bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask, bool useCharges = false);
- virtual bool IsImmunedToSpellEffect(uint32 effect, uint32 mechanic) const;
+ bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask);
+ virtual bool IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const;
// redefined in Creature
- uint32 CalcArmorReducedDamage(Unit* pVictim, const uint32 damage);
- void CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist);
+ uint32 CalcArmorReducedDamage(Unit* pVictim, const uint32 damage, SpellEntry const *spellInfo, WeaponAttackType attackType=MAX_ATTACK);
+ void CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist, SpellEntry const *spellInfo = NULL);
void UpdateSpeed(UnitMoveType mtype, bool forced);
float GetSpeed( UnitMoveType mtype ) const;
@@ -1335,7 +1451,9 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void _ApplyAllAuraMods();
int32 CalculateSpellDamage(SpellEntry const* spellProto, uint8 effect_index, int32 basePoints, Unit const* target);
- int32 CalculateSpellDuration(SpellEntry const* spellProto, uint8 effect_index, Unit const* target);
+ int32 CalcSpellDuration(SpellEntry const* spellProto);
+ int32 ModSpellDuration(SpellEntry const* spellProto, uint8 effect_index, Unit const* target, int32 duration);
+ void ModSpellCastTime(SpellEntry const* spellProto, int32 & castTime);
float CalculateLevelPenalty(SpellEntry const* spellProto) const;
void addFollower(FollowerReference* pRef) { m_FollowingRefManager.insertFirst(pRef); }
@@ -1418,6 +1536,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
DeathState m_deathState;
+ uint64 m_auraUpdateMask;
AuraMap m_Auras;
typedef std::list<uint64> DynObjectGUIDs;
@@ -1438,6 +1557,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
float m_weaponDamage[MAX_ATTACK][2];
bool m_canModifyStats;
//std::list< spellEffectPair > AuraSpells[TOTAL_AURAS]; // TODO: use this if ok for mem
+ VisibleAuraMap m_visibleAuras;
float m_speed_rate[MAX_MOVE_TYPE];
@@ -1450,6 +1570,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
uint32 m_unit_movement_flags;
uint32 m_reactiveTimer[MAX_REACTIVE];
+ uint32 m_regenTimer;
ThreatManager m_ThreatManager;
@@ -1458,11 +1579,11 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void SendAttackStop(Unit* victim); // only from AttackStop(Unit*)
//void SendAttackStart(Unit* pVictim); // only from Unit::AttackStart(Unit*)
- bool IsTriggeredAtSpellProcEvent( Aura* aura, SpellEntry const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent );
+ bool IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura* aura, SpellEntry const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent );
bool HandleDummyAuraProc( Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
bool HandleHasteAuraProc( Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
bool HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
- bool HandleOverrideClassScriptAuraProc(Unit *pVictim, Aura* triggredByAura, SpellEntry const *procSpell, uint32 cooldown);
+ bool HandleOverrideClassScriptAuraProc(Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 cooldown);
bool HandleMeandingAuraProc(Aura* triggeredByAura);
uint32 m_state; // Even derived shouldn't modify
diff --git a/src/game/UnitEvents.h b/src/game/UnitEvents.h
index 35003c3d09e..0bde9ca5ada 100644
--- a/src/game/UnitEvents.h
+++ b/src/game/UnitEvents.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/UpdateData.cpp b/src/game/UpdateData.cpp
index 2b6282997e8..bdd3345751d 100644
--- a/src/game/UpdateData.cpp
+++ b/src/game/UpdateData.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -108,7 +108,7 @@ bool UpdateData::BuildPacket(WorldPacket *packet, bool hasTransport)
ByteBuffer buf(m_data.size() + 10 + m_outOfRangeGUIDs.size()*8);
buf << (uint32) (!m_outOfRangeGUIDs.empty() ? m_blockCount + 1 : m_blockCount);
- buf << (uint8) (hasTransport ? 1 : 0);
+ //buf << (uint8) (hasTransport ? 1 : 0);
if(!m_outOfRangeGUIDs.empty())
{
diff --git a/src/game/UpdateData.h b/src/game/UpdateData.h
index 8fdcac4b400..c33e06589c1 100644
--- a/src/game/UpdateData.h
+++ b/src/game/UpdateData.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -38,11 +38,12 @@ enum OBJECT_UPDATE_FLAGS
UPDATEFLAG_NONE = 0x00,
UPDATEFLAG_SELF = 0x01,
UPDATEFLAG_TRANSPORT = 0x02,
- UPDATEFLAG_FULLGUID = 0x04,
+ UPDATEFLAG_HAS_TARGET = 0x04,
UPDATEFLAG_LOWGUID = 0x08,
UPDATEFLAG_HIGHGUID = 0x10,
UPDATEFLAG_LIVING = 0x20,
- UPDATEFLAG_HASPOSITION = 0x40
+ UPDATEFLAG_HAS_POSITION = 0x40,
+ UPDATEFLAG_VEHICLE = 0x80
};
class UpdateData
diff --git a/src/game/UpdateFields.h b/src/game/UpdateFields.h
index db64e0bc1dd..ca971dac460 100644
--- a/src/game/UpdateFields.h
+++ b/src/game/UpdateFields.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -21,7 +21,7 @@
#ifndef _UPDATEFIELDS_AUTO_H
#define _UPDATEFIELDS_AUTO_H
-// Auto generated for version 2, 4, 3, 8606
+// Auto generated for version 3, 0, 3, 9183
enum EObjectFields
{
@@ -43,13 +43,37 @@ enum EItemFields
ITEM_FIELD_DURATION = OBJECT_END + 0x0009, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2
ITEM_FIELD_SPELL_CHARGES = OBJECT_END + 0x000A, // Size: 5, Type: INT, Flags: OWNER_ONLY, UNK2
ITEM_FIELD_FLAGS = OBJECT_END + 0x000F, // Size: 1, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT = OBJECT_END + 0x0010, // Size: 33, Type: INT, Flags: PUBLIC
- ITEM_FIELD_PROPERTY_SEED = OBJECT_END + 0x0031, // Size: 1, Type: INT, Flags: PUBLIC
- ITEM_FIELD_RANDOM_PROPERTIES_ID = OBJECT_END + 0x0032, // Size: 1, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ITEM_TEXT_ID = OBJECT_END + 0x0033, // Size: 1, Type: INT, Flags: OWNER_ONLY
- ITEM_FIELD_DURABILITY = OBJECT_END + 0x0034, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2
- ITEM_FIELD_MAXDURABILITY = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2
- ITEM_END = OBJECT_END + 0x0036,
+ 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_ITEM_TEXT_ID = OBJECT_END + 0x0036, // Size: 1, Type: INT, Flags: OWNER_ONLY
+ ITEM_FIELD_DURABILITY = OBJECT_END + 0x0037, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2
+ ITEM_FIELD_MAXDURABILITY = OBJECT_END + 0x0038, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2
+ ITEM_FIELD_PAD = OBJECT_END + 0x0039, // Size: 1, Type: INT, Flags: NONE
+ ITEM_END = OBJECT_END + 0x003A,
};
enum EContainerFields
@@ -64,93 +88,94 @@ 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_CHARMEDBY = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PUBLIC
- UNIT_FIELD_SUMMONEDBY = OBJECT_END + 0x0006, // Size: 2, Type: LONG, Flags: PUBLIC
- UNIT_FIELD_CREATEDBY = OBJECT_END + 0x0008, // Size: 2, Type: LONG, Flags: PUBLIC
- UNIT_FIELD_TARGET = OBJECT_END + 0x000A, // Size: 2, Type: LONG, Flags: PUBLIC
- UNIT_FIELD_PERSUADED = OBJECT_END + 0x000C, // 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_FIELD_HEALTH = OBJECT_END + 0x0010, // Size: 1, Type: INT, Flags: DYNAMIC
- UNIT_FIELD_POWER1 = OBJECT_END + 0x0011, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_POWER2 = OBJECT_END + 0x0012, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_POWER3 = OBJECT_END + 0x0013, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_POWER4 = OBJECT_END + 0x0014, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_POWER5 = OBJECT_END + 0x0015, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MAXHEALTH = OBJECT_END + 0x0016, // Size: 1, Type: INT, Flags: DYNAMIC
- UNIT_FIELD_MAXPOWER1 = OBJECT_END + 0x0017, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MAXPOWER2 = OBJECT_END + 0x0018, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MAXPOWER3 = OBJECT_END + 0x0019, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MAXPOWER4 = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MAXPOWER5 = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_LEVEL = OBJECT_END + 0x001C, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_FACTIONTEMPLATE = OBJECT_END + 0x001D, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_BYTES_0 = OBJECT_END + 0x001E, // Size: 1, Type: BYTES, Flags: PUBLIC
- UNIT_VIRTUAL_ITEM_SLOT_DISPLAY = OBJECT_END + 0x001F, // Size: 3, Type: INT, Flags: PUBLIC
- UNIT_VIRTUAL_ITEM_INFO = OBJECT_END + 0x0022, // Size: 6, Type: BYTES, Flags: PUBLIC
- UNIT_FIELD_FLAGS = OBJECT_END + 0x0028, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_FLAGS_2 = OBJECT_END + 0x0029, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_AURA = OBJECT_END + 0x002A, // Size: 56, Type: INT, Flags: PUBLIC
- UNIT_FIELD_AURAFLAGS = OBJECT_END + 0x0062, // Size: 14, Type: BYTES, Flags: PUBLIC
- UNIT_FIELD_AURALEVELS = OBJECT_END + 0x0070, // Size: 14, Type: BYTES, Flags: PUBLIC
- UNIT_FIELD_AURAAPPLICATIONS = OBJECT_END + 0x007E, // Size: 14, Type: BYTES, Flags: PUBLIC
- UNIT_FIELD_AURASTATE = OBJECT_END + 0x008C, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_BASEATTACKTIME = OBJECT_END + 0x008D, // Size: 2, Type: INT, Flags: PUBLIC
- UNIT_FIELD_RANGEDATTACKTIME = OBJECT_END + 0x008F, // Size: 1, Type: INT, Flags: PRIVATE
- UNIT_FIELD_BOUNDINGRADIUS = OBJECT_END + 0x0090, // Size: 1, Type: FLOAT, Flags: PUBLIC
- UNIT_FIELD_COMBATREACH = OBJECT_END + 0x0091, // Size: 1, Type: FLOAT, Flags: PUBLIC
- UNIT_FIELD_DISPLAYID = OBJECT_END + 0x0092, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_NATIVEDISPLAYID = OBJECT_END + 0x0093, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MOUNTDISPLAYID = OBJECT_END + 0x0094, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MINDAMAGE = OBJECT_END + 0x0095, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3
- UNIT_FIELD_MAXDAMAGE = OBJECT_END + 0x0096, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3
- UNIT_FIELD_MINOFFHANDDAMAGE = OBJECT_END + 0x0097, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3
- UNIT_FIELD_MAXOFFHANDDAMAGE = OBJECT_END + 0x0098, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3
- UNIT_FIELD_BYTES_1 = OBJECT_END + 0x0099, // Size: 1, Type: BYTES, Flags: PUBLIC
- UNIT_FIELD_PETNUMBER = OBJECT_END + 0x009A, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_PET_NAME_TIMESTAMP = OBJECT_END + 0x009B, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_PETEXPERIENCE = OBJECT_END + 0x009C, // Size: 1, Type: INT, Flags: OWNER_ONLY
- UNIT_FIELD_PETNEXTLEVELEXP = OBJECT_END + 0x009D, // Size: 1, Type: INT, Flags: OWNER_ONLY
- UNIT_DYNAMIC_FLAGS = OBJECT_END + 0x009E, // Size: 1, Type: INT, Flags: DYNAMIC
- UNIT_CHANNEL_SPELL = OBJECT_END + 0x009F, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_MOD_CAST_SPEED = OBJECT_END + 0x00A0, // Size: 1, Type: FLOAT, Flags: PUBLIC
- UNIT_CREATED_BY_SPELL = OBJECT_END + 0x00A1, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_NPC_FLAGS = OBJECT_END + 0x00A2, // Size: 1, Type: INT, Flags: DYNAMIC
- UNIT_NPC_EMOTESTATE = OBJECT_END + 0x00A3, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_TRAINING_POINTS = OBJECT_END + 0x00A4, // Size: 1, Type: TWO_SHORT, Flags: OWNER_ONLY
- UNIT_FIELD_STAT0 = OBJECT_END + 0x00A5, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_STAT1 = OBJECT_END + 0x00A6, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_STAT2 = OBJECT_END + 0x00A7, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_STAT3 = OBJECT_END + 0x00A8, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_STAT4 = OBJECT_END + 0x00A9, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_POSSTAT0 = OBJECT_END + 0x00AA, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_POSSTAT1 = OBJECT_END + 0x00AB, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_POSSTAT2 = OBJECT_END + 0x00AC, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_POSSTAT3 = OBJECT_END + 0x00AD, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_POSSTAT4 = OBJECT_END + 0x00AE, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_NEGSTAT0 = OBJECT_END + 0x00AF, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_NEGSTAT1 = OBJECT_END + 0x00B0, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_NEGSTAT2 = OBJECT_END + 0x00B1, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_NEGSTAT3 = OBJECT_END + 0x00B2, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_NEGSTAT4 = OBJECT_END + 0x00B3, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_RESISTANCES = OBJECT_END + 0x00B4, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY, UNK3
- UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE = OBJECT_END + 0x00BB, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE = OBJECT_END + 0x00C2, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_BASE_MANA = OBJECT_END + 0x00C9, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_BASE_HEALTH = OBJECT_END + 0x00CA, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_BYTES_2 = OBJECT_END + 0x00CB, // Size: 1, Type: BYTES, Flags: PUBLIC
- UNIT_FIELD_ATTACK_POWER = OBJECT_END + 0x00CC, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_ATTACK_POWER_MODS = OBJECT_END + 0x00CD, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x00CE, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_RANGED_ATTACK_POWER = OBJECT_END + 0x00CF, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_RANGED_ATTACK_POWER_MODS = OBJECT_END + 0x00D0, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x00D1, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_MINRANGEDDAMAGE = OBJECT_END + 0x00D2, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_MAXRANGEDDAMAGE = OBJECT_END + 0x00D3, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_POWER_COST_MODIFIER = OBJECT_END + 0x00D4, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_POWER_COST_MULTIPLIER = OBJECT_END + 0x00DB, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_MAXHEALTHMODIFIER = OBJECT_END + 0x00E2, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
- UNIT_FIELD_PADDING = OBJECT_END + 0x00E3, // Size: 1, Type: INT, Flags: NONE
- UNIT_END = OBJECT_END + 0x00E4,
+ UNIT_FIELD_BYTES_0 = OBJECT_END + 0x0010, // Size: 1, Type: BYTES, Flags: PUBLIC
+ UNIT_FIELD_HEALTH = OBJECT_END + 0x0011, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER1 = OBJECT_END + 0x0012, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER2 = OBJECT_END + 0x0013, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER3 = OBJECT_END + 0x0014, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER4 = OBJECT_END + 0x0015, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER5 = OBJECT_END + 0x0016, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER6 = OBJECT_END + 0x0017, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER7 = OBJECT_END + 0x0018, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXHEALTH = OBJECT_END + 0x0019, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXPOWER1 = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXPOWER2 = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXPOWER3 = OBJECT_END + 0x001C, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXPOWER4 = OBJECT_END + 0x001D, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXPOWER5 = OBJECT_END + 0x001E, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXPOWER6 = OBJECT_END + 0x001F, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXPOWER7 = OBJECT_END + 0x0020, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER = OBJECT_END + 0x0021, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER = OBJECT_END + 0x0028, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_LEVEL = OBJECT_END + 0x002F, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_FACTIONTEMPLATE = OBJECT_END + 0x0030, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_VIRTUAL_ITEM_SLOT_ID = OBJECT_END + 0x0031, // Size: 3, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_FLAGS = OBJECT_END + 0x0034, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_FLAGS_2 = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_AURASTATE = OBJECT_END + 0x0036, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_BASEATTACKTIME = OBJECT_END + 0x0037, // Size: 2, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_RANGEDATTACKTIME = OBJECT_END + 0x0039, // Size: 1, Type: INT, Flags: PRIVATE
+ UNIT_FIELD_BOUNDINGRADIUS = OBJECT_END + 0x003A, // Size: 1, Type: FLOAT, Flags: PUBLIC
+ UNIT_FIELD_COMBATREACH = OBJECT_END + 0x003B, // Size: 1, Type: FLOAT, Flags: PUBLIC
+ UNIT_FIELD_DISPLAYID = OBJECT_END + 0x003C, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_NATIVEDISPLAYID = OBJECT_END + 0x003D, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MOUNTDISPLAYID = OBJECT_END + 0x003E, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MINDAMAGE = OBJECT_END + 0x003F, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3
+ UNIT_FIELD_MAXDAMAGE = OBJECT_END + 0x0040, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3
+ UNIT_FIELD_MINOFFHANDDAMAGE = OBJECT_END + 0x0041, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3
+ UNIT_FIELD_MAXOFFHANDDAMAGE = OBJECT_END + 0x0042, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3
+ UNIT_FIELD_BYTES_1 = OBJECT_END + 0x0043, // Size: 1, Type: BYTES, Flags: PUBLIC
+ UNIT_FIELD_PETNUMBER = OBJECT_END + 0x0044, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_PET_NAME_TIMESTAMP = OBJECT_END + 0x0045, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_PETEXPERIENCE = OBJECT_END + 0x0046, // Size: 1, Type: INT, Flags: OWNER_ONLY
+ UNIT_FIELD_PETNEXTLEVELEXP = OBJECT_END + 0x0047, // Size: 1, Type: INT, Flags: OWNER_ONLY
+ UNIT_DYNAMIC_FLAGS = OBJECT_END + 0x0048, // Size: 1, Type: INT, Flags: DYNAMIC
+ UNIT_CHANNEL_SPELL = OBJECT_END + 0x0049, // Size: 1, Type: INT, Flags: PUBLIC
+ 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_ONLY
+ UNIT_FIELD_STAT1 = OBJECT_END + 0x004F, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_STAT2 = OBJECT_END + 0x0050, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_STAT3 = OBJECT_END + 0x0051, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_STAT4 = OBJECT_END + 0x0052, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_POSSTAT0 = OBJECT_END + 0x0053, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_POSSTAT1 = OBJECT_END + 0x0054, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_POSSTAT2 = OBJECT_END + 0x0055, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_POSSTAT3 = OBJECT_END + 0x0056, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_POSSTAT4 = OBJECT_END + 0x0057, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_NEGSTAT0 = OBJECT_END + 0x0058, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_NEGSTAT1 = OBJECT_END + 0x0059, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_NEGSTAT2 = OBJECT_END + 0x005A, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_NEGSTAT3 = OBJECT_END + 0x005B, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_NEGSTAT4 = OBJECT_END + 0x005C, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_RESISTANCES = OBJECT_END + 0x005D, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY, UNK3
+ UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE = OBJECT_END + 0x0064, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE = OBJECT_END + 0x006B, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ 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_ONLY
+ 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_ONLY
+ UNIT_FIELD_ATTACK_POWER_MODS = OBJECT_END + 0x0076, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x0077, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_RANGED_ATTACK_POWER = OBJECT_END + 0x0078, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_RANGED_ATTACK_POWER_MODS = OBJECT_END + 0x0079, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x007A, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_MINRANGEDDAMAGE = OBJECT_END + 0x007B, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_MAXRANGEDDAMAGE = OBJECT_END + 0x007C, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_POWER_COST_MODIFIER = OBJECT_END + 0x007D, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_POWER_COST_MULTIPLIER = OBJECT_END + 0x0084, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
+ UNIT_FIELD_MAXHEALTHMODIFIER = OBJECT_END + 0x008B, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
+ 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,
PLAYER_DUEL_ARBITER = UNIT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
PLAYER_FLAGS = UNIT_END + 0x0002, // Size: 1, Type: INT, Flags: PUBLIC
@@ -262,160 +287,184 @@ enum EUnitFields
PLAYER_QUEST_LOG_25_3 = UNIT_END + 0x006C, // Size: 1, Type: BYTES, Flags: PRIVATE
PLAYER_QUEST_LOG_25_4 = UNIT_END + 0x006D, // Size: 1, Type: INT, Flags: PRIVATE
PLAYER_VISIBLE_ITEM_1_CREATOR = UNIT_END + 0x006E, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_1_0 = UNIT_END + 0x0070, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_1_PROPERTIES = UNIT_END + 0x007C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_1_PAD = UNIT_END + 0x007D, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_2_CREATOR = UNIT_END + 0x007E, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_2_0 = UNIT_END + 0x0080, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_2_PROPERTIES = UNIT_END + 0x008C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_2_PAD = UNIT_END + 0x008D, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_3_CREATOR = UNIT_END + 0x008E, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_3_0 = UNIT_END + 0x0090, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_3_PROPERTIES = UNIT_END + 0x009C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_3_PAD = UNIT_END + 0x009D, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_4_CREATOR = UNIT_END + 0x009E, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_4_0 = UNIT_END + 0x00A0, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_4_PROPERTIES = UNIT_END + 0x00AC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_4_PAD = UNIT_END + 0x00AD, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_5_CREATOR = UNIT_END + 0x00AE, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_5_0 = UNIT_END + 0x00B0, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_5_PROPERTIES = UNIT_END + 0x00BC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_5_PAD = UNIT_END + 0x00BD, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_6_CREATOR = UNIT_END + 0x00BE, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_6_0 = UNIT_END + 0x00C0, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_6_PROPERTIES = UNIT_END + 0x00CC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_6_PAD = UNIT_END + 0x00CD, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_7_CREATOR = UNIT_END + 0x00CE, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_7_0 = UNIT_END + 0x00D0, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_7_PROPERTIES = UNIT_END + 0x00DC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_7_PAD = UNIT_END + 0x00DD, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_8_CREATOR = UNIT_END + 0x00DE, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_8_0 = UNIT_END + 0x00E0, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_8_PROPERTIES = UNIT_END + 0x00EC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_8_PAD = UNIT_END + 0x00ED, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_9_CREATOR = UNIT_END + 0x00EE, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_9_0 = UNIT_END + 0x00F0, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_9_PROPERTIES = UNIT_END + 0x00FC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_9_PAD = UNIT_END + 0x00FD, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_10_CREATOR = UNIT_END + 0x00FE, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_10_0 = UNIT_END + 0x0100, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_10_PROPERTIES = UNIT_END + 0x010C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_10_PAD = UNIT_END + 0x010D, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_11_CREATOR = UNIT_END + 0x010E, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_11_0 = UNIT_END + 0x0110, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_11_PROPERTIES = UNIT_END + 0x011C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_11_PAD = UNIT_END + 0x011D, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_12_CREATOR = UNIT_END + 0x011E, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_12_0 = UNIT_END + 0x0120, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_12_PROPERTIES = UNIT_END + 0x012C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_12_PAD = UNIT_END + 0x012D, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_13_CREATOR = UNIT_END + 0x012E, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_13_0 = UNIT_END + 0x0130, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_13_PROPERTIES = UNIT_END + 0x013C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_13_PAD = UNIT_END + 0x013D, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_14_CREATOR = UNIT_END + 0x013E, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_14_0 = UNIT_END + 0x0140, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_14_PROPERTIES = UNIT_END + 0x014C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_14_PAD = UNIT_END + 0x014D, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_15_CREATOR = UNIT_END + 0x014E, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_15_0 = UNIT_END + 0x0150, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_15_PROPERTIES = UNIT_END + 0x015C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_15_PAD = UNIT_END + 0x015D, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_16_CREATOR = UNIT_END + 0x015E, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_16_0 = UNIT_END + 0x0160, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_16_PROPERTIES = UNIT_END + 0x016C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_16_PAD = UNIT_END + 0x016D, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_17_CREATOR = UNIT_END + 0x016E, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_17_0 = UNIT_END + 0x0170, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_17_PROPERTIES = UNIT_END + 0x017C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_17_PAD = UNIT_END + 0x017D, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_18_CREATOR = UNIT_END + 0x017E, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_18_0 = UNIT_END + 0x0180, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_18_PROPERTIES = UNIT_END + 0x018C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_18_PAD = UNIT_END + 0x018D, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_19_CREATOR = UNIT_END + 0x018E, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_19_0 = UNIT_END + 0x0190, // Size: 12, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_19_PROPERTIES = UNIT_END + 0x019C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_19_PAD = UNIT_END + 0x019D, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_CHOSEN_TITLE = UNIT_END + 0x019E, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_FIELD_PAD_0 = UNIT_END + 0x019F, // Size: 1, Type: INT, Flags: NONE
- PLAYER_FIELD_INV_SLOT_HEAD = UNIT_END + 0x01A0, // Size: 46, Type: LONG, Flags: PRIVATE
- PLAYER_FIELD_PACK_SLOT_1 = UNIT_END + 0x01CE, // Size: 32, Type: LONG, Flags: PRIVATE
- PLAYER_FIELD_BANK_SLOT_1 = UNIT_END + 0x01EE, // Size: 56, Type: LONG, Flags: PRIVATE
- PLAYER_FIELD_BANKBAG_SLOT_1 = UNIT_END + 0x0226, // Size: 14, Type: LONG, Flags: PRIVATE
- PLAYER_FIELD_VENDORBUYBACK_SLOT_1 = UNIT_END + 0x0234, // Size: 24, Type: LONG, Flags: PRIVATE
- PLAYER_FIELD_KEYRING_SLOT_1 = UNIT_END + 0x024C, // Size: 64, Type: LONG, Flags: PRIVATE
- PLAYER_FIELD_VANITYPET_SLOT_1 = UNIT_END + 0x028C, // Size: 36, Type: LONG, Flags: PRIVATE
- PLAYER_FARSIGHT = UNIT_END + 0x02B0, // Size: 2, Type: LONG, Flags: PRIVATE
- PLAYER__FIELD_KNOWN_TITLES = UNIT_END + 0x02B2, // Size: 2, Type: LONG, Flags: PRIVATE
- PLAYER_XP = UNIT_END + 0x02B4, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_NEXT_LEVEL_XP = UNIT_END + 0x02B5, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_SKILL_INFO_1_1 = UNIT_END + 0x02B6, // Size: 384, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_CHARACTER_POINTS1 = UNIT_END + 0x0436, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_CHARACTER_POINTS2 = UNIT_END + 0x0437, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_TRACK_CREATURES = UNIT_END + 0x0438, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_TRACK_RESOURCES = UNIT_END + 0x0439, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_BLOCK_PERCENTAGE = UNIT_END + 0x043A, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_DODGE_PERCENTAGE = UNIT_END + 0x043B, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_PARRY_PERCENTAGE = UNIT_END + 0x043C, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_EXPERTISE = UNIT_END + 0x043D, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_OFFHAND_EXPERTISE = UNIT_END + 0x043E, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_CRIT_PERCENTAGE = UNIT_END + 0x043F, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_RANGED_CRIT_PERCENTAGE = UNIT_END + 0x0440, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_OFFHAND_CRIT_PERCENTAGE = UNIT_END + 0x0441, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_SPELL_CRIT_PERCENTAGE1 = UNIT_END + 0x0442, // Size: 7, Type: FLOAT, Flags: PRIVATE
- PLAYER_SHIELD_BLOCK = UNIT_END + 0x0449, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_EXPLORED_ZONES_1 = UNIT_END + 0x044A, // Size: 128, Type: BYTES, Flags: PRIVATE
- PLAYER_REST_STATE_EXPERIENCE = UNIT_END + 0x04CA, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_COINAGE = UNIT_END + 0x04CB, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_MOD_DAMAGE_DONE_POS = UNIT_END + 0x04CC, // Size: 7, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_MOD_DAMAGE_DONE_NEG = UNIT_END + 0x04D3, // Size: 7, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_MOD_DAMAGE_DONE_PCT = UNIT_END + 0x04DA, // Size: 7, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_MOD_HEALING_DONE_POS = UNIT_END + 0x04E1, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_MOD_TARGET_RESISTANCE = UNIT_END + 0x04E2, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE = UNIT_END + 0x04E3, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_BYTES = UNIT_END + 0x04E4, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_AMMO_ID = UNIT_END + 0x04E5, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_SELF_RES_SPELL = UNIT_END + 0x04E6, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_PVP_MEDALS = UNIT_END + 0x04E7, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_BUYBACK_PRICE_1 = UNIT_END + 0x04E8, // Size: 12, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_BUYBACK_TIMESTAMP_1 = UNIT_END + 0x04F4, // Size: 12, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_KILLS = UNIT_END + 0x0500, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_FIELD_TODAY_CONTRIBUTION = UNIT_END + 0x0501, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_YESTERDAY_CONTRIBUTION = UNIT_END + 0x0502, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_LIFETIME_HONORBALE_KILLS = UNIT_END + 0x0503, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_BYTES2 = UNIT_END + 0x0504, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_FIELD_WATCHED_FACTION_INDEX = UNIT_END + 0x0505, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_COMBAT_RATING_1 = UNIT_END + 0x0506, // Size: 24, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_ARENA_TEAM_INFO_1_1 = UNIT_END + 0x051E, // Size: 18, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_HONOR_CURRENCY = UNIT_END + 0x0530, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_ARENA_CURRENCY = UNIT_END + 0x0531, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_MOD_MANA_REGEN = UNIT_END + 0x0532, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_FIELD_MOD_MANA_REGEN_INTERRUPT = UNIT_END + 0x0533, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_FIELD_MAX_LEVEL = UNIT_END + 0x0534, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_DAILY_QUESTS_1 = UNIT_END + 0x0535, // Size: 25, Type: INT, Flags: PRIVATE
- PLAYER_END = UNIT_END + 0x054E,
+ PLAYER_VISIBLE_ITEM_1_0 = UNIT_END + 0x0070, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_1_PROPERTIES = UNIT_END + 0x007D, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_1_SEED = UNIT_END + 0x007E, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_1_PAD = UNIT_END + 0x007F, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_2_CREATOR = UNIT_END + 0x0080, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_2_0 = UNIT_END + 0x0082, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_2_PROPERTIES = UNIT_END + 0x008F, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_2_SEED = UNIT_END + 0x0090, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_2_PAD = UNIT_END + 0x0091, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_3_CREATOR = UNIT_END + 0x0092, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_3_0 = UNIT_END + 0x0094, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_3_PROPERTIES = UNIT_END + 0x00A1, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_3_SEED = UNIT_END + 0x00A2, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_3_PAD = UNIT_END + 0x00A3, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_4_CREATOR = UNIT_END + 0x00A4, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_4_0 = UNIT_END + 0x00A6, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_4_PROPERTIES = UNIT_END + 0x00B3, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_4_SEED = UNIT_END + 0x00B4, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_4_PAD = UNIT_END + 0x00B5, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_5_CREATOR = UNIT_END + 0x00B6, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_5_0 = UNIT_END + 0x00B8, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_5_PROPERTIES = UNIT_END + 0x00C5, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_5_SEED = UNIT_END + 0x00C6, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_5_PAD = UNIT_END + 0x00C7, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_6_CREATOR = UNIT_END + 0x00C8, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_6_0 = UNIT_END + 0x00CA, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_6_PROPERTIES = UNIT_END + 0x00D7, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_6_SEED = UNIT_END + 0x00D8, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_6_PAD = UNIT_END + 0x00D9, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_7_CREATOR = UNIT_END + 0x00DA, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_7_0 = UNIT_END + 0x00DC, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_7_PROPERTIES = UNIT_END + 0x00E9, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_7_SEED = UNIT_END + 0x00EA, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_7_PAD = UNIT_END + 0x00EB, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_8_CREATOR = UNIT_END + 0x00EC, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_8_0 = UNIT_END + 0x00EE, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_8_PROPERTIES = UNIT_END + 0x00FB, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_8_SEED = UNIT_END + 0x00FC, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_8_PAD = UNIT_END + 0x00FD, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_9_CREATOR = UNIT_END + 0x00FE, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_9_0 = UNIT_END + 0x0100, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_9_PROPERTIES = UNIT_END + 0x010D, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_9_SEED = UNIT_END + 0x010E, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_9_PAD = UNIT_END + 0x010F, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_10_CREATOR = UNIT_END + 0x0110, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_10_0 = UNIT_END + 0x0112, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_10_PROPERTIES = UNIT_END + 0x011F, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_10_SEED = UNIT_END + 0x0120, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_10_PAD = UNIT_END + 0x0121, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_11_CREATOR = UNIT_END + 0x0122, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_11_0 = UNIT_END + 0x0124, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_11_PROPERTIES = UNIT_END + 0x0131, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_11_SEED = UNIT_END + 0x0132, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_11_PAD = UNIT_END + 0x0133, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_12_CREATOR = UNIT_END + 0x0134, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_12_0 = UNIT_END + 0x0136, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_12_PROPERTIES = UNIT_END + 0x0143, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_12_SEED = UNIT_END + 0x0144, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_12_PAD = UNIT_END + 0x0145, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_13_CREATOR = UNIT_END + 0x0146, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_13_0 = UNIT_END + 0x0148, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_13_PROPERTIES = UNIT_END + 0x0155, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_13_SEED = UNIT_END + 0x0156, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_13_PAD = UNIT_END + 0x0157, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_14_CREATOR = UNIT_END + 0x0158, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_14_0 = UNIT_END + 0x015A, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_14_PROPERTIES = UNIT_END + 0x0167, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_14_SEED = UNIT_END + 0x0168, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_14_PAD = UNIT_END + 0x0169, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_15_CREATOR = UNIT_END + 0x016A, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_15_0 = UNIT_END + 0x016C, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_15_PROPERTIES = UNIT_END + 0x0179, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_15_SEED = UNIT_END + 0x017A, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_15_PAD = UNIT_END + 0x017B, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_16_CREATOR = UNIT_END + 0x017C, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_16_0 = UNIT_END + 0x017E, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_16_PROPERTIES = UNIT_END + 0x018B, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_16_SEED = UNIT_END + 0x018C, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_16_PAD = UNIT_END + 0x018D, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_17_CREATOR = UNIT_END + 0x018E, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_17_0 = UNIT_END + 0x0190, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_17_PROPERTIES = UNIT_END + 0x019D, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_17_SEED = UNIT_END + 0x019E, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_17_PAD = UNIT_END + 0x019F, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_18_CREATOR = UNIT_END + 0x01A0, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_18_0 = UNIT_END + 0x01A2, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_18_PROPERTIES = UNIT_END + 0x01AF, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_18_SEED = UNIT_END + 0x01B0, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_18_PAD = UNIT_END + 0x01B1, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_19_CREATOR = UNIT_END + 0x01B2, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_19_0 = UNIT_END + 0x01B4, // Size: 13, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_19_PROPERTIES = UNIT_END + 0x01C1, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_19_SEED = UNIT_END + 0x01C2, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_19_PAD = UNIT_END + 0x01C3, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_CHOSEN_TITLE = UNIT_END + 0x01C4, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_FIELD_PAD_0 = UNIT_END + 0x01C5, // Size: 1, Type: INT, Flags: NONE
+ PLAYER_FIELD_INV_SLOT_HEAD = UNIT_END + 0x01C6, // Size: 46, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_PACK_SLOT_1 = UNIT_END + 0x01F4, // Size: 32, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_BANK_SLOT_1 = UNIT_END + 0x0214, // Size: 56, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_BANKBAG_SLOT_1 = UNIT_END + 0x024C, // Size: 14, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_VENDORBUYBACK_SLOT_1 = UNIT_END + 0x025A, // Size: 24, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_KEYRING_SLOT_1 = UNIT_END + 0x0272, // Size: 64, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_VANITYPET_SLOT_1 = UNIT_END + 0x02B2, // Size: 36, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_CURRENCYTOKEN_SLOT_1 = UNIT_END + 0x02D6, // Size: 64, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_QUESTBAG_SLOT_1 = UNIT_END + 0x0316, // Size: 64, Type: LONG, Flags: PRIVATE
+ PLAYER_FARSIGHT = UNIT_END + 0x0356, // Size: 2, Type: LONG, Flags: PRIVATE
+ PLAYER__FIELD_KNOWN_TITLES = UNIT_END + 0x0358, // Size: 2, Type: LONG, Flags: PRIVATE
+ PLAYER__FIELD_KNOWN_TITLES1 = UNIT_END + 0x035A, // Size: 2, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_KNOWN_CURRENCIES = UNIT_END + 0x035C, // Size: 2, Type: LONG, Flags: PRIVATE
+ PLAYER_XP = UNIT_END + 0x035E, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_NEXT_LEVEL_XP = UNIT_END + 0x035F, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_SKILL_INFO_1_1 = UNIT_END + 0x0360, // Size: 384, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_CHARACTER_POINTS1 = UNIT_END + 0x04E0, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_CHARACTER_POINTS2 = UNIT_END + 0x04E1, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_TRACK_CREATURES = UNIT_END + 0x04E2, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_TRACK_RESOURCES = UNIT_END + 0x04E3, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_BLOCK_PERCENTAGE = UNIT_END + 0x04E4, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_DODGE_PERCENTAGE = UNIT_END + 0x04E5, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_PARRY_PERCENTAGE = UNIT_END + 0x04E6, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_EXPERTISE = UNIT_END + 0x04E7, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_OFFHAND_EXPERTISE = UNIT_END + 0x04E8, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_CRIT_PERCENTAGE = UNIT_END + 0x04E9, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_RANGED_CRIT_PERCENTAGE = UNIT_END + 0x04EA, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_OFFHAND_CRIT_PERCENTAGE = UNIT_END + 0x04EB, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_SPELL_CRIT_PERCENTAGE1 = UNIT_END + 0x04EC, // Size: 7, Type: FLOAT, Flags: PRIVATE
+ PLAYER_SHIELD_BLOCK = UNIT_END + 0x04F3, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_SHIELD_BLOCK_CRIT_PERCENTAGE = UNIT_END + 0x04F4, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_EXPLORED_ZONES_1 = UNIT_END + 0x04F5, // Size: 128, Type: BYTES, Flags: PRIVATE
+ PLAYER_REST_STATE_EXPERIENCE = UNIT_END + 0x0575, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_COINAGE = UNIT_END + 0x0576, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_DAMAGE_DONE_POS = UNIT_END + 0x0577, // Size: 7, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_DAMAGE_DONE_NEG = UNIT_END + 0x057E, // Size: 7, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_DAMAGE_DONE_PCT = UNIT_END + 0x0585, // Size: 7, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_HEALING_DONE_POS = UNIT_END + 0x058C, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_TARGET_RESISTANCE = UNIT_END + 0x058D, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE = UNIT_END + 0x058E, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_BYTES = UNIT_END + 0x058F, // Size: 1, Type: BYTES, Flags: PRIVATE
+ PLAYER_AMMO_ID = UNIT_END + 0x0590, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_SELF_RES_SPELL = UNIT_END + 0x0591, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_PVP_MEDALS = UNIT_END + 0x0592, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_BUYBACK_PRICE_1 = UNIT_END + 0x0593, // Size: 12, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_BUYBACK_TIMESTAMP_1 = UNIT_END + 0x059F, // Size: 12, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_KILLS = UNIT_END + 0x05AB, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_FIELD_TODAY_CONTRIBUTION = UNIT_END + 0x05AC, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_YESTERDAY_CONTRIBUTION = UNIT_END + 0x05AD, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_LIFETIME_HONORBALE_KILLS = UNIT_END + 0x05AE, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_BYTES2 = UNIT_END + 0x05AF, // Size: 1, Type: BYTES, Flags: PRIVATE
+ PLAYER_FIELD_WATCHED_FACTION_INDEX = UNIT_END + 0x05B0, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_COMBAT_RATING_1 = UNIT_END + 0x05B1, // Size: 25, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_ARENA_TEAM_INFO_1_1 = UNIT_END + 0x05CA, // Size: 18, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_HONOR_CURRENCY = UNIT_END + 0x05DC, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_ARENA_CURRENCY = UNIT_END + 0x05DD, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_MAX_LEVEL = UNIT_END + 0x05DE, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_DAILY_QUESTS_1 = UNIT_END + 0x05DF, // Size: 25, Type: INT, Flags: PRIVATE
+ PLAYER_RUNE_REGEN_1 = UNIT_END + 0x05F8, // Size: 4, Type: FLOAT, Flags: PRIVATE
+ PLAYER_NO_REAGENT_COST_1 = UNIT_END + 0x05FC, // Size: 3, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_GLYPH_SLOTS_1 = UNIT_END + 0x05FF, // Size: 8, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_GLYPHS_1 = UNIT_END + 0x0607, // Size: 8, Type: INT, Flags: PRIVATE
+ PLAYER_GLYPHS_ENABLED = UNIT_END + 0x060F, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_END = UNIT_END + 0x0610,
};
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_ROTATION = OBJECT_END + 0x0004, // Size: 4, Type: FLOAT, Flags: PUBLIC
- GAMEOBJECT_STATE = OBJECT_END + 0x0008, // Size: 1, Type: INT, Flags: PUBLIC
- GAMEOBJECT_POS_X = OBJECT_END + 0x0009, // Size: 1, Type: FLOAT, Flags: PUBLIC
- GAMEOBJECT_POS_Y = OBJECT_END + 0x000A, // Size: 1, Type: FLOAT, Flags: PUBLIC
- GAMEOBJECT_POS_Z = OBJECT_END + 0x000B, // Size: 1, Type: FLOAT, Flags: PUBLIC
- GAMEOBJECT_FACING = OBJECT_END + 0x000C, // Size: 1, Type: FLOAT, Flags: PUBLIC
- GAMEOBJECT_DYN_FLAGS = OBJECT_END + 0x000D, // Size: 1, Type: INT, Flags: DYNAMIC
- GAMEOBJECT_FACTION = OBJECT_END + 0x000E, // Size: 1, Type: INT, Flags: PUBLIC
- GAMEOBJECT_TYPE_ID = OBJECT_END + 0x000F, // Size: 1, Type: INT, Flags: PUBLIC
+ GAMEOBJECT_FLAGS = OBJECT_END + 0x0003, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ GAMEOBJECT_ROTATION = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PUBLIC
+ GAMEOBJECT_PARENTROTATION = OBJECT_END + 0x0006, // Size: 4, Type: FLOAT, Flags: PUBLIC
+ GAMEOBJECT_POS_X = OBJECT_END + 0x000A, // Size: 1, Type: FLOAT, Flags: PUBLIC
+ GAMEOBJECT_POS_Y = OBJECT_END + 0x000B, // Size: 1, Type: FLOAT, Flags: PUBLIC
+ GAMEOBJECT_POS_Z = OBJECT_END + 0x000C, // Size: 1, Type: FLOAT, Flags: PUBLIC
+ GAMEOBJECT_FACING = OBJECT_END + 0x000D, // Size: 1, Type: FLOAT, Flags: PUBLIC
+ GAMEOBJECT_DYNAMIC = OBJECT_END + 0x000E, // Size: 1, Type: TWO_SHORT, Flags: DYNAMIC
+ GAMEOBJECT_FACTION = OBJECT_END + 0x000F, // Size: 1, Type: INT, Flags: PUBLIC
GAMEOBJECT_LEVEL = OBJECT_END + 0x0010, // Size: 1, Type: INT, Flags: PUBLIC
- GAMEOBJECT_ARTKIT = OBJECT_END + 0x0011, // Size: 1, Type: INT, Flags: PUBLIC
- GAMEOBJECT_ANIMPROGRESS = OBJECT_END + 0x0012, // Size: 1, Type: INT, Flags: DYNAMIC
- GAMEOBJECT_PADDING = OBJECT_END + 0x0013, // Size: 1, Type: INT, Flags: NONE
- GAMEOBJECT_END = OBJECT_END + 0x0014,
+ GAMEOBJECT_BYTES_1 = OBJECT_END + 0x0011, // Size: 1, Type: BYTES, Flags: PUBLIC
+ GAMEOBJECT_END = OBJECT_END + 0x0012,
};
enum EDynamicObjectFields
diff --git a/src/game/UpdateMask.h b/src/game/UpdateMask.h
index 9949dd6aa5b..8909b23ed51 100644
--- a/src/game/UpdateMask.h
+++ b/src/game/UpdateMask.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -36,27 +36,27 @@ class UpdateMask
delete [] mUpdateMask;
}
- inline void SetBit (uint32 index)
+ void SetBit (uint32 index)
{
( (uint8 *)mUpdateMask )[ index >> 3 ] |= 1 << ( index & 0x7 );
}
- inline void UnsetBit (uint32 index)
+ void UnsetBit (uint32 index)
{
( (uint8 *)mUpdateMask )[ index >> 3 ] &= (0xff ^ (1 << ( index & 0x7 ) ) );
}
- inline bool GetBit (uint32 index)
+ bool GetBit (uint32 index) const
{
return ( ( (uint8 *)mUpdateMask)[ index >> 3 ] & ( 1 << ( index & 0x7 ) )) != 0;
}
- inline uint32 GetBlockCount() { return mBlocks; }
- inline uint32 GetLength() { return mBlocks << 2; }
- inline uint32 GetCount() { return mCount; }
- inline uint8* GetMask() { return (uint8*)mUpdateMask; }
+ uint32 GetBlockCount() const { return mBlocks; }
+ uint32 GetLength() const { return mBlocks << 2; }
+ uint32 GetCount() const { return mCount; }
+ uint8* GetMask() { return (uint8*)mUpdateMask; }
- inline void SetCount (uint32 valuesCount)
+ void SetCount (uint32 valuesCount)
{
if(mUpdateMask)
delete [] mUpdateMask;
@@ -68,13 +68,13 @@ class UpdateMask
memset(mUpdateMask, 0, mBlocks << 2);
}
- inline void Clear()
+ void Clear()
{
if (mUpdateMask)
memset(mUpdateMask, 0, mBlocks << 2);
}
- inline UpdateMask& operator = ( const UpdateMask& mask )
+ UpdateMask& operator = ( const UpdateMask& mask )
{
SetCount(mask.mCount);
memcpy(mUpdateMask, mask.mUpdateMask, mBlocks << 2);
@@ -82,21 +82,21 @@ class UpdateMask
return *this;
}
- inline void operator &= ( const UpdateMask& mask )
+ void operator &= ( const UpdateMask& mask )
{
ASSERT(mask.mCount <= mCount);
for (uint32 i = 0; i < mBlocks; i++)
mUpdateMask[i] &= mask.mUpdateMask[i];
}
- inline void operator |= ( const UpdateMask& mask )
+ void operator |= ( const UpdateMask& mask )
{
ASSERT(mask.mCount <= mCount);
for (uint32 i = 0; i < mBlocks; i++)
mUpdateMask[i] |= mask.mUpdateMask[i];
}
- inline UpdateMask operator & ( const UpdateMask& mask ) const
+ UpdateMask operator & ( const UpdateMask& mask ) const
{
ASSERT(mask.mCount <= mCount);
@@ -107,7 +107,7 @@ class UpdateMask
return newmask;
}
- inline UpdateMask operator | ( const UpdateMask& mask ) const
+ UpdateMask operator | ( const UpdateMask& mask ) const
{
ASSERT(mask.mCount <= mCount);
diff --git a/src/game/Vehicle.cpp b/src/game/Vehicle.cpp
new file mode 100644
index 00000000000..b533609d763
--- /dev/null
+++ b/src/game/Vehicle.cpp
@@ -0,0 +1,102 @@
+/*
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "Common.h"
+#include "Log.h"
+#include "WorldSession.h"
+#include "WorldPacket.h"
+#include "ObjectMgr.h"
+#include "SpellMgr.h"
+#include "Vehicle.h"
+#include "MapManager.h"
+#include "SpellAuras.h"
+#include "Unit.h"
+#include "Util.h"
+
+Vehicle::Vehicle() : Creature(), m_vehicleId(0)
+{
+ m_isVehicle = true;
+ m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_LIVING | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_VEHICLE);
+}
+
+Vehicle::~Vehicle()
+{
+ if(m_uint32Values) // only for fully created Object
+ ObjectAccessor::Instance().RemoveObject(this);
+}
+
+void Vehicle::AddToWorld()
+{
+ ///- Register the vehicle for guid lookup
+ if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this);
+ Unit::AddToWorld();
+}
+
+void Vehicle::RemoveFromWorld()
+{
+ ///- Remove the vehicle from the accessor
+ if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this);
+ ///- Don't call the function for Creature, normal mobs + totems go in a different storage
+ Unit::RemoveFromWorld();
+}
+
+void Vehicle::setDeathState(DeathState s) // overwrite virtual Creature::setDeathState and Unit::setDeathState
+{
+ Creature::setDeathState(s);
+}
+
+void Vehicle::Update(uint32 diff)
+{
+ Creature::Update(diff);
+}
+
+bool Vehicle::Create(uint32 guidlow, Map *map, uint32 Entry, uint32 vehicleId, uint32 team)
+{
+ SetMapId(map->GetId());
+ SetInstanceId(map->GetInstanceId());
+
+ Object::_Create(guidlow, Entry, HIGHGUID_VEHICLE);
+
+ if(!InitEntry(Entry, team))
+ return false;
+
+ m_defaultMovementType = IDLE_MOTION_TYPE;
+
+ AIM_Initialize();
+
+ SetVehicleId(vehicleId);
+
+ SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+ SetFloatValue(UNIT_FIELD_HOVERHEIGHT, 1.0f);
+
+ CreatureInfo const *ci = GetCreatureInfo();
+ setFaction(team == ALLIANCE ? ci->faction_A : ci->faction_H);
+ SetMaxHealth(ci->maxhealth);
+ SelectLevel(ci);
+ SetHealth(GetMaxHealth());
+
+ return true;
+}
+
+void Vehicle::Dismiss()
+{
+ SendObjectDeSpawnAnim(GetGUID());
+ CombatStop();
+ CleanupsBeforeDelete();
+ AddObjectToRemoveList();
+}
diff --git a/src/game/Vehicle.h b/src/game/Vehicle.h
new file mode 100644
index 00000000000..6d9c7cd7943
--- /dev/null
+++ b/src/game/Vehicle.h
@@ -0,0 +1,58 @@
+/*
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef MANGOSSERVER_VEHICLE_H
+#define MANGOSSERVER_VEHICLE_H
+
+#include "ObjectDefines.h"
+#include "Creature.h"
+#include "Unit.h"
+
+class Vehicle : public Creature
+{
+ public:
+ explicit Vehicle();
+ virtual ~Vehicle();
+
+ void AddToWorld();
+ void RemoveFromWorld();
+
+ bool Create (uint32 guidlow, Map *map, uint32 Entry, uint32 vehicleId, uint32 team);
+
+ void setDeathState(DeathState s); // overwrite virtual Creature::setDeathState and Unit::setDeathState
+ void Update(uint32 diff); // overwrite virtual Creature::Update and Unit::Update
+
+ uint32 GetVehicleId() { return m_vehicleId; }
+ void SetVehicleId(uint32 vehicleid) { m_vehicleId = vehicleid; }
+
+ void Dismiss();
+
+ protected:
+ uint32 m_vehicleId;
+
+ private:
+ void SaveToDB(uint32, uint8) // overwrited of Creature::SaveToDB - don't must be called
+ {
+ assert(false);
+ }
+ void DeleteFromDB() // overwrited of Creature::DeleteFromDB - don't must be called
+ {
+ assert(false);
+ }
+};
+#endif
diff --git a/src/game/VoiceChatHandler.cpp b/src/game/VoiceChatHandler.cpp
index f75678f305f..ddc178a8694 100644
--- a/src/game/VoiceChatHandler.cpp
+++ b/src/game/VoiceChatHandler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/WaypointManager.cpp b/src/game/WaypointManager.cpp
index 8a9de3849c4..6e303ca3053 100644
--- a/src/game/WaypointManager.cpp
+++ b/src/game/WaypointManager.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/WaypointManager.h b/src/game/WaypointManager.h
index 2e1ac25c369..e9787090ede 100644
--- a/src/game/WaypointManager.h
+++ b/src/game/WaypointManager.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/WaypointMovementGenerator.cpp b/src/game/WaypointMovementGenerator.cpp
index 5a3b1eee8e2..e5b625fb6e5 100644
--- a/src/game/WaypointMovementGenerator.cpp
+++ b/src/game/WaypointMovementGenerator.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.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
diff --git a/src/game/WaypointMovementGenerator.h b/src/game/WaypointMovementGenerator.h
index b8f72bb5dbf..5b5df75d31e 100644
--- a/src/game/WaypointMovementGenerator.h
+++ b/src/game/WaypointMovementGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -48,7 +48,7 @@ class TRINITY_DLL_SPEC PathMovementBase
PathMovementBase() : i_currentNode(0) {}
virtual ~PathMovementBase() {};
- inline bool MovementInProgress(void) const { return i_currentNode < i_path.Size(); }
+ bool MovementInProgress(void) const { return i_currentNode < i_path.Size(); }
void LoadPath(T &);
void ReloadPath(T &);
@@ -109,7 +109,7 @@ public PathMovementBase<Player>
Path& GetPath() { return i_path; }
uint32 GetPathAtMapEnd() const;
- inline bool HasArrived() const { return (i_currentNode >= i_path.Size()); }
+ bool HasArrived() const { return (i_currentNode >= i_path.Size()); }
void SetCurrentNodeAfterTeleport();
void SkipCurrentNode() { ++i_currentNode; }
bool GetDestination(float& x, float& y, float& z) const { i_destinationHolder.GetDestination(x,y,z); return true; }
diff --git a/src/game/Weather.cpp b/src/game/Weather.cpp
index d825b2f4064..9fd91764ca3 100644
--- a/src/game/Weather.cpp
+++ b/src/game/Weather.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -42,7 +42,7 @@ Weather::Weather(uint32 zone, WeatherZoneChances const* weatherChances) : m_zone
}
/// Launch a weather update
-bool Weather::Update(time_t diff)
+bool Weather::Update(uint32 diff)
{
if (m_timer.GetCurrent()>=0)
m_timer.Update(diff);
diff --git a/src/game/Weather.h b/src/game/Weather.h
index 7fc3068ffe7..fd04d6b6abd 100644
--- a/src/game/Weather.h
+++ b/src/game/Weather.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -62,7 +62,7 @@ class Weather
void SetWeather(WeatherType type, float grade);
/// For which zone is this weather?
uint32 GetZone() { return m_zone; };
- bool Update(time_t diff);
+ bool Update(uint32 diff);
private:
WeatherState GetWeatherState() const;
uint32 m_zone;
diff --git a/src/game/World.cpp b/src/game/World.cpp
index e494d041b5f..97938058d27 100644
--- a/src/game/World.cpp
+++ b/src/game/World.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -37,6 +37,7 @@
#include "SkillDiscovery.h"
#include "World.h"
#include "AccountMgr.h"
+#include "AchievementMgr.h"
#include "ObjectMgr.h"
#include "SpellMgr.h"
#include "Chat.h"
@@ -237,7 +238,7 @@ World::AddSession_ (WorldSession* s)
uint32 Sessions = GetActiveAndQueuedSessionCount ();
uint32 pLimit = GetPlayerAmountLimit ();
- uint32 QueueSize = GetQueueSize (); //number of players in the queue
+ uint32 QueueSize = GetQueueSize (); //number of players in the queue
//so we don't count the user trying to
//login as a session and queue the socket that we are using
@@ -254,10 +255,10 @@ World::AddSession_ (WorldSession* s)
WorldPacket packet(SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4 + 1);
packet << uint8 (AUTH_OK);
- packet << uint32 (0); // unknown random value...
- packet << uint8 (0);
- packet << uint32 (0);
- packet << uint8 (s->Expansion()); // 0 - normal, 1 - TBC, must be set in database manually for each account
+ packet << uint32 (0); // BillingTimeRemaining
+ packet << uint8 (0); // BillingPlanFlags
+ packet << uint32 (0); // BillingTimeRested
+ packet << uint8 (s->Expansion()); // 0 - normal, 1 - TBC, must be set in database manually for each account
s->SendPacket (&packet);
UpdateMaxSessionCounters ();
@@ -265,7 +266,7 @@ World::AddSession_ (WorldSession* s)
// Updates the population
if (pLimit > 0)
{
- float popu = GetActiveSessionCount (); //updated number of users on the server
+ float popu = GetActiveSessionCount (); //updated number of users on the server
popu /= pLimit;
popu *= 2;
LoginDatabase.PExecute ("UPDATE realmlist SET population = '%f' WHERE id = '%d'", popu, realmID);
@@ -292,10 +293,10 @@ void World::AddQueuedPlayer(WorldSession* sess)
// The 1st SMSG_AUTH_RESPONSE needs to contain other info too.
WorldPacket packet (SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4 + 1);
packet << uint8 (AUTH_WAIT_QUEUE);
- packet << uint32 (0); // unknown random value...
- packet << uint8 (0);
- packet << uint32 (0);
- packet << uint8 (sess->Expansion () ? 1 : 0); // 0 - normal, 1 - TBC, must be set in database manually for each account
+ packet << uint32 (0); // BillingTimeRemaining
+ packet << uint8 (0); // BillingPlanFlags
+ packet << uint32 (0); // BillingTimeRested
+ packet << uint8 (sess->Expansion () ? 1 : 0); // 0 - normal, 1 - TBC, must be set in database manually for each account
packet << uint32(GetQueuePos (sess));
sess->SendPacket (&packet);
@@ -419,24 +420,30 @@ void World::LoadConfigSettings(bool reload)
rate_values[RATE_HEALTH] = sConfig.GetFloatDefault("Rate.Health", 1);
if(rate_values[RATE_HEALTH] < 0)
{
- sLog.outError("Rate.Health (%f) mustbe > 0. Using 1 instead.",rate_values[RATE_HEALTH]);
+ sLog.outError("Rate.Health (%f) must be > 0. Using 1 instead.",rate_values[RATE_HEALTH]);
rate_values[RATE_HEALTH] = 1;
}
rate_values[RATE_POWER_MANA] = sConfig.GetFloatDefault("Rate.Mana", 1);
if(rate_values[RATE_POWER_MANA] < 0)
{
- sLog.outError("Rate.Mana (%f) mustbe > 0. Using 1 instead.",rate_values[RATE_POWER_MANA]);
+ sLog.outError("Rate.Mana (%f) must be > 0. Using 1 instead.",rate_values[RATE_POWER_MANA]);
rate_values[RATE_POWER_MANA] = 1;
}
rate_values[RATE_POWER_RAGE_INCOME] = sConfig.GetFloatDefault("Rate.Rage.Income", 1);
rate_values[RATE_POWER_RAGE_LOSS] = sConfig.GetFloatDefault("Rate.Rage.Loss", 1);
if(rate_values[RATE_POWER_RAGE_LOSS] < 0)
{
- sLog.outError("Rate.Rage.Loss (%f) mustbe > 0. Using 1 instead.",rate_values[RATE_POWER_RAGE_LOSS]);
+ sLog.outError("Rate.Rage.Loss (%f) must be > 0. Using 1 instead.",rate_values[RATE_POWER_RAGE_LOSS]);
rate_values[RATE_POWER_RAGE_LOSS] = 1;
}
+ rate_values[RATE_POWER_RUNICPOWER_INCOME] = sConfig.GetFloatDefault("Rate.RunicPower.Income", 1);
+ rate_values[RATE_POWER_RUNICPOWER_LOSS] = sConfig.GetFloatDefault("Rate.RunicPower.Loss", 1);
+ if(rate_values[RATE_POWER_RUNICPOWER_LOSS] < 0)
+ {
+ sLog.outError("Rate.RunicPower.Loss (%f) must be > 0. Using 1 instead.",rate_values[RATE_POWER_RUNICPOWER_LOSS]);
+ rate_values[RATE_POWER_RUNICPOWER_LOSS] = 1;
+ }
rate_values[RATE_POWER_FOCUS] = sConfig.GetFloatDefault("Rate.Focus", 1.0f);
- rate_values[RATE_LOYALTY] = sConfig.GetFloatDefault("Rate.Loyalty", 1.0f);
rate_values[RATE_SKILL_DISCOVERY] = sConfig.GetFloatDefault("Rate.Skill.Discovery", 1.0f);
rate_values[RATE_DROP_ITEM_POOR] = sConfig.GetFloatDefault("Rate.Drop.Item.Poor", 1.0f);
rate_values[RATE_DROP_ITEM_NORMAL] = sConfig.GetFloatDefault("Rate.Drop.Item.Normal", 1.0f);
@@ -450,7 +457,6 @@ void World::LoadConfigSettings(bool reload)
rate_values[RATE_XP_KILL] = sConfig.GetFloatDefault("Rate.XP.Kill", 1.0f);
rate_values[RATE_XP_QUEST] = sConfig.GetFloatDefault("Rate.XP.Quest", 1.0f);
rate_values[RATE_XP_EXPLORE] = sConfig.GetFloatDefault("Rate.XP.Explore", 1.0f);
- rate_values[RATE_XP_PAST_70] = sConfig.GetFloatDefault("Rate.XP.PastLevel70", 1.0f);
rate_values[RATE_REPUTATION_GAIN] = sConfig.GetFloatDefault("Rate.Reputation.Gain", 1.0f);
rate_values[RATE_CREATURE_NORMAL_DAMAGE] = sConfig.GetFloatDefault("Rate.Creature.Normal.Damage", 1.0f);
rate_values[RATE_CREATURE_ELITE_ELITE_DAMAGE] = sConfig.GetFloatDefault("Rate.Creature.Elite.Elite.Damage", 1.0f);
@@ -629,6 +635,15 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_CHARACTERS_PER_ACCOUNT] = m_configs[CONFIG_CHARACTERS_PER_REALM];
}
+ m_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM] = sConfig.GetIntDefault("HeroicCharactersPerRealm", 1);
+ if(m_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM] < 0 || m_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM] > 10)
+ {
+ sLog.outError("HeroicCharactersPerRealm (%i) must be in range 0..10. Set to 1.",m_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM]);
+ m_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM] = 1;
+ }
+
+ m_configs[CONFIG_MIN_LEVEL_FOR_HEROIC_CHARACTER_CREATING] = sConfig.GetIntDefault("MinLevelForHeroicCharacterCreating", 55);
+
m_configs[CONFIG_SKIP_CINEMATICS] = sConfig.GetIntDefault("SkipCinematics", 0);
if(m_configs[CONFIG_SKIP_CINEMATICS] < 0 || m_configs[CONFIG_SKIP_CINEMATICS] > 2)
{
@@ -663,6 +678,20 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_START_PLAYER_LEVEL] = m_configs[CONFIG_MAX_PLAYER_LEVEL];
}
+ m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] = sConfig.GetIntDefault("StartHeroicPlayerLevel", 55);
+ if(m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] < 1)
+ {
+ sLog.outError("StartHeroicPlayerLevel (%i) must be in range 1..MaxPlayerLevel(%u). Set to 55.",
+ m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL],m_configs[CONFIG_MAX_PLAYER_LEVEL]);
+ m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] = 55;
+ }
+ else if(m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] > m_configs[CONFIG_MAX_PLAYER_LEVEL])
+ {
+ sLog.outError("StartHeroicPlayerLevel (%i) must be in range 1..MaxPlayerLevel(%u). Set to %u.",
+ m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL],m_configs[CONFIG_MAX_PLAYER_LEVEL],m_configs[CONFIG_MAX_PLAYER_LEVEL]);
+ m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] = m_configs[CONFIG_MAX_PLAYER_LEVEL];
+ }
+
m_configs[CONFIG_START_PLAYER_MONEY] = sConfig.GetIntDefault("StartPlayerMoney", 0);
if(m_configs[CONFIG_START_PLAYER_MONEY] < 0)
{
@@ -724,8 +753,11 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_INSTANCE_IGNORE_RAID] = sConfig.GetBoolDefault("Instance.IgnoreRaid", false);
m_configs[CONFIG_BATTLEGROUND_CAST_DESERTER] = sConfig.GetBoolDefault("Battleground.CastDeserter", true);
- m_configs[CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE] = sConfig.GetBoolDefault("Battleground.QueueAnnouncer.Enable", true);
+ m_configs[CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE] = sConfig.GetBoolDefault("Battleground.QueueAnnouncer.Enable", false);
m_configs[CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY] = sConfig.GetBoolDefault("Battleground.QueueAnnouncer.PlayerOnly", false);
+ m_configs[CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE] = sConfig.GetBoolDefault("Arena.QueueAnnouncer.Enable", false);
+ m_configs[CONFIG_ARENA_SEASON_ID] = sConfig.GetIntDefault ("Arena.ArenaSeason.ID", 1);
+ m_configs[CONFIG_ARENA_SEASON_IN_PROGRESS] = sConfig.GetBoolDefault("Arena.ArenaSeason.InProgress", true);
m_configs[CONFIG_CAST_UNSTUCK] = sConfig.GetBoolDefault("CastUnstuck", true);
m_configs[CONFIG_INSTANCE_RESET_TIME_HOUR] = sConfig.GetIntDefault("Instance.ResetTimeHour", 4);
@@ -735,15 +767,17 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_MIN_PETITION_SIGNS] = sConfig.GetIntDefault("MinPetitionSigns", 9);
if(m_configs[CONFIG_MIN_PETITION_SIGNS] > 9)
{
- sLog.outError("MinPetitionSigns (%i) must be in range 0..9. Set to 9.",m_configs[CONFIG_MIN_PETITION_SIGNS]);
+ sLog.outError("MinPetitionSigns (%i) must be in range 0..9. Set to 9.", m_configs[CONFIG_MIN_PETITION_SIGNS]);
m_configs[CONFIG_MIN_PETITION_SIGNS] = 9;
}
- m_configs[CONFIG_GM_LOGIN_STATE] = sConfig.GetIntDefault("GM.LoginState",2);
- m_configs[CONFIG_GM_CHAT] = sConfig.GetIntDefault("GM.Chat",2);
- m_configs[CONFIG_GM_WISPERING_TO] = sConfig.GetIntDefault("GM.WhisperingTo",2);
- m_configs[CONFIG_GM_IN_GM_LIST] = sConfig.GetBoolDefault("GM.InGMList",false);
- m_configs[CONFIG_GM_IN_WHO_LIST] = sConfig.GetBoolDefault("GM.InWhoList",false);
+ m_configs[CONFIG_GM_LOGIN_STATE] = sConfig.GetIntDefault("GM.LoginState", 2);
+ m_configs[CONFIG_GM_VISIBLE_STATE] = sConfig.GetIntDefault("GM.Visible", 2);
+ //m_configs[CONFIG_GM_ACCEPT_TICKETS] = sConfig.GetIntDefault("GM.AcceptTickets", 2);
+ m_configs[CONFIG_GM_CHAT] = sConfig.GetIntDefault("GM.Chat", 2);
+ m_configs[CONFIG_GM_WISPERING_TO] = sConfig.GetIntDefault("GM.WhisperingTo", 2);
+ m_configs[CONFIG_GM_IN_GM_LIST] = sConfig.GetBoolDefault("GM.InGMList", false);
+ m_configs[CONFIG_GM_IN_WHO_LIST] = sConfig.GetBoolDefault("GM.InWhoList", false);
m_configs[CONFIG_GM_LOG_TRADE] = sConfig.GetBoolDefault("GM.LogTrade", false);
m_configs[CONFIG_START_GM_LEVEL] = sConfig.GetIntDefault("GM.StartLevel", 1);
if(m_configs[CONFIG_START_GM_LEVEL] < m_configs[CONFIG_START_PLAYER_LEVEL])
@@ -757,6 +791,8 @@ void World::LoadConfigSettings(bool reload)
sLog.outError("GM.StartLevel (%i) must be in range 1..%u. Set to %u.", m_configs[CONFIG_START_GM_LEVEL], MAX_LEVEL, MAX_LEVEL);
m_configs[CONFIG_START_GM_LEVEL] = MAX_LEVEL;
}
+ m_configs[CONFIG_GM_LOWER_SECURITY] = sConfig.GetBoolDefault("GM.LowerSecurity", false);
+ m_configs[CONFIG_GM_ALLOW_ACHIEVEMENT_GAINS] = sConfig.GetBoolDefault("GM.AllowAchievementGain", true);
m_configs[CONFIG_GROUP_VISIBILITY] = sConfig.GetIntDefault("Visibility.GroupMode",0);
@@ -783,6 +819,7 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_SKILL_CHANCE_SKINNING_STEPS] = sConfig.GetIntDefault("SkillChance.SkinningSteps",75);
m_configs[CONFIG_SKILL_PROSPECTING] = sConfig.GetBoolDefault("SkillChance.Prospecting",false);
+ m_configs[CONFIG_SKILL_MILLING] = sConfig.GetBoolDefault("SkillChance.Milling",false);
m_configs[CONFIG_SKILL_GAIN_CRAFTING] = sConfig.GetIntDefault("SkillGain.Crafting", 1);
if(m_configs[CONFIG_SKILL_GAIN_CRAFTING] < 0)
@@ -871,6 +908,8 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_DEATH_SICKNESS_LEVEL] = sConfig.GetIntDefault("Death.SicknessLevel", 11);
m_configs[CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVP] = sConfig.GetBoolDefault("Death.CorpseReclaimDelay.PvP", true);
m_configs[CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVE] = sConfig.GetBoolDefault("Death.CorpseReclaimDelay.PvE", true);
+ m_configs[CONFIG_DEATH_BONES_WORLD] = sConfig.GetBoolDefault("Death.Bones.World", true);
+ m_configs[CONFIG_DEATH_BONES_BG_OR_ARENA] = sConfig.GetBoolDefault("Death.Bones.BattlegroundOrArena", true);
m_configs[CONFIG_THREAT_RADIUS] = sConfig.GetIntDefault("ThreatRadius", 60);
@@ -1069,7 +1108,7 @@ void World::SetInitialWorldSettings()
sLog.outString( "Loading Script Names...");
objmgr.LoadScriptNames();
- sLog.outString( "Loading InstanceTemplate" );
+ sLog.outString( "Loading InstanceTemplate..." );
objmgr.LoadInstanceTemplate();
sLog.outString( "Loading SkillLineAbilityMultiMap Data..." );
@@ -1077,11 +1116,12 @@ void World::SetInitialWorldSettings()
///- Clean up and pack instances
sLog.outString( "Cleaning up instances..." );
- sInstanceSaveManager.CleanupInstances(); // must be called before `creature_respawn`/`gameobject_respawn` tables
+ sInstanceSaveManager.CleanupInstances(); // must be called before `creature_respawn`/`gameobject_respawn` tables
sLog.outString( "Packing instances..." );
sInstanceSaveManager.PackInstances();
+ sLog.outString();
sLog.outString( "Loading Localization strings..." );
objmgr.LoadCreatureLocales();
objmgr.LoadGameObjectLocales();
@@ -1091,6 +1131,8 @@ void World::SetInitialWorldSettings()
objmgr.LoadPageTextLocales();
objmgr.LoadNpcOptionLocales();
objmgr.SetDBCLocaleIndex(GetDefaultDbcLocale()); // Get once for all the locale index of DBC language (console/broadcasts)
+ sLog.outString( ">>> Localization strings loaded" );
+ sLog.outString();
sLog.outString( "Loading Page Texts..." );
objmgr.LoadPageTexts();
@@ -1119,6 +1161,9 @@ void World::SetInitialWorldSettings()
sLog.outString( "Loading Spell Proc Event conditions..." );
spellmgr.LoadSpellProcEvents();
+ sLog.outString( "Loading Spell Bonus Data..." );
+ spellmgr.LoadSpellBonusess();
+
sLog.outString( "Loading Aggro Spells Definitions...");
spellmgr.LoadSpellThreats();
@@ -1156,7 +1201,10 @@ void World::SetInitialWorldSettings()
objmgr.LoadCreatures();
sLog.outString( "Loading Creature Addon Data..." );
+ sLog.outString();
objmgr.LoadCreatureAddons(); // must be after LoadCreatureTemplates() and LoadCreatures()
+ sLog.outString( ">>> Creature Addon Data loaded" );
+ sLog.outString();
sLog.outString( "Loading Creature Respawn Data..." ); // must be after PackInstances()
objmgr.LoadCreatureRespawnTimes();
@@ -1168,7 +1216,10 @@ void World::SetInitialWorldSettings()
objmgr.LoadGameobjectRespawnTimes();
sLog.outString( "Loading Game Event Data...");
+ sLog.outString();
gameeventmgr.LoadFromDB();
+ sLog.outString( ">>> Game Event Data loaded" );
+ sLog.outString();
sLog.outString( "Loading Weather Data..." );
objmgr.LoadWeatherZoneChances();
@@ -1177,7 +1228,10 @@ void World::SetInitialWorldSettings()
objmgr.LoadQuests(); // must be loaded after DBCs, creature_template, item_template, gameobject tables
sLog.outString( "Loading Quests Relations..." );
+ sLog.outString();
objmgr.LoadQuestRelations(); // must be after quest load
+ sLog.outString( ">>> Quests Relations loaded" );
+ sLog.outString();
sLog.outString( "Loading AreaTrigger definitions..." );
objmgr.LoadAreaTriggerTeleports(); // must be after item template load
@@ -1203,14 +1257,20 @@ void World::SetInitialWorldSettings()
sLog.outString( "Loading spell pet auras..." );
spellmgr.LoadSpellPetAuras();
+ sLog.outString( "Loading pet levelup spells..." );
+ spellmgr.LoadPetLevelupSpellMap();
+
sLog.outString( "Loading spell extra attributes...(TODO)" );
spellmgr.LoadSpellCustomAttr();
sLog.outString( "Loading linked spells..." );
spellmgr.LoadSpellLinked();
- sLog.outString( "Loading player Create Info & Level Stats..." );
+ sLog.outString( "Loading Player Create Info & Level Stats..." );
+ sLog.outString();
objmgr.LoadPlayerInfo();
+ sLog.outString( ">>> Player Create Info & Level Stats loaded" );
+ sLog.outString();
sLog.outString( "Loading Exploration BaseXP Data..." );
objmgr.LoadExplorationBaseXP();
@@ -1231,7 +1291,10 @@ void World::SetInitialWorldSettings()
objmgr.LoadSpellDisabledEntrys();
sLog.outString( "Loading Loot Tables..." );
+ sLog.outString();
LoadLootTables();
+ sLog.outString( ">>> Loot Tables loaded" );
+ sLog.outString();
sLog.outString( "Loading Skill Discovery Table..." );
LoadSkillDiscoveryTable();
@@ -1242,10 +1305,22 @@ void World::SetInitialWorldSettings()
sLog.outString( "Loading Skill Fishing base level requirements..." );
objmgr.LoadFishingBaseSkillLevel();
+ sLog.outString( "Loading Achievements..." );
+ sLog.outString();
+ achievementmgr.LoadAchievementCriteriaList();
+ achievementmgr.LoadRewards();
+ achievementmgr.LoadRewardLocales();
+ achievementmgr.LoadCompletedAchievements();
+ sLog.outString( ">>> Achievements loaded" );
+ sLog.outString();
+
///- Load dynamic data tables from the database
sLog.outString( "Loading Auctions..." );
+ sLog.outString();
objmgr.LoadAuctionItems();
objmgr.LoadAuctions();
+ sLog.outString( ">>> Auctions loaded" );
+ sLog.outString();
sLog.outString( "Loading Guilds..." );
objmgr.LoadGuilds();
@@ -1259,11 +1334,11 @@ void World::SetInitialWorldSettings()
sLog.outString( "Loading ReservedNames..." );
objmgr.LoadReservedPlayersNames();
- sLog.outString( "Loading GameObject for quests..." );
+ sLog.outString( "Loading GameObjects for quests..." );
objmgr.LoadGameObjectForQuests();
sLog.outString( "Loading BattleMasters..." );
- objmgr.LoadBattleMastersEntry();
+ sBattleGroundMgr.LoadBattleMastersEntry();
sLog.outString( "Loading GameTeleports..." );
objmgr.LoadGameTele();
@@ -1274,13 +1349,14 @@ void World::SetInitialWorldSettings()
sLog.outString( "Loading Npc Options..." );
objmgr.LoadNpcOptions();
- sLog.outString( "Loading vendors..." );
+ sLog.outString( "Loading Vendors..." );
objmgr.LoadVendors(); // must be after load CreatureTemplate and ItemTemplate
- sLog.outString( "Loading trainers..." );
+ sLog.outString( "Loading Trainers..." );
objmgr.LoadTrainerSpell(); // must be after load CreatureTemplate
sLog.outString( "Loading Waypoints..." );
+ sLog.outString();
WaypointMgr.Load();
sLog.outString( "Loading Creature Formations..." );
@@ -1295,12 +1371,15 @@ void World::SetInitialWorldSettings()
///- Load and initialize scripts
sLog.outString( "Loading Scripts..." );
+ sLog.outString();
objmgr.LoadQuestStartScripts(); // must be after load Creature/Gameobject(Template/Data) and QuestTemplate
objmgr.LoadQuestEndScripts(); // must be after load Creature/Gameobject(Template/Data) and QuestTemplate
objmgr.LoadSpellScripts(); // must be after load Creature/Gameobject(Template/Data)
objmgr.LoadGameObjectScripts(); // must be after load Creature/Gameobject(Template/Data)
objmgr.LoadEventScripts(); // must be after load Creature/Gameobject(Template/Data)
objmgr.LoadWaypointScripts();
+ sLog.outString( ">>> Scripts loaded" );
+ sLog.outString();
sLog.outString( "Loading Scripts text locales..." ); // must be after Load*Scripts calls
objmgr.LoadDbScriptStrings();
@@ -1422,6 +1501,7 @@ void World::DetectDBCLang()
m_defaultDbcLocale = LocaleConstant(default_locale);
sLog.outString("Using %s DBC Locale as default. All available DBC locales: %s",localeNames[m_defaultDbcLocale],availableLocalsStr.empty() ? "<none>" : availableLocalsStr.c_str());
+ sLog.outString();
}
void World::RecordTimeDiff(const char *text, ...)
@@ -1451,7 +1531,7 @@ void World::RecordTimeDiff(const char *text, ...)
}
/// Update the World !
-void World::Update(time_t diff)
+void World::Update(uint32 diff)
{
m_updateTime = uint32(diff);
if(m_configs[CONFIG_INTERVAL_LOG_UPDATE])
@@ -1505,13 +1585,13 @@ void World::Update(time_t diff)
switch (i)
{
case 0:
- AuctionMap = objmgr.GetAuctionsMap( 6 );//horde
+ AuctionMap = objmgr.GetAuctionsMap(AUCTION_HORDE);
break;
case 1:
- AuctionMap = objmgr.GetAuctionsMap( 2 );//alliance
+ AuctionMap = objmgr.GetAuctionsMap(AUCTION_ALLIANCE);
break;
case 2:
- AuctionMap = objmgr.GetAuctionsMap( 7 );//neutral
+ AuctionMap = objmgr.GetAuctionsMap(AUCTION_NEUTRAL);
break;
}
@@ -1739,6 +1819,9 @@ void World::ScriptsProcess()
case HIGHGUID_PET:
source = HashMapHolder<Pet>::Find(step.sourceGUID);
break;
+ case HIGHGUID_VEHICLE:
+ source = HashMapHolder<Vehicle>::Find(step.sourceGUID);
+ break;
case HIGHGUID_PLAYER:
source = HashMapHolder<Player>::Find(step.sourceGUID);
break;
@@ -1778,6 +1861,9 @@ void World::ScriptsProcess()
case HIGHGUID_PET:
target = HashMapHolder<Pet>::Find(step.targetGUID);
break;
+ case HIGHGUID_VEHICLE:
+ target = HashMapHolder<Vehicle>::Find(step.targetGUID);
+ break;
case HIGHGUID_PLAYER: // empty GUID case also
target = HashMapHolder<Player>::Find(step.targetGUID);
break;
@@ -2008,8 +2094,8 @@ void World::ScriptsProcess()
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
- Trinity::GameObjectWithDbGUIDCheck go_check(*summoner,step.script->datalong);
- Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck> checker(go,go_check);
+ MaNGOS::GameObjectWithDbGUIDCheck go_check(*summoner,step.script->datalong);
+ MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck> checker(summoner, go,go_check);
TypeContainerVisitor<Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
@@ -2069,8 +2155,8 @@ void World::ScriptsProcess()
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
- Trinity::GameObjectWithDbGUIDCheck go_check(*caster,step.script->datalong);
- Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck> checker(door,go_check);
+ MaNGOS::GameObjectWithDbGUIDCheck go_check(*caster,step.script->datalong);
+ MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck> checker(caster,door,go_check);
TypeContainerVisitor<Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
@@ -2125,8 +2211,8 @@ void World::ScriptsProcess()
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
- Trinity::GameObjectWithDbGUIDCheck go_check(*caster,step.script->datalong);
- Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck> checker(door,go_check);
+ MaNGOS::GameObjectWithDbGUIDCheck go_check(*caster,step.script->datalong);
+ MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck> checker(caster,door,go_check);
TypeContainerVisitor<Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
@@ -2342,7 +2428,7 @@ void World::ScriptsProcess()
//sLog.outDebug("Attempting to find Creature: Db GUID: %i", step.script->datalong);
Trinity::CreatureWithDbGUIDCheck target_check(((Unit*)source), step.script->datalong);
- Trinity::CreatureSearcher<Trinity::CreatureWithDbGUIDCheck> checker(target,target_check);
+ Trinity::CreatureSearcher<Trinity::CreatureWithDbGUIDCheck> checker(((Unit*)source), target, target_check);
TypeContainerVisitor<Trinity::CreatureSearcher <Trinity::CreatureWithDbGUIDCheck>, GridTypeMapContainer > unit_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
@@ -2559,7 +2645,7 @@ void World::SendGMText(int32 string_id, ...)
delete data_cache[i][j];
}
-/// Send a System Message to all players (except self if mentioned)
+/// DEPRICATED, only for debug purpose. Send a System Message to all players (except self if mentioned)
void World::SendGlobalText(const char* text, WorldSession *self)
{
WorldPacket data;
@@ -2850,7 +2936,7 @@ void World::SendServerMessage(uint32 type, const char *text, Player* player)
SendGlobalMessage( &data );
}
-void World::UpdateSessions( time_t diff )
+void World::UpdateSessions( uint32 diff )
{
///- Add new sessions
while(!addSessQueue.empty())
diff --git a/src/game/World.h b/src/game/World.h
index 502f403d130..8ceb356c076 100644
--- a/src/game/World.h
+++ b/src/game/World.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -103,9 +103,12 @@ enum WorldConfigs
CONFIG_CHARACTERS_CREATING_DISABLED,
CONFIG_CHARACTERS_PER_ACCOUNT,
CONFIG_CHARACTERS_PER_REALM,
+ CONFIG_HEROIC_CHARACTERS_PER_REALM,
+ CONFIG_MIN_LEVEL_FOR_HEROIC_CHARACTER_CREATING,
CONFIG_SKIP_CINEMATICS,
CONFIG_MAX_PLAYER_LEVEL,
CONFIG_START_PLAYER_LEVEL,
+ CONFIG_START_HEROIC_PLAYER_LEVEL,
CONFIG_START_PLAYER_MONEY,
CONFIG_MAX_HONOR_POINTS,
CONFIG_START_HONOR_POINTS,
@@ -122,12 +125,16 @@ enum WorldConfigs
CONFIG_MAX_PRIMARY_TRADE_SKILL,
CONFIG_MIN_PETITION_SIGNS,
CONFIG_GM_LOGIN_STATE,
+ CONFIG_GM_VISIBLE_STATE,
+ CONFIG_GM_ACCEPT_TICKETS,
CONFIG_GM_CHAT,
CONFIG_GM_WISPERING_TO,
CONFIG_GM_IN_GM_LIST,
CONFIG_GM_IN_WHO_LIST,
CONFIG_GM_LOG_TRADE,
CONFIG_START_GM_LEVEL,
+ CONFIG_GM_LOWER_SECURITY,
+ CONFIG_GM_ALLOW_ACHIEVEMENT_GAINS,
CONFIG_GROUP_VISIBILITY,
CONFIG_MAIL_DELIVERY_DELAY,
CONFIG_UPTIME_UPDATE,
@@ -170,6 +177,8 @@ enum WorldConfigs
CONFIG_DEATH_SICKNESS_LEVEL,
CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVP,
CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVE,
+ CONFIG_DEATH_BONES_WORLD,
+ CONFIG_DEATH_BONES_BG_OR_ARENA,
CONFIG_THREAT_RADIUS,
CONFIG_INSTANT_LOGOUT,
CONFIG_DISABLE_BREATHING,
@@ -182,8 +191,11 @@ enum WorldConfigs
CONFIG_ARENA_RATING_DISCARD_TIMER,
CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS,
CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS,
+ CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE,
+ CONFIG_ARENA_SEASON_ID,
+ CONFIG_ARENA_SEASON_IN_PROGRESS,
CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER,
-
+ CONFIG_SKILL_MILLING,
CONFIG_MAX_WHO,
CONFIG_BG_START_MUSIC,
CONFIG_START_ALL_SPELLS,
@@ -211,6 +223,8 @@ enum Rates
RATE_POWER_MANA,
RATE_POWER_RAGE_INCOME,
RATE_POWER_RAGE_LOSS,
+ RATE_POWER_RUNICPOWER_INCOME,
+ RATE_POWER_RUNICPOWER_LOSS,
RATE_POWER_FOCUS,
RATE_SKILL_DISCOVERY,
RATE_DROP_ITEM_POOR,
@@ -225,7 +239,6 @@ enum Rates
RATE_XP_KILL,
RATE_XP_QUEST,
RATE_XP_EXPLORE,
- RATE_XP_PAST_70,
RATE_REPUTATION_GAIN,
RATE_CREATURE_NORMAL_HP,
RATE_CREATURE_ELITE_ELITE_HP,
@@ -254,7 +267,6 @@ enum Rates
RATE_MINING_AMOUNT,
RATE_MINING_NEXT,
RATE_TALENT,
- RATE_LOYALTY,
RATE_CORPSE_DECAY_LOOTED,
RATE_INSTANCE_RESET_TIME,
RATE_TARGET_POS_RECALCULATION_RANGE,
@@ -450,9 +462,9 @@ class World
static void StopNow(uint8 exitcode) { m_stopEvent = true; m_ExitCode = exitcode; }
static bool IsStopped() { return m_stopEvent; }
- void Update(time_t diff);
+ void Update(uint32 diff);
- void UpdateSessions( time_t diff );
+ void UpdateSessions( uint32 diff );
/// Set a server rate (see #Rates)
void setRate(Rates rate,float value) { rate_values[rate]=value; }
/// Get a server rate (see #Rates)
diff --git a/src/game/WorldLog.cpp b/src/game/WorldLog.cpp
index 4881b997495..eeac973ba5f 100644
--- a/src/game/WorldLog.cpp
+++ b/src/game/WorldLog.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/WorldLog.h b/src/game/WorldLog.h
index 8ec03d37d6d..47e1a912986 100644
--- a/src/game/WorldLog.h
+++ b/src/game/WorldLog.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -51,9 +51,9 @@ class TRINITY_DLL_DECL WorldLog : public Trinity::Singleton<WorldLog, Trinity::C
public:
void Initialize();
/// Is the world logger active?
- inline bool LogWorld(void) const { return (i_file != NULL); }
+ bool LogWorld(void) const { return (i_file != NULL); }
/// %Log to the file
- inline void Log(char const *fmt, ...)
+ void Log(char const *fmt, ...)
{
if( LogWorld() )
{
diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp
index e043bbe9659..edcb0dc8a39 100644
--- a/src/game/WorldSession.cpp
+++ b/src/game/WorldSession.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -314,9 +314,9 @@ void WorldSession::LogoutPlayer(bool Save)
_player->RepopAtGraveyard();
}
- ///- Remove player from battleground (teleport to entrance)
- if(_player->InBattleGround())
- _player->LeaveBattleground();
+ ///- Teleport to home if the player is in an invalid instance
+ if(!_player->m_InstanceValid && !_player->isGameMaster())
+ _player->TeleportTo(_player->m_homebindMapId, _player->m_homebindX, _player->m_homebindY, _player->m_homebindZ, _player->GetOrientation());
sOutdoorPvPMgr.HandlePlayerLeaveZone(_player,_player->GetZoneId());
@@ -526,3 +526,93 @@ void WorldSession::SendAuthWaitQue(uint32 position)
SendPacket(&packet);
}
}
+
+void WorldSession::LoadAccountData()
+{
+ for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i)
+ {
+ AccountData data;
+ m_accountData[i] = data;
+ }
+
+ QueryResult *result = CharacterDatabase.PQuery("SELECT type, time, data FROM account_data WHERE account='%u'", GetAccountId());
+
+ if(!result)
+ return;
+
+ do
+ {
+ Field *fields = result->Fetch();
+
+ uint32 type = fields[0].GetUInt32();
+ if(type < NUM_ACCOUNT_DATA_TYPES)
+ {
+ m_accountData[type].Time = fields[1].GetUInt32();
+ m_accountData[type].Data = fields[2].GetCppString();
+ }
+ } while (result->NextRow());
+
+ delete result;
+}
+
+void WorldSession::SetAccountData(uint32 type, time_t time_, std::string data)
+{
+ m_accountData[type].Time = time_;
+ m_accountData[type].Data = data;
+
+ uint32 acc = GetAccountId();
+
+ CharacterDatabase.BeginTransaction ();
+ CharacterDatabase.PExecute("DELETE FROM account_data WHERE account='%u' AND type='%u'", acc, type);
+ CharacterDatabase.escape_string(data);
+ CharacterDatabase.PExecute("INSERT INTO account_data VALUES ('%u','%u','%u','%s')", acc, type, (uint32)time_, data.c_str());
+ CharacterDatabase.CommitTransaction ();
+}
+
+void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi)
+{
+ CHECK_PACKET_SIZE(data, data.rpos()+4+2+4+4+4+4+4);
+ data >> mi->flags;
+ data >> mi->unk1;
+ data >> mi->time;
+ data >> mi->x;
+ data >> mi->y;
+ data >> mi->z;
+ data >> mi->o;
+
+ if(mi->flags & MOVEMENTFLAG_ONTRANSPORT)
+ {
+ CHECK_PACKET_SIZE(data, data.rpos()+8+4+4+4+4+4+1);
+ data >> mi->t_guid;
+ data >> mi->t_x;
+ data >> mi->t_y;
+ data >> mi->t_z;
+ data >> mi->t_o;
+ data >> mi->t_time;
+ data >> mi->t_seat;
+ }
+
+ if((mi->flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2)) || (mi->unk1 & 0x20))
+ {
+ CHECK_PACKET_SIZE(data, data.rpos()+4);
+ data >> mi->s_pitch;
+ }
+
+ CHECK_PACKET_SIZE(data, data.rpos()+4);
+ data >> mi->fallTime;
+
+ if(mi->flags & MOVEMENTFLAG_JUMPING)
+ {
+ CHECK_PACKET_SIZE(data, data.rpos()+4+4+4+4);
+ data >> mi->j_unk;
+ data >> mi->j_sinAngle;
+ data >> mi->j_cosAngle;
+ data >> mi->j_xyspeed;
+ }
+
+ if(mi->flags & MOVEMENTFLAG_SPLINE)
+ {
+ CHECK_PACKET_SIZE(data, data.rpos()+4);
+ data >> mi->u_unk1;
+ }
+}
diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h
index a19e0bb7376..f845fc0d1c9 100644
--- a/src/game/WorldSession.h
+++ b/src/game/WorldSession.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -26,6 +26,7 @@
#define __WORLDSESSION_H
#include "Common.h"
+#include "SharedDefines.h"
class MailItemsInfo;
struct ItemPrototype;
@@ -47,6 +48,16 @@ class CharacterHandler;
#define CHECK_PACKET_SIZE(P,S) if((P).size() < (S)) return SizeError((P),(S));
+#define NUM_ACCOUNT_DATA_TYPES 8
+
+struct AccountData
+{
+ AccountData() : Time(0), Data("") {}
+
+ time_t Time;
+ std::string Data;
+};
+
enum PartyOperation
{
PARTY_OP_INVITE = 0,
@@ -81,6 +92,8 @@ class TRINITY_DLL_SPEC WorldSession
void SizeError(WorldPacket const& packet, uint32 size) const;
+ void ReadMovementInfo(WorldPacket &data, MovementInfo *mi);
+
void SendPacket(WorldPacket const* packet);
void SendNotification(const char *format,...) ATTR_PRINTF(2,3);
void SendNotification(int32 string_id,...);
@@ -141,7 +154,7 @@ class TRINITY_DLL_SPEC WorldSession
void SendAttackStop(Unit const* enemy);
- void SendBattlegGroundList( uint64 guid, uint32 bgTypeId );
+ void SendBattlegGroundList( uint64 guid, BattleGroundTypeId bgTypeId );
void SendTradeStatus(uint32 status);
void SendCancelTrade();
@@ -153,6 +166,11 @@ class TRINITY_DLL_SPEC WorldSession
//pet
void SendPetNameQuery(uint64 guid, uint32 petnumber);
+ // Account Data
+ AccountData *GetAccountData(uint32 type) { return &m_accountData[type]; }
+ void SetAccountData(uint32 type, time_t time_, std::string data);
+ void LoadAccountData();
+
//mail
//used with item_page table
bool SendItemInfo( uint32 itemid, WorldPacket data );
@@ -310,6 +328,7 @@ class TRINITY_DLL_SPEC WorldSession
void HandleGameObjectUseOpcode(WorldPacket& recPacket);
void HandleMeetingStoneInfo(WorldPacket& recPacket);
+ void HandleGameobjectReportUse(WorldPacket& recvPacket);
void HandleNameQueryOpcode(WorldPacket& recvPacket);
@@ -323,9 +342,10 @@ class TRINITY_DLL_SPEC WorldSession
void HandleMoveWorldportAckOpcode(); // for server-side calls
void HandleMovementOpcodes(WorldPacket& recvPacket);
- void HandlePossessedMovement(WorldPacket& recv_data, MovementInfo& movementInfo, uint32& MovementFlags);
+ //void HandlePossessedMovement(WorldPacket& recv_data, MovementInfo& movementInfo, uint32& MovementFlags);
void HandleSetActiveMoverOpcode(WorldPacket &recv_data);
- void HandleNotActiveMoverOpcode(WorldPacket &recv_data);
+ void HandleMoveNotActiveMover(WorldPacket &recv_data);
+ void HandleDismissControlledVehicle(WorldPacket &recv_data);
void HandleMoveTimeSkippedOpcode(WorldPacket &recv_data);
void HandleRequestRaidInfoOpcode( WorldPacket & recv_data );
@@ -386,7 +406,7 @@ class TRINITY_DLL_SPEC WorldSession
void HandleGuildSaveEmblemOpcode(WorldPacket& recvPacket);
void HandleTaxiNodeStatusQueryOpcode(WorldPacket& recvPacket);
- void HandleTaxiQueryAvailableNodesOpcode(WorldPacket& recvPacket);
+ void HandleTaxiQueryAvailableNodes(WorldPacket& recvPacket);
void HandleActivateTaxiOpcode(WorldPacket& recvPacket);
void HandleActivateTaxiFarOpcode(WorldPacket& recvPacket);
void HandleTaxiNextDestinationOpcode(WorldPacket& recvPacket);
@@ -430,6 +450,7 @@ class TRINITY_DLL_SPEC WorldSession
void HandleAuctionRemoveItem( WorldPacket & recv_data );
void HandleAuctionListOwnerItems( WorldPacket & recv_data );
void HandleAuctionPlaceBid( WorldPacket & recv_data );
+ void HandleAuctionListPendingSales( WorldPacket & recv_data );
void HandleGetMail( WorldPacket & recv_data );
void HandleSendMail( WorldPacket & recv_data );
@@ -545,6 +566,7 @@ class TRINITY_DLL_SPEC WorldSession
void HandlePetUnlearnOpcode( WorldPacket& recvPacket );
void HandlePetSpellAutocastOpcode( WorldPacket& recvPacket );
void HandlePetCastSpellOpcode( WorldPacket& recvPacket );
+ void HandlePetLearnTalent( WorldPacket& recvPacket );
void HandleSetActionBar(WorldPacket& recv_data);
@@ -581,10 +603,9 @@ class TRINITY_DLL_SPEC WorldSession
void HandleLfmSetNoneOpcode(WorldPacket& recv_data);
void HandleLfmSetOpcode(WorldPacket& recv_data);
void HandleLfgSetCommentOpcode(WorldPacket& recv_data);
- void HandleNewUnknownOpcode(WorldPacket& recv_data);
void HandleChooseTitleOpcode(WorldPacket& recv_data);
void HandleRealmStateRequestOpcode(WorldPacket& recv_data);
- void HandleAllowMoveAckOpcode(WorldPacket& recv_data);
+ void HandleTimeSyncResp(WorldPacket& recv_data);
void HandleWhoisOpcode(WorldPacket& recv_data);
void HandleResetInstancesOpcode(WorldPacket& recv_data);
@@ -630,6 +651,29 @@ class TRINITY_DLL_SPEC WorldSession
void HandleGuildBankBuyTab(WorldPacket& recv_data);
void HandleGuildBankTabText(WorldPacket& recv_data);
void HandleGuildBankSetTabText(WorldPacket& recv_data);
+
+ // Calendar
+ void HandleCalendarGetCalendar(WorldPacket& recv_data);
+ void HandleCalendarGetEvent(WorldPacket& recv_data);
+ void HandleCalendarGuildFilter(WorldPacket& recv_data);
+ void HandleCalendarArenaTeam(WorldPacket& recv_data);
+ void HandleCalendarAddEvent(WorldPacket& recv_data);
+ void HandleCalendarUpdateEvent(WorldPacket& recv_data);
+ void HandleCalendarRemoveEvent(WorldPacket& recv_data);
+ void HandleCalendarCopyEvent(WorldPacket& recv_data);
+ void HandleCalendarEventInvite(WorldPacket& recv_data);
+ void HandleCalendarEventRsvp(WorldPacket& recv_data);
+ void HandleCalendarEventRemoveInvite(WorldPacket& recv_data);
+ void HandleCalendarEventStatus(WorldPacket& recv_data);
+ void HandleCalendarEventModeratorStatus(WorldPacket& recv_data);
+ void HandleCalendarComplain(WorldPacket& recv_data);
+ void HandleCalendarGetNumPending(WorldPacket& recv_data);
+
+ void HandleSpellClick(WorldPacket& recv_data);
+ void HandleAlterAppearance(WorldPacket& recv_data);
+ void HandleRemoveGlyph(WorldPacket& recv_data);
+ void HandleCharCustomize(WorldPacket& recv_data);
+ void HandleInspectAchievements(WorldPacket& recv_data);
private:
// private trade methods
void moveItems(Item* myItems[], Item* hisItems[]);
@@ -652,6 +696,7 @@ class TRINITY_DLL_SPEC WorldSession
LocaleConstant m_sessionDbcLocale;
int m_sessionDbLocaleIndex;
uint32 m_latency;
+ AccountData m_accountData[NUM_ACCOUNT_DATA_TYPES];
ZThread::LockedQueue<WorldPacket*,ZThread::FastMutex> _recvQueue;
};
diff --git a/src/game/WorldSocket.cpp b/src/game/WorldSocket.cpp
index c54a7aaf45a..9913c912c70 100644
--- a/src/game/WorldSocket.cpp
+++ b/src/game/WorldSocket.cpp
@@ -1,7 +1,7 @@
/*
-* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
-* Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+* Copyright (C) 2008-2009 Trinity <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
@@ -54,8 +54,37 @@
struct ServerPktHeader
{
- uint16 size;
- uint16 cmd;
+ /**
+ * size is the length of the payload _plus_ the length of the opcode
+ */
+ ServerPktHeader(uint32 size, uint16 cmd) : size(size)
+ {
+ uint8 headerIndex=0;
+ if(isLargePacket())
+ {
+ sLog.outDebug("initializing large server to client packet. Size: %u, cmd: %u", size, cmd);
+ header[headerIndex++] = 0x80|(0xFF &(size>>16));
+ }
+ header[headerIndex++] = 0xFF &(size>>8);
+ header[headerIndex++] = 0xFF &size;
+
+ header[headerIndex++] = 0xFF & cmd;
+ header[headerIndex++] = 0xFF & (cmd>>8);
+ }
+
+ uint8 getHeaderLength()
+ {
+ // cmd = 2 bytes, size= 2||3bytes
+ return 2+(isLargePacket()?3:2);
+ }
+
+ bool isLargePacket()
+ {
+ return size > 0x7FFF;
+ }
+
+ const uint32 size;
+ uint8 header[5];
};
struct ClientPktHeader
@@ -84,6 +113,9 @@ m_OverSpeedPings (0),
m_LastPingTime (ACE_Time_Value::zero)
{
reference_counting_policy ().value (ACE_Event_Handler::Reference_Counting_Policy::ENABLED);
+
+ msg_queue()->high_water_mark(8*1024*1024);
+ msg_queue()->low_water_mark(8*1024*1024);
}
WorldSocket::~WorldSocket (void)
@@ -97,10 +129,6 @@ WorldSocket::~WorldSocket (void)
closing_ = true;
peer ().close ();
-
- WorldPacket* pct;
- while (m_PacketQueue.dequeue_head (pct) == 0)
- delete pct;
}
bool WorldSocket::IsClosed (void) const
@@ -160,18 +188,35 @@ int WorldSocket::SendPacket (const WorldPacket& pct)
sWorldLog.Log ("\n\n");
}
- if (iSendPacket (pct) == -1)
+ ServerPktHeader header(pct.size()+2, pct.GetOpcode());
+ m_Crypt.EncryptSend ( header.header, header.getHeaderLength());
+
+ if (m_OutBuffer->space () >= pct.size () + header.getHeaderLength() && msg_queue()->is_empty())
+ {
+ // Put the packet on the buffer.
+ if (m_OutBuffer->copy ((char*) header.header, header.getHeaderLength()) == -1)
+ ACE_ASSERT (false);
+
+ if (!pct.empty ())
+ if (m_OutBuffer->copy ((char*) pct.contents (), pct.size ()) == -1)
+ ACE_ASSERT (false);
+ }
+ else
{
- WorldPacket* npct;
+ // Enqueue the packet.
+ ACE_Message_Block* mb;
+
+ ACE_NEW_RETURN(mb, ACE_Message_Block(pct.size () + header.getHeaderLength()), -1);
+
+ mb->copy((char*) header.header, header.getHeaderLength());
- ACE_NEW_RETURN (npct, WorldPacket (pct), -1);
+ if (!pct.empty ())
+ mb->copy((const char*)pct.contents(), pct.size ());
- // NOTE maybe check of the size of the queue can be good ?
- // to make it bounded instead of unbounded
- if (m_PacketQueue.enqueue_tail (npct) == -1)
+ if(msg_queue()->enqueue_tail(mb,(ACE_Time_Value*)&ACE_Time_Value::zero) == -1)
{
- delete npct;
- sLog.outError ("WorldSocket::SendPacket: m_PacketQueue.enqueue_tail failed");
+ sLog.outError("WorldSocket::SendPacket enqueue_tail");
+ mb->release();
return -1;
}
}
@@ -296,7 +341,7 @@ int WorldSocket::handle_output (ACE_HANDLE)
const size_t send_len = m_OutBuffer->length ();
if (send_len == 0)
- return cancel_wakeup_output (Guard);
+ return handle_output_queue (Guard);
#ifdef MSG_NOSIGNAL
ssize_t n = peer ().send (m_OutBuffer->rd_ptr (), send_len, MSG_NOSIGNAL);
@@ -326,15 +371,73 @@ int WorldSocket::handle_output (ACE_HANDLE)
{
m_OutBuffer->reset ();
- if (!iFlushPacketQueue ())
- return cancel_wakeup_output (Guard);
- else
- return schedule_wakeup_output (Guard);
+ return handle_output_queue (Guard);
}
ACE_NOTREACHED (return 0);
}
+int WorldSocket::handle_output_queue (GuardType& g)
+{
+ if(msg_queue()->is_empty())
+ return cancel_wakeup_output(g);
+
+ ACE_Message_Block *mblk;
+
+ if(msg_queue()->dequeue_head(mblk, (ACE_Time_Value*)&ACE_Time_Value::zero) == -1)
+ {
+ sLog.outError("WorldSocket::handle_output_queue dequeue_head");
+ return -1;
+ }
+
+ const size_t send_len = mblk->length ();
+
+#ifdef MSG_NOSIGNAL
+ ssize_t n = peer ().send (mblk->rd_ptr (), send_len, MSG_NOSIGNAL);
+#else
+ ssize_t n = peer ().send (mblk->rd_ptr (), send_len);
+#endif // MSG_NOSIGNAL
+
+ if (n == 0)
+ {
+ mblk->release();
+
+ return -1;
+ }
+ else if (n == -1)
+ {
+ if (errno == EWOULDBLOCK || errno == EAGAIN)
+ {
+ msg_queue()->enqueue_head(mblk, (ACE_Time_Value*) &ACE_Time_Value::zero);
+ return schedule_wakeup_output (g);
+ }
+
+ mblk->release();
+ return -1;
+ }
+ else if (n < send_len) //now n > 0
+ {
+ mblk->rd_ptr (static_cast<size_t> (n));
+
+ if (msg_queue()->enqueue_head(mblk, (ACE_Time_Value*) &ACE_Time_Value::zero) == -1)
+ {
+ sLog.outError("WorldSocket::handle_output_queue enqueue_head");
+ mblk->release();
+ return -1;
+ }
+
+ return schedule_wakeup_output (g);
+ }
+ else //now n == send_len
+ {
+ mblk->release();
+
+ return msg_queue()->is_empty() ? cancel_wakeup_output(g) : ACE_Event_Handler::WRITE_MASK;
+ }
+
+ ACE_NOTREACHED(return -1);
+}
+
int WorldSocket::handle_close (ACE_HANDLE h, ACE_Reactor_Mask)
{
// Critical section
@@ -362,10 +465,15 @@ int WorldSocket::Update (void)
if (closing_)
return -1;
- if (m_OutActive || m_OutBuffer->length () == 0)
+ if (m_OutActive || (m_OutBuffer->length () == 0 && msg_queue()->is_empty()))
return 0;
- return handle_output (get_handle ());
+ int ret;
+ do
+ ret = handle_output (get_handle ());
+ while( ret > 0 );
+
+ return ret;
}
int WorldSocket::handle_input_header (void)
@@ -639,7 +747,7 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
// NOTE: ATM the socket is singlethread, have this in mind ...
uint8 digest[20];
uint32 clientSeed;
- uint32 unk2;
+ uint32 unk2, unk3;
uint32 BuiltNumberClient;
uint32 id, security;
//uint8 expansion = 0;
@@ -661,6 +769,7 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
recvPacket >> BuiltNumberClient; // for now no use
recvPacket >> unk2;
recvPacket >> account;
+ recvPacket >> unk3;
if (recvPacket.size () < (4 + 4 + (account.size () + 1) + 4 + 20))
{
@@ -684,17 +793,17 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
QueryResult *result =
LoginDatabase.PQuery ("SELECT "
- "id, " //0
- "gmlevel, " //1
- "sessionkey, " //2
- "last_ip, " //3
- "locked, " //4
- "sha_pass_hash, " //5
- "v, " //6
- "s, " //7
- "expansion, " //8
- "mutetime, " //9
- "locale " //10
+ "id, " //0
+ "gmlevel, " //1
+ "sessionkey, " //2
+ "last_ip, " //3
+ "locked, " //4
+ "sha_pass_hash, " //5
+ "v, " //6
+ "s, " //7
+ "expansion, " //8
+ "mutetime, " //9
+ "locale " //10
"FROM account "
"WHERE username = '%s'",
safe_account.c_str ());
@@ -788,6 +897,9 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
id = fields[0].GetUInt32 ();
security = fields[1].GetUInt16 ();
+ if(security > SEC_ADMINISTRATOR) // prevent invalid security settings in DB
+ security = SEC_ADMINISTRATOR;
+
K.SetHexStr (fields[2].GetString ());
time_t mutetime = time_t (fields[9].GetUInt64 ());
@@ -880,6 +992,8 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
m_Crypt.SetKey (&K);
m_Crypt.Init ();
+ m_Session->LoadAccountData();
+
// In case needed sometime the second arg is in microseconds 1 000 000 = 1 sec
ACE_OS::sleep (ACE_Time_Value (0, 10000));
@@ -961,25 +1075,19 @@ int WorldSocket::HandlePing (WorldPacket& recvPacket)
return SendPacket (packet);
}
-int WorldSocket::iSendPacket (const WorldPacket& pct)
+/*int WorldSocket::iSendPacket (const WorldPacket& pct)
{
- if (m_OutBuffer->space () < pct.size () + sizeof (ServerPktHeader))
+ ServerPktHeader header(pct.size()+2, pct.GetOpcode());
+ if (m_OutBuffer->space () < pct.size () + header.getHeaderLength())
{
errno = ENOBUFS;
return -1;
}
- ServerPktHeader header;
- header.cmd = pct.GetOpcode ();
- EndianConvert(header.cmd);
+ m_Crypt.EncryptSend ( header.header, header.getHeaderLength());
- header.size = (uint16) pct.size () + 2;
- EndianConvertReverse(header.size);
-
- m_Crypt.EncryptSend ((uint8*) & header, sizeof (header));
-
- if (m_OutBuffer->copy ((char*) & header, sizeof (header)) == -1)
+ if (m_OutBuffer->copy ((char*) header.header, header.getHeaderLength()) == -1)
ACE_ASSERT (false);
if (!pct.empty ())
@@ -1015,4 +1123,4 @@ bool WorldSocket::iFlushPacketQueue ()
}
return haveone;
-}
+}*/
diff --git a/src/game/WorldSocket.h b/src/game/WorldSocket.h
index fc564b6553a..15d3ec31e06 100644
--- a/src/game/WorldSocket.h
+++ b/src/game/WorldSocket.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -103,9 +103,6 @@ class WorldSocket : protected WorldHandler
typedef ACE_Thread_Mutex LockType;
typedef ACE_Guard<LockType> GuardType;
- /// Queue for storing packets for which there is no space.
- typedef ACE_Unbounded_Queue< WorldPacket* > PacketQueueT;
-
/// Check if socket is closed.
bool IsClosed (void) const;
@@ -161,6 +158,9 @@ class WorldSocket : protected WorldHandler
int cancel_wakeup_output (GuardType& g);
int schedule_wakeup_output (GuardType& g);
+ /// Drain the queue if its not empty.
+ int handle_output_queue (GuardType& g);
+
/// process one incoming packet.
/// @param new_pct received packet ,note that you need to delete it.
int ProcessIncoming (WorldPacket* new_pct);
@@ -171,16 +171,6 @@ class WorldSocket : protected WorldHandler
/// Called by ProcessIncoming() on CMSG_PING.
int HandlePing (WorldPacket& recvPacket);
- /// Try to write WorldPacket to m_OutBuffer ,return -1 if no space
- /// Need to be called with m_OutBufferLock lock held
- int iSendPacket (const WorldPacket& pct);
-
- /// Flush m_PacketQueue if there are packets in it
- /// Need to be called with m_OutBufferLock lock held
- /// @return true if it wrote to the buffer ( AKA you need
- /// to mark the socket for output ).
- bool iFlushPacketQueue ();
-
private:
/// Time in which the last ping was received
ACE_Time_Value m_LastPingTime;
@@ -220,10 +210,6 @@ class WorldSocket : protected WorldHandler
/// Size of the m_OutBuffer.
size_t m_OutBufferSize;
- /// Here are stored packets for which there was no space on m_OutBuffer,
- /// this allows not-to kick player if its buffer is overflowed.
- PacketQueueT m_PacketQueue;
-
/// True if the socket is registered with the reactor for output
bool m_OutActive;
diff --git a/src/game/WorldSocketMgr.cpp b/src/game/WorldSocketMgr.cpp
index baf8896f3f2..b6ea361f7e3 100644
--- a/src/game/WorldSocketMgr.cpp
+++ b/src/game/WorldSocketMgr.cpp
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2005-2008,2007 MaNGOS <http://getmangos.com/>
*
-* Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+* Copyright (C) 2008-2009 Trinity <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
diff --git a/src/game/WorldSocketMgr.h b/src/game/WorldSocketMgr.h
index fc009d69f80..d7cb627b11c 100644
--- a/src/game/WorldSocketMgr.h
+++ b/src/game/WorldSocketMgr.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/mangosd/CMakeLists.txt b/src/mangosd/CMakeLists.txt
new file mode 100644
index 00000000000..dc5941ef4e2
--- /dev/null
+++ b/src/mangosd/CMakeLists.txt
@@ -0,0 +1,53 @@
+
+########### next target ###############
+
+SET(trinity-core_SRCS
+CliRunnable.cpp
+CliRunnable.h
+Main.cpp
+Master.cpp
+Master.h
+RASocket.cpp
+RASocket.h
+WorldRunnable.cpp
+WorldRunnable.h
+)
+
+add_executable(trinity-core ${trinity-core_SRCS})
+add_definitions(
+-D_TRINITY_CORE_CONFIG='"${CONF_DIR}/trinitycore.conf"'
+)
+IF (DO_MYSQL)
+ SET_TARGET_PROPERTIES(trinity-core PROPERTIES LINK_FLAGS "-pthread")
+ENDIF(DO_MYSQL)
+
+
+
+target_link_libraries(
+trinity-core
+game
+shared
+zlib
+trinityframework
+trinitysockets
+trinitydatabase
+trinityauth
+trinityconfig
+vmaps
+ZThread
+g3dlite
+${SCRIPT_LIB}
+${MYSQL_LIBRARIES}
+${POSTGRE_LIBS}
+${SSLLIB}
+${ACE_LIBRARY}
+${ZLIB}
+)
+
+install(TARGETS trinity-core DESTINATION bin)
+
+
+########### install files ###############
+
+install(FILES mangosd.conf.dist.in DESTINATION etc)
+
diff --git a/src/mangosd/CliRunnable.cpp b/src/mangosd/CliRunnable.cpp
new file mode 100644
index 00000000000..f3bc640f9ff
--- /dev/null
+++ b/src/mangosd/CliRunnable.cpp
@@ -0,0 +1,366 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2009 Trinity <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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/// \addtogroup Trinityd
+/// @{
+/// \file
+
+#include "Common.h"
+#include "Language.h"
+#include "Log.h"
+#include "World.h"
+#include "ScriptCalls.h"
+#include "ObjectMgr.h"
+#include "WorldSession.h"
+#include "Config/ConfigEnv.h"
+#include "Util.h"
+#include "AccountMgr.h"
+#include "CliRunnable.h"
+#include "MapManager.h"
+#include "Player.h"
+#include "Chat.h"
+
+void utf8print(const char* str)
+{
+#if PLATFORM == PLATFORM_WINDOWS
+ wchar_t wtemp_buf[6000];
+ size_t wtemp_len = 6000-1;
+ if(!Utf8toWStr(str,strlen(str),wtemp_buf,wtemp_len))
+ return;
+
+ char temp_buf[6000];
+ CharToOemBuffW(&wtemp_buf[0],&temp_buf[0],wtemp_len+1);
+ printf(temp_buf);
+#else
+ printf(str);
+#endif
+}
+
+/// Delete a user account and all associated characters in this realm
+/// \todo This function has to be enhanced to respect the login/realm split (delete char, delete account chars in realm, delete account chars in realm then delete account
+bool ChatHandler::HandleAccountDeleteCommand(const char* args)
+{
+ if(!*args)
+ return false;
+
+ ///- Get the account name from the command line
+ char *account_name_str=strtok ((char*)args," ");
+ if (!account_name_str)
+ return false;
+
+ std::string account_name = account_name_str;
+ if(!AccountMgr::normilizeString(account_name))
+ {
+ PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 account_id = accmgr.GetId(account_name);
+ if(!account_id)
+ {
+ PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ /// Commands not recommended call from chat, but support anyway
+ /// can delete only for account with less security
+ /// This is also reject self apply in fact
+ if(HasLowerSecurityAccount (NULL,account_id,true))
+ return false;
+
+ AccountOpResult result = accmgr.DeleteAccount(account_id);
+ switch(result)
+ {
+ case AOR_OK:
+ PSendSysMessage(LANG_ACCOUNT_DELETED,account_name.c_str());
+ break;
+ case AOR_NAME_NOT_EXIST:
+ PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ case AOR_DB_INTERNAL_ERROR:
+ PSendSysMessage(LANG_ACCOUNT_NOT_DELETED_SQL_ERROR,account_name.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ default:
+ PSendSysMessage(LANG_ACCOUNT_NOT_DELETED,account_name.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ return true;
+}
+
+bool ChatHandler::HandleCharacterDeleteCommand(const char* args)
+{
+ if(!*args)
+ return false;
+
+ char *character_name_str = strtok((char*)args," ");
+ if(!character_name_str)
+ return false;
+
+ std::string character_name = character_name_str;
+ if(!normalizePlayerName(character_name))
+ return false;
+
+ uint64 character_guid;
+ uint32 account_id;
+
+ Player *player = objmgr.GetPlayer(character_name.c_str());
+ if(player)
+ {
+ character_guid = player->GetGUID();
+ account_id = player->GetSession()->GetAccountId();
+ player->GetSession()->KickPlayer();
+ }
+ else
+ {
+ character_guid = objmgr.GetPlayerGUIDByName(character_name);
+ if(!character_guid)
+ {
+ PSendSysMessage(LANG_NO_PLAYER,character_name.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ account_id = objmgr.GetPlayerAccountIdByGUID(character_guid);
+ }
+
+ std::string account_name;
+ accmgr.GetName (account_id,account_name);
+
+ Player::DeleteFromDB(character_guid, account_id, true);
+ PSendSysMessage(LANG_CHARACTER_DELETED,character_name.c_str(),GUID_LOPART(character_guid),account_name.c_str(), account_id);
+ return true;
+}
+
+/// Exit the realm
+bool ChatHandler::HandleServerExitCommand(const char* args)
+{
+ SendSysMessage(LANG_COMMAND_EXIT);
+ World::StopNow(SHUTDOWN_EXIT_CODE);
+ return true;
+}
+
+/// Display info on users currently in the realm
+bool ChatHandler::HandleAccountOnlineListCommand(const char* args)
+{
+ ///- Get the list of accounts ID logged to the realm
+ QueryResult *resultDB = CharacterDatabase.Query("SELECT name,account FROM characters WHERE online > 0");
+ if (!resultDB)
+ return true;
+
+ ///- Display the list of account/characters online
+ SendSysMessage("=====================================================================");
+ SendSysMessage(LANG_ACCOUNT_LIST_HEADER);
+ SendSysMessage("=====================================================================");
+
+ ///- Circle through accounts
+ do
+ {
+ Field *fieldsDB = resultDB->Fetch();
+ std::string name = fieldsDB[0].GetCppString();
+ uint32 account = fieldsDB[1].GetUInt32();
+
+ ///- Get the username, last IP and GM level of each account
+ // No SQL injection. account is uint32.
+ // 0 1 2 3
+ QueryResult *resultLogin = LoginDatabase.PQuery("SELECT username, last_ip, gmlevel, expansion FROM account WHERE id = '%u'",account);
+
+ if(resultLogin)
+ {
+ Field *fieldsLogin = resultLogin->Fetch();
+ PSendSysMessage("|%15s| %20s | %15s |%4d|%5d|",
+ fieldsLogin[0].GetString(),name.c_str(),fieldsLogin[1].GetString(),fieldsLogin[2].GetUInt32(),fieldsLogin[3].GetUInt32());
+
+ delete resultLogin;
+ }
+ else
+ PSendSysMessage(LANG_ACCOUNT_LIST_ERROR,name.c_str());
+
+ }while(resultDB->NextRow());
+
+ delete resultDB;
+
+ SendSysMessage("=====================================================================");
+ return true;
+}
+
+/// Create an account
+bool ChatHandler::HandleAccountCreateCommand(const char* args)
+{
+ if(!*args)
+ return false;
+
+ ///- %Parse the command line arguments
+ char *szAcc = strtok((char*)args, " ");
+ char *szPassword = strtok(NULL, " ");
+ if(!szAcc || !szPassword)
+ return false;
+
+ // normilized in accmgr.CreateAccount
+ std::string account_name = szAcc;
+ std::string password = szPassword;
+
+ AccountOpResult result = accmgr.CreateAccount(account_name, password);
+ switch(result)
+ {
+ case AOR_OK:
+ PSendSysMessage(LANG_ACCOUNT_CREATED,account_name.c_str());
+ break;
+ case AOR_NAME_TOO_LONG:
+ SendSysMessage(LANG_ACCOUNT_TOO_LONG);
+ SetSentErrorMessage(true);
+ return false;
+ case AOR_NAME_ALREDY_EXIST:
+ SendSysMessage(LANG_ACCOUNT_ALREADY_EXIST);
+ SetSentErrorMessage(true);
+ return false;
+ case AOR_DB_INTERNAL_ERROR:
+ PSendSysMessage(LANG_ACCOUNT_NOT_CREATED_SQL_ERROR,account_name.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ default:
+ PSendSysMessage(LANG_ACCOUNT_NOT_CREATED,account_name.c_str());
+ SetSentErrorMessage(true);
+ return false;
+ }
+
+ return true;
+}
+
+/// Set the level of logging
+bool ChatHandler::HandleServerSetLogLevelCommand(const char *args)
+{
+ if(!*args)
+ return false;
+
+ char *NewLevel = strtok((char*)args, " ");
+ if (!NewLevel)
+ return false;
+
+ sLog.SetLogLevel(NewLevel);
+ return true;
+}
+
+/// set diff time record interval
+bool ChatHandler::HandleServerSetDiffTimeCommand(const char *args)
+{
+ if(!*args)
+ return false;
+
+ char *NewTimeStr = strtok((char*)args, " ");
+ if(!NewTimeStr)
+ return false;
+
+ int32 NewTime =atoi(NewTimeStr);
+ if(NewTime < 0)
+ return false;
+
+ sWorld.SetRecordDiffInterval(NewTime);
+ printf( "Record diff every %u ms\n", NewTime);
+ return true;
+}
+
+
+/// @}
+
+#ifdef linux
+// Non-blocking keypress detector, when return pressed, return 1, else always return 0
+int kb_hit_return()
+{
+ struct timeval tv;
+ fd_set fds;
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ FD_ZERO(&fds);
+ FD_SET(STDIN_FILENO, &fds);
+ select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
+ return FD_ISSET(STDIN_FILENO, &fds);
+}
+#endif
+
+/// %Thread start
+void CliRunnable::run()
+{
+ ///- Init new SQL thread for the world database (one connection call enough)
+ WorldDatabase.ThreadStart(); // let thread do safe mySQL requests
+
+ char commandbuf[256];
+
+ ///- Display the list of available CLI functions then beep
+ sLog.outString();
+
+ if(sConfig.GetBoolDefault("BeepAtStart", true))
+ printf("\a"); // \a = Alert
+
+ // print this here the first time
+ // later it will be printed after command queue updates
+ printf("TC>");
+
+ ///- As long as the World is running (no World::m_stopEvent), get the command line and handle it
+ while (!World::IsStopped())
+ {
+ fflush(stdout);
+ #ifdef linux
+ while (!kb_hit_return() && !World::IsStopped())
+ // With this, we limit CLI to 10commands/second
+ usleep(100);
+ if (World::IsStopped())
+ break;
+ #endif
+ char *command_str = fgets(commandbuf,sizeof(commandbuf),stdin);
+ if (command_str != NULL)
+ {
+ for(int x=0;command_str[x];x++)
+ if(command_str[x]=='\r'||command_str[x]=='\n')
+ {
+ command_str[x]=0;
+ break;
+ }
+
+
+ if(!*command_str)
+ {
+ printf("TC>");
+ continue;
+ }
+
+ std::string command;
+ if(!consoleToUtf8(command_str,command)) // convert from console encoding to utf8
+ {
+ printf("TC>");
+ continue;
+ }
+
+ sWorld.QueueCliCommand(&utf8print,command.c_str());
+ }
+ else if (feof(stdin))
+ {
+ World::StopNow(SHUTDOWN_EXIT_CODE);
+ }
+ }
+
+ ///- End the database thread
+ WorldDatabase.ThreadEnd(); // free mySQL thread resources
+}
diff --git a/src/mangosd/CliRunnable.h b/src/mangosd/CliRunnable.h
new file mode 100644
index 00000000000..e5f78bb5259
--- /dev/null
+++ b/src/mangosd/CliRunnable.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2009 Trinity <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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/// \addtogroup Trinityd
+/// @{
+/// \file
+
+#ifndef __CLIRUNNABLE_H
+#define __CLIRUNNABLE_H
+
+/// Command Line Interface handling thread
+class CliRunnable : public ZThread::Runnable
+{
+ public:
+ void run();
+};
+#endif
+/// @}
diff --git a/src/mangosd/Main.cpp b/src/mangosd/Main.cpp
new file mode 100644
index 00000000000..68c467d6265
--- /dev/null
+++ b/src/mangosd/Main.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2009 Trinity <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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/// \addtogroup Trinityd Trinity Daemon
+/// @{
+/// \file
+
+#include "Common.h"
+#include "Database/DatabaseEnv.h"
+#include "Config/ConfigEnv.h"
+#include "Log.h"
+#include "Master.h"
+
+#ifndef _TRINITY_CORE_CONFIG
+# define _TRINITY_CORE_CONFIG "TrinityCore.conf"
+#endif //_TRINITY_CORE_CONFIG
+
+// Format is YYYYMMDDRR where RR is the change in the conf file
+// for that day.
+#ifndef _TRINITY_CORE_CONFVER
+# define _TRINITY_CORE_CONFVER 2008022901
+#endif //_TRINITY_CORE_CONFVER
+
+#ifdef WIN32
+#include "ServiceWin32.h"
+char serviceName[] = "TrinityCore";
+char serviceLongName[] = "Trinity core service";
+char serviceDescription[] = "Massive Network Game Object Server";
+/*
+ * -1 - not in service mode
+ * 0 - stopped
+ * 1 - running
+ * 2 - paused
+ */
+int m_ServiceStatus = -1;
+#endif
+
+DatabaseType WorldDatabase; ///< Accessor to the world database
+DatabaseType CharacterDatabase; ///< Accessor to the character database
+DatabaseType LoginDatabase; ///< Accessor to the realm/login database
+
+uint32 realmID; ///< Id of the realm
+
+/// Print out the usage string for this program on the console.
+void usage(const char *prog)
+{
+ sLog.outString("Usage: \n %s [<options>]\n"
+ " -c config_file use config_file as configuration file\n\r"
+ #ifdef WIN32
+ " Running as service functions:\n\r"
+ " --service run as service\n\r"
+ " -s install install service\n\r"
+ " -s uninstall uninstall service\n\r"
+ #endif
+ ,prog);
+}
+
+/// Launch the Trinity server
+extern int main(int argc, char **argv)
+{
+ ///- Command line parsing to get the configuration file name
+ char const* cfg_file = _TRINITY_CORE_CONFIG;
+ int c=1;
+ while( c < argc )
+ {
+ if( strcmp(argv[c],"-c") == 0)
+ {
+ if( ++c >= argc )
+ {
+ sLog.outError("Runtime-Error: -c option requires an input argument");
+ usage(argv[0]);
+ return 1;
+ }
+ else
+ cfg_file = argv[c];
+ }
+
+ #ifdef WIN32
+ ////////////
+ //Services//
+ ////////////
+ if( strcmp(argv[c],"-s") == 0)
+ {
+ if( ++c >= argc )
+ {
+ sLog.outError("Runtime-Error: -s option requires an input argument");
+ usage(argv[0]);
+ return 1;
+ }
+ if( strcmp(argv[c],"install") == 0)
+ {
+ if (WinServiceInstall())
+ sLog.outString("Installing service");
+ return 1;
+ }
+ else if( strcmp(argv[c],"uninstall") == 0)
+ {
+ if(WinServiceUninstall())
+ sLog.outString("Uninstalling service");
+ return 1;
+ }
+ else
+ {
+ sLog.outError("Runtime-Error: unsupported option %s",argv[c]);
+ usage(argv[0]);
+ return 1;
+ }
+ }
+ if( strcmp(argv[c],"--service") == 0)
+ {
+ WinServiceRun();
+ }
+ ////
+ #endif
+ ++c;
+ }
+
+ if (!sConfig.SetSource(cfg_file))
+ {
+ sLog.outError("Could not find configuration file %s.", cfg_file);
+ return 1;
+ }
+ sLog.outString("Using configuration file %s.", cfg_file);
+
+ uint32 confVersion = sConfig.GetIntDefault("ConfVersion", 0);
+ if (confVersion < _TRINITY_CORE_CONFVER)
+ {
+ sLog.outError("*****************************************************************************");
+ sLog.outError(" WARNING: Your trinitycore.conf version indicates your conf file is out of date!");
+ sLog.outError(" Please check for updates, as your current default values may cause");
+ sLog.outError(" strange behavior.");
+ sLog.outError("*****************************************************************************");
+ clock_t pause = 3000 + clock();
+
+ while (pause > clock()) {}
+ }
+
+ ///- and run the 'Master'
+ /// \todo Why do we need this 'Master'? Can't all of this be in the Main as for Realmd?
+ return sMaster.Run();
+
+ // at sMaster return function exist with codes
+ // 0 - normal shutdown
+ // 1 - shutdown at error
+ // 2 - restart command used, this code can be used by restarter for restart Trinityd
+}
+
+/// @}
diff --git a/src/mangosd/Makefile.am b/src/mangosd/Makefile.am
new file mode 100644
index 00000000000..7e1cd086d3c
--- /dev/null
+++ b/src/mangosd/Makefile.am
@@ -0,0 +1,62 @@
+# Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+#
+# Copyright (C) 2008-2009 Trinity <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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+## Process this file with automake to produce Makefile.in
+
+## CPP flags for includes, defines, etc.
+AM_CPPFLAGS = $(TRINI_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir)/../../dep/include -I$(srcdir)/../framework -I$(srcdir)/../shared -I$(srcdir)/../game -I$(srcdir) -DSYSCONFDIR=\"$(sysconfdir)/\"
+
+## Build world list daemon as standalone program
+bin_PROGRAMS = trinity-worldd
+trinity_worldd_SOURCES = \
+ CliRunnable.cpp \
+ CliRunnable.h \
+ Main.cpp \
+ Master.cpp \
+ Master.h \
+ RASocket.cpp \
+ RASocket.h \
+ WorldRunnable.cpp \
+ WorldRunnable.h
+
+## Link world daemon against the shared library
+trinity_worldd_LDADD = ../bindings/scripts/libtrinityscript.la ../game/libmangosgame.a ../shared/Database/libmangosdatabase.a ../shared/Config/libmangosconfig.a ../shared/Auth/libmangosauth.a ../shared/libmangosshared.a ../shared/vmap/libmangosvmaps.a ../framework/libmangosframework.a ../../dep/src/sockets/libmangossockets.a ../../dep/src/zthread/libZThread.la ../../dep/src/g3dlite/libg3dlite.a
+trinity_worldd_LDFLAGS = -L../../dep/src/sockets -L../../dep/src/zthread -L../../dep/src/g3dlite -L../bindings/scripts/ -L$(libdir) $(TRINI_LIBS) -export-dynamic
+
+## Additional files to include when running 'make dist'
+# Include world daemon configuration
+EXTRA_DIST = \
+ mangosd.conf.dist
+
+## Additional files to install
+sysconf_DATA = \
+ mangosd.conf.dist
+
+install-data-hook:
+ @list='$(sysconf_DATA)'; for p in $$list; do \
+ dest=`echo $$p | sed -e s/.dist//`; \
+ if test -f $(DESTDIR)$(sysconfdir)/$$dest; then \
+ echo "$@ will not overwrite existing $(DESTDIR)$(sysconfdir)/$$dest"; \
+ else \
+ echo " $(INSTALL_DATA) $$p $(DESTDIR)$(sysconfdir)/$$dest"; \
+ $(INSTALL_DATA) $$p $(DESTDIR)$(sysconfdir)/$$dest; \
+ fi; \
+ done
+
+clean-local:
+ rm -f $(sysconf_DATA)
diff --git a/src/mangosd/Master.cpp b/src/mangosd/Master.cpp
new file mode 100644
index 00000000000..f175d4d82b0
--- /dev/null
+++ b/src/mangosd/Master.cpp
@@ -0,0 +1,519 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2009 Trinity <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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/** \file
+ \ingroup Trinityd
+*/
+
+#include <ace/OS_NS_signal.h>
+
+#include "WorldSocketMgr.h"
+#include "Common.h"
+#include "Master.h"
+#include "WorldSocket.h"
+#include "WorldRunnable.h"
+#include "World.h"
+#include "Log.h"
+#include "Timer.h"
+#include "Policies/SingletonImp.h"
+#include "SystemConfig.h"
+#include "Config/ConfigEnv.h"
+#include "Database/DatabaseEnv.h"
+#include "CliRunnable.h"
+#include "RASocket.h"
+#include "ScriptCalls.h"
+#include "Util.h"
+
+#include "sockets/TcpSocket.h"
+#include "sockets/Utility.h"
+#include "sockets/Parse.h"
+#include "sockets/Socket.h"
+#include "sockets/SocketHandler.h"
+#include "sockets/ListenSocket.h"
+
+#ifdef WIN32
+#include "ServiceWin32.h"
+extern int m_ServiceStatus;
+#endif
+
+/// \todo Warning disabling not useful under VC++2005. Can somebody say on which compiler it is useful?
+#pragma warning(disable:4305)
+
+INSTANTIATE_SINGLETON_1( Master );
+
+volatile uint32 Master::m_masterLoopCounter = 0;
+
+class FreezeDetectorRunnable : public ZThread::Runnable
+{
+public:
+ FreezeDetectorRunnable() { _delaytime = 0; }
+ uint32 m_loops, m_lastchange;
+ uint32 w_loops, w_lastchange;
+ uint32 _delaytime;
+ void SetDelayTime(uint32 t) { _delaytime = t; }
+ void run(void)
+ {
+ if(!_delaytime)
+ return;
+ sLog.outString("Starting up anti-freeze thread (%u seconds max stuck time)...",_delaytime/1000);
+ m_loops = 0;
+ w_loops = 0;
+ m_lastchange = 0;
+ w_lastchange = 0;
+ while(!World::IsStopped())
+ {
+ ZThread::Thread::sleep(1000);
+ uint32 curtime = getMSTime();
+ //DEBUG_LOG("anti-freeze: time=%u, counters=[%u; %u]",curtime,Master::m_masterLoopCounter,World::m_worldLoopCounter);
+
+ // There is no Master anymore
+ // TODO: clear the rest of the code
+// // normal work
+// if(m_loops != Master::m_masterLoopCounter)
+// {
+// m_lastchange = curtime;
+// m_loops = Master::m_masterLoopCounter;
+// }
+// // possible freeze
+// else if(getMSTimeDiff(m_lastchange,curtime) > _delaytime)
+// {
+// sLog.outError("Main/Sockets Thread hangs, kicking out server!");
+// *((uint32 volatile*)NULL) = 0; // bang crash
+// }
+
+ // normal work
+ if(w_loops != World::m_worldLoopCounter)
+ {
+ w_lastchange = curtime;
+ w_loops = World::m_worldLoopCounter;
+ }
+ // possible freeze
+ else if(getMSTimeDiff(w_lastchange,curtime) > _delaytime)
+ {
+ sLog.outError("World Thread hangs, kicking out server!");
+ *((uint32 volatile*)NULL) = 0; // bang crash
+ }
+ }
+ sLog.outString("Anti-freeze thread exiting without problems.");
+ }
+};
+
+class RARunnable : public ZThread::Runnable
+{
+public:
+ uint32 numLoops, loopCounter;
+
+ RARunnable ()
+ {
+ uint32 socketSelecttime = sWorld.getConfig (CONFIG_SOCKET_SELECTTIME);
+ numLoops = (sConfig.GetIntDefault ("MaxPingTime", 30) * (MINUTE * 1000000 / socketSelecttime));
+ loopCounter = 0;
+ }
+
+ void
+ checkping ()
+ {
+ // ping if need
+ if ((++loopCounter) == numLoops)
+ {
+ loopCounter = 0;
+ sLog.outDetail ("Ping MySQL to keep connection alive");
+ delete WorldDatabase.Query ("SELECT 1 FROM command LIMIT 1");
+ delete LoginDatabase.Query ("SELECT 1 FROM realmlist LIMIT 1");
+ delete CharacterDatabase.Query ("SELECT 1 FROM bugreport LIMIT 1");
+ }
+ }
+
+ void
+ run (void)
+ {
+ SocketHandler h;
+
+ // Launch the RA listener socket
+ ListenSocket<RASocket> RAListenSocket (h);
+ bool usera = sConfig.GetBoolDefault ("Ra.Enable", false);
+
+ if (usera)
+ {
+ port_t raport = sConfig.GetIntDefault ("Ra.Port", 3443);
+ std::string stringip = sConfig.GetStringDefault ("Ra.IP", "0.0.0.0");
+ ipaddr_t raip;
+ if (!Utility::u2ip (stringip, raip))
+ sLog.outError ("Trinity RA can not bind to ip %s", stringip.c_str ());
+ else if (RAListenSocket.Bind (raip, raport))
+ sLog.outError ("Trinity RA can not bind to port %d on %s", raport, stringip.c_str ());
+ else
+ {
+ h.Add (&RAListenSocket);
+
+ sLog.outString ("Starting Remote access listner on port %d on %s", raport, stringip.c_str ());
+ }
+ }
+
+ // Socket Selet time is in microseconds , not miliseconds!!
+ uint32 socketSelecttime = sWorld.getConfig (CONFIG_SOCKET_SELECTTIME);
+
+ // if use ra spend time waiting for io, if not use ra ,just sleep
+ if (usera)
+ while (!World::IsStopped())
+ {
+ h.Select (0, socketSelecttime);
+ checkping ();
+ }
+ else
+ while (!World::IsStopped())
+ {
+ ZThread::Thread::sleep (static_cast<unsigned long> (socketSelecttime / 1000));
+ checkping ();
+ }
+ }
+};
+
+Master::Master()
+{
+}
+
+Master::~Master()
+{
+}
+
+/// Main function
+int Master::Run()
+{
+ sLog.outString( "%s (core-daemon)", _FULLVERSION );
+ sLog.outString( "<Ctrl-C> to stop.\n" );
+
+ sLog.outTitle( " ______ __");
+ sLog.outTitle( "/\\__ _\\ __ __/\\ \\__");
+ sLog.outTitle( "\\/_/\\ \\/ _ __ /\\_\\ ___ /\\_\\ \\ ,_\\ __ __");
+ sLog.outTitle( " \\ \\ \\/\\`'__\\/\\ \\ /' _ `\\/\\ \\ \\ \\/ /\\ \\/\\ \\");
+ sLog.outTitle( " \\ \\ \\ \\ \\/ \\ \\ \\/\\ \\/\\ \\ \\ \\ \\ \\_\\ \\ \\_\\ \\");
+ sLog.outTitle( " \\ \\_\\ \\_\\ \\ \\_\\ \\_\\ \\_\\ \\_\\ \\__\\\\/`____ \\");
+ sLog.outTitle( " \\/_/\\/_/ \\/_/\\/_/\\/_/\\/_/\\/__/ `/___/> \\");
+ sLog.outTitle( " C O R E /\\___/");
+ sLog.outTitle( "http://TrinityCore.org \\/__/\n");
+
+ /// worldd PID file creation
+ std::string pidfile = sConfig.GetStringDefault("PidFile", "");
+ if(!pidfile.empty())
+ {
+ uint32 pid = CreatePIDFile(pidfile);
+ if( !pid )
+ {
+ sLog.outError( "Cannot create PID file %s.\n", pidfile.c_str() );
+ return 1;
+ }
+
+ sLog.outString( "Daemon PID: %u\n", pid );
+ }
+
+ ///- Start the databases
+ if (!_StartDB())
+ return 1;
+
+ ///- Initialize the World
+ sWorld.SetInitialWorldSettings();
+
+ ///- Catch termination signals
+ _HookSignals();
+
+ ///- Launch WorldRunnable thread
+ ZThread::Thread t(new WorldRunnable);
+ t.setPriority ((ZThread::Priority )2);
+
+ // set server online
+ LoginDatabase.PExecute("UPDATE realmlist SET color = 0, population = 0 WHERE id = '%d'",realmID);
+
+#ifdef WIN32
+ if (sConfig.GetBoolDefault("Console.Enable", true) && (m_ServiceStatus == -1)/* need disable console in service mode*/)
+#else
+ if (sConfig.GetBoolDefault("Console.Enable", true))
+#endif
+ {
+ ///- Launch CliRunnable thread
+ ZThread::Thread td1(new CliRunnable);
+ }
+
+ ZThread::Thread td2(new RARunnable);
+
+ ///- Handle affinity for multiple processors and process priority on Windows
+ #ifdef WIN32
+ {
+ HANDLE hProcess = GetCurrentProcess();
+
+ uint32 Aff = sConfig.GetIntDefault("UseProcessors", 0);
+ if(Aff > 0)
+ {
+ ULONG_PTR appAff;
+ ULONG_PTR sysAff;
+
+ if(GetProcessAffinityMask(hProcess,&appAff,&sysAff))
+ {
+ ULONG_PTR curAff = Aff & appAff; // remove non accessible processors
+
+ if(!curAff )
+ {
+ sLog.outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for Trinityd. Accessible processors bitmask (hex): %x",Aff,appAff);
+ }
+ else
+ {
+ if(SetProcessAffinityMask(hProcess,curAff))
+ sLog.outString("Using processors (bitmask, hex): %x", curAff);
+ else
+ sLog.outError("Can't set used processors (hex): %x",curAff);
+ }
+ }
+ sLog.outString();
+ }
+
+ bool Prio = sConfig.GetBoolDefault("ProcessPriority", false);
+
+// if(Prio && (m_ServiceStatus == -1)/* need set to default process priority class in service mode*/)
+ if(Prio)
+ {
+ if(SetPriorityClass(hProcess,HIGH_PRIORITY_CLASS))
+ sLog.outString("TrinityCore process priority class set to HIGH");
+ else
+ sLog.outError("ERROR: Can't set Trinityd process priority class.");
+ sLog.outString();
+ }
+ }
+ #endif
+
+ uint32 realCurrTime, realPrevTime;
+ realCurrTime = realPrevTime = getMSTime();
+
+ uint32 socketSelecttime = sWorld.getConfig(CONFIG_SOCKET_SELECTTIME);
+
+ // maximum counter for next ping
+ uint32 numLoops = (sConfig.GetIntDefault( "MaxPingTime", 30 ) * (MINUTE * 1000000 / socketSelecttime));
+ uint32 loopCounter = 0;
+
+ ///- Start up freeze catcher thread
+ uint32 freeze_delay = sConfig.GetIntDefault("MaxCoreStuckTime", 0);
+ if(freeze_delay)
+ {
+ FreezeDetectorRunnable *fdr = new FreezeDetectorRunnable();
+ fdr->SetDelayTime(freeze_delay*1000);
+ ZThread::Thread t(fdr);
+ t.setPriority(ZThread::High);
+ }
+
+ ///- Launch the world listener socket
+ port_t wsport = sWorld.getConfig (CONFIG_PORT_WORLD);
+ std::string bind_ip = sConfig.GetStringDefault ("BindIP", "0.0.0.0");
+
+ if (sWorldSocketMgr->StartNetwork (wsport, bind_ip.c_str ()) == -1)
+ {
+ sLog.outError ("Failed to start network");
+ World::StopNow(ERROR_EXIT_CODE);
+ // go down and shutdown the server
+ }
+
+ sWorldSocketMgr->Wait ();
+
+ // set server offline
+ LoginDatabase.PExecute("UPDATE realmlist SET color = 2 WHERE id = '%d'",realmID);
+
+ ///- Remove signal handling before leaving
+ _UnhookSignals();
+
+ // when the main thread closes the singletons get unloaded
+ // since worldrunnable uses them, it will crash if unloaded after master
+ t.wait();
+ td2.wait ();
+
+ ///- Clean database before leaving
+ clearOnlineAccounts();
+
+ ///- Wait for delay threads to end
+ CharacterDatabase.HaltDelayThread();
+ WorldDatabase.HaltDelayThread();
+ LoginDatabase.HaltDelayThread();
+
+ sLog.outString( "Halting process..." );
+
+ #ifdef WIN32
+ if (sConfig.GetBoolDefault("Console.Enable", true))
+ {
+ // this only way to terminate CLI thread exist at Win32 (alt. way exist only in Windows Vista API)
+ //_exit(1);
+ // send keyboard input to safely unblock the CLI thread
+ INPUT_RECORD b[5];
+ HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
+ b[0].EventType = KEY_EVENT;
+ b[0].Event.KeyEvent.bKeyDown = TRUE;
+ b[0].Event.KeyEvent.uChar.AsciiChar = 'X';
+ b[0].Event.KeyEvent.wVirtualKeyCode = 'X';
+ b[0].Event.KeyEvent.wRepeatCount = 1;
+
+ b[1].EventType = KEY_EVENT;
+ b[1].Event.KeyEvent.bKeyDown = FALSE;
+ b[1].Event.KeyEvent.uChar.AsciiChar = 'X';
+ b[1].Event.KeyEvent.wVirtualKeyCode = 'X';
+ b[1].Event.KeyEvent.wRepeatCount = 1;
+
+ b[2].EventType = KEY_EVENT;
+ b[2].Event.KeyEvent.bKeyDown = TRUE;
+ b[2].Event.KeyEvent.dwControlKeyState = 0;
+ b[2].Event.KeyEvent.uChar.AsciiChar = '\r';
+ b[2].Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
+ b[2].Event.KeyEvent.wRepeatCount = 1;
+ b[2].Event.KeyEvent.wVirtualScanCode = 0x1c;
+
+ b[3].EventType = KEY_EVENT;
+ b[3].Event.KeyEvent.bKeyDown = FALSE;
+ b[3].Event.KeyEvent.dwControlKeyState = 0;
+ b[3].Event.KeyEvent.uChar.AsciiChar = '\r';
+ b[3].Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
+ b[3].Event.KeyEvent.wVirtualScanCode = 0x1c;
+ b[3].Event.KeyEvent.wRepeatCount = 1;
+ DWORD numb;
+ BOOL ret = WriteConsoleInput(hStdIn, b, 4, &numb);
+ }
+ #endif
+
+ // for some unknown reason, unloading scripts here and not in worldrunnable
+ // fixes a memory leak related to detaching threads from the module
+ UnloadScriptingModule();
+
+ // Exit the process with specified return value
+ return World::GetExitCode();
+}
+
+/// Initialize connection to the databases
+bool Master::_StartDB()
+{
+ ///- Get world database info from configuration file
+ std::string dbstring;
+ if(!sConfig.GetString("WorldDatabaseInfo", &dbstring))
+ {
+ sLog.outError("Database not specified in configuration file");
+ return false;
+ }
+ sLog.outString("World Database: %s", dbstring.c_str());
+
+ ///- Initialise the world database
+ if(!WorldDatabase.Initialize(dbstring.c_str()))
+ {
+ sLog.outError("Cannot connect to world database %s",dbstring.c_str());
+ return false;
+ }
+
+ if(!sConfig.GetString("CharacterDatabaseInfo", &dbstring))
+ {
+ sLog.outError("Character Database not specified in configuration file");
+ return false;
+ }
+ sLog.outString("Character Database: %s", dbstring.c_str());
+
+ ///- Initialise the Character database
+ if(!CharacterDatabase.Initialize(dbstring.c_str()))
+ {
+ sLog.outError("Cannot connect to Character database %s",dbstring.c_str());
+ return false;
+ }
+
+ ///- Get login database info from configuration file
+ if(!sConfig.GetString("LoginDatabaseInfo", &dbstring))
+ {
+ sLog.outError("Login database not specified in configuration file");
+ return false;
+ }
+
+ ///- Initialise the login database
+ sLog.outString("Login Database: %s", dbstring.c_str() );
+ if(!LoginDatabase.Initialize(dbstring.c_str()))
+ {
+ sLog.outError("Cannot connect to login database %s",dbstring.c_str());
+ return false;
+ }
+
+ ///- Get the realm Id from the configuration file
+ realmID = sConfig.GetIntDefault("RealmID", 0);
+ if(!realmID)
+ {
+ sLog.outError("Realm ID not defined in configuration file");
+ return false;
+ }
+ sLog.outString("Realm running as realm ID %d", realmID);
+
+ ///- Clean the database before starting
+ clearOnlineAccounts();
+
+ sWorld.LoadDBVersion();
+
+ sLog.outString("Using %s", sWorld.GetDBVersion());
+ return true;
+}
+
+/// Clear 'online' status for all accounts with characters in this realm
+void Master::clearOnlineAccounts()
+{
+ // Cleanup online status for characters hosted at current realm
+ /// \todo Only accounts with characters logged on *this* realm should have online status reset. Move the online column from 'account' to 'realmcharacters'?
+ LoginDatabase.PExecute(
+ "UPDATE account SET online = 0 WHERE online > 0 "
+ "AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = '%d')",realmID);
+
+ CharacterDatabase.Execute("UPDATE characters SET online = 0 WHERE online<>0");
+
+ // Battleground instance ids reset at server restart
+ CharacterDatabase.Execute("UPDATE characters SET bgid = 0 WHERE bgid<>0");
+}
+
+/// Handle termination signals
+void Master::_OnSignal(int s)
+{
+ switch (s)
+ {
+ case SIGINT:
+ World::StopNow(RESTART_EXIT_CODE);
+ break;
+ case SIGTERM:
+ #ifdef _WIN32
+ case SIGBREAK:
+ #endif
+ World::StopNow(SHUTDOWN_EXIT_CODE);
+ break;
+ }
+
+ signal(s, _OnSignal);
+}
+
+/// Define hook '_OnSignal' for all termination signals
+void Master::_HookSignals()
+{
+ signal(SIGINT, _OnSignal);
+ signal(SIGTERM, _OnSignal);
+ #ifdef _WIN32
+ signal(SIGBREAK, _OnSignal);
+ #endif
+}
+
+/// Unhook the signals before leaving
+void Master::_UnhookSignals()
+{
+ signal(SIGINT, 0);
+ signal(SIGTERM, 0);
+ #ifdef _WIN32
+ signal(SIGBREAK, 0);
+ #endif
+}
diff --git a/src/mangosd/Master.h b/src/mangosd/Master.h
new file mode 100644
index 00000000000..3b2b38f32f4
--- /dev/null
+++ b/src/mangosd/Master.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2009 Trinity <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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/// \addtogroup Trinityd
+/// @{
+/// \file
+
+#ifndef _MASTER_H
+#define _MASTER_H
+
+#include "Common.h"
+#include "Policies/Singleton.h"
+
+/// Start the server
+class Master
+{
+ public:
+ Master();
+ ~Master();
+ int Run();
+ static volatile uint32 m_masterLoopCounter;
+
+ private:
+ bool _StartDB();
+
+ void _HookSignals();
+ void _UnhookSignals();
+ static void _OnSignal(int s);
+
+ void clearOnlineAccounts();
+};
+
+#define sMaster Trinity::Singleton<Master>::Instance()
+#endif
+/// @}
diff --git a/src/mangosd/RASocket.cpp b/src/mangosd/RASocket.cpp
new file mode 100644
index 00000000000..a48928d5a23
--- /dev/null
+++ b/src/mangosd/RASocket.cpp
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2009 Trinity <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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/** \file
+ \ingroup Trinityd
+*/
+
+#include "Common.h"
+#include "Database/DatabaseEnv.h"
+#include "Log.h"
+#include "RASocket.h"
+#include "World.h"
+#include "Config/ConfigEnv.h"
+#include "Util.h"
+#include "AccountMgr.h"
+
+/// \todo Make this thread safe if in the future 2 admins should be able to log at the same time.
+SOCKET r;
+
+#define dropclient {Sendf("I'm busy right now, come back later."); \
+ SetCloseAndDelete(); \
+ return; \
+ }
+
+uint32 iSession=0; ///< Session number (incremented each time a new connection is made)
+unsigned int iUsers=0; ///< Number of active administrators
+
+typedef int(* pPrintf)(const char*,...);
+
+void ParseCommand(CliCommandHolder::Print*, char*command);
+
+/// RASocket constructor
+RASocket::RASocket(ISocketHandler &h): TcpSocket(h)
+{
+
+ ///- Increment the session number
+ iSess =iSession++ ;
+
+ ///- Get the config parameters
+ bSecure = sConfig.GetBoolDefault( "RA.Secure", true );
+ iMinLevel = sConfig.GetIntDefault( "RA.MinLevel", 3 );
+
+ ///- Initialize buffer and data
+ iInputLength=0;
+ buff=new char[RA_BUFF_SIZE];
+ stage=NONE;
+}
+
+/// RASocket destructor
+RASocket::~RASocket()
+{
+ ///- Delete buffer and decrease active admins count
+ delete [] buff;
+
+ sLog.outRALog("Connection was closed.\n");
+
+ if(stage==OK)
+ iUsers--;
+}
+
+/// Accept an incoming connection
+void RASocket::OnAccept()
+{
+ std::string ss=GetRemoteAddress();
+ sLog.outRALog("Incoming connection from %s.\n",ss.c_str());
+ ///- If there is already an active admin, drop the connection
+ if(iUsers)
+ dropclient
+
+ ///- Else print Motd
+ Sendf("%s\r\n",sWorld.GetMotd());
+}
+
+/// Read data from the network
+void RASocket::OnRead()
+{
+ ///- Read data and check input length
+ TcpSocket::OnRead();
+
+ unsigned int sz=ibuf.GetLength();
+ if(iInputLength+sz>=RA_BUFF_SIZE)
+ {
+ sLog.outRALog("Input buffer overflow, possible DOS attack.\n");
+ SetCloseAndDelete();
+ return;
+ }
+
+ ///- If there is already an active admin (other than you), drop the connection
+ if(stage!=OK && iUsers)
+ dropclient
+
+ char *inp = new char [sz+1];
+ ibuf.Read(inp,sz);
+
+ /// \todo Can somebody explain this 'Linux bugfix'?
+ if(stage==NONE)
+ if(sz>4) //linux remote telnet
+ if(memcmp(inp ,"USER ",5))
+ {
+ delete [] inp;return;
+ printf("lin bugfix");
+ } //linux bugfix
+
+ ///- Discard data after line break or line feed
+ bool gotenter=false;
+ unsigned int y=0;
+ for(;y<sz;y++)
+ if(inp[y]=='\r'||inp[y]=='\n')
+ {
+ gotenter=true;
+ break;
+ }
+
+ //No buffer overflow (checked above)
+ memcpy(&buff[iInputLength],inp,y);
+ iInputLength+=y;
+ delete [] inp;
+ if(gotenter)
+ {
+
+ buff[iInputLength]=0;
+ iInputLength=0;
+ switch(stage)
+ {
+ /// <ul> <li> If the input is 'USER <username>'
+ case NONE:
+ if(!memcmp(buff,"USER ",5)) //got "USER" cmd
+ {
+ szLogin=&buff[5];
+
+ ///- Get the gmlevel and password from the account table
+ std::string login = szLogin;
+
+ ///- Convert Account name to Upper Format
+ AccountMgr::normilizeString(login);
+
+ ///- Escape the Login to allow quotes in names
+ LoginDatabase.escape_string(login);
+
+ QueryResult* result = LoginDatabase.PQuery("SELECT gmlevel FROM account WHERE username = '%s'",login.c_str());
+
+ ///- If the user is not found, deny access
+ if(!result)
+ {
+ Sendf("-No such user.\r\n");
+ sLog.outRALog("User %s does not exist.\n",szLogin.c_str());
+ if(bSecure)SetCloseAndDelete();
+ }
+ else
+ {
+ Field *fields = result->Fetch();
+
+ //szPass=fields[0].GetString();
+
+ ///- if gmlevel is too low, deny access
+ if(fields[0].GetUInt32()<iMinLevel)
+ {
+ Sendf("-Not enough privileges.\r\n");
+ sLog.outRALog("User %s has no privilege.\n",szLogin.c_str());
+ if(bSecure)SetCloseAndDelete();
+ } else
+ {
+ stage=LG;
+ }
+ delete result;
+ }
+ }
+ break;
+ ///<li> If the input is 'PASS <password>' (and the user already gave his username)
+ case LG:
+ if(!memcmp(buff,"PASS ",5)) //got "PASS" cmd
+ { //login+pass ok
+ ///- If password is correct, increment the number of active administrators
+ std::string login = szLogin;
+ std::string pw = &buff[5];
+
+ AccountMgr::normilizeString(login);
+ AccountMgr::normilizeString(pw);
+ LoginDatabase.escape_string(login);
+ LoginDatabase.escape_string(pw);
+
+ QueryResult *check = LoginDatabase.PQuery(
+ "SELECT 1 FROM account WHERE username = '%s' AND sha_pass_hash=SHA1(CONCAT(username,':','%s'))",
+ login.c_str(), pw.c_str());
+
+ if(check)
+ {
+ delete check;
+ r=GetSocket();
+ stage=OK;
+ ++iUsers;
+
+ Sendf("+Logged in.\r\n");
+ sLog.outRALog("User %s has logged in.\n",szLogin.c_str());
+ Sendf("TC>");
+ }
+ else
+ {
+ ///- Else deny access
+ Sendf("-Wrong pass.\r\n");
+ sLog.outRALog("User %s has failed to log in.\n",szLogin.c_str());
+ if(bSecure)SetCloseAndDelete();
+ }
+ }
+ break;
+ ///<li> If user is logged, parse and execute the command
+ case OK:
+ if(strlen(buff))
+ {
+ sLog.outRALog("Got '%s' cmd.\n",buff);
+ sWorld.QueueCliCommand(&RASocket::zprint , buff);
+ }
+ else
+ Sendf("TC>");
+ break;
+ ///</ul>
+ };
+
+ }
+}
+
+/// Output function
+void RASocket::zprint( const char * szText )
+{
+ if( !szText )
+ return;
+
+ #ifdef RA_CRYPT
+
+ char *megabuffer=strdup(szText);
+ unsigned int sz=strlen(megabuffer);
+ Encrypt(megabuffer,sz);
+ send(r,megabuffer,sz,0);
+ delete [] megabuffer;
+
+ #else
+
+ unsigned int sz=strlen(szText);
+ send(r,szText,sz,0);
+
+ #endif
+}
diff --git a/src/trinitycore/RASocket.h b/src/mangosd/RASocket.h
index a164c9d3aa2..8900e689b2c 100644
--- a/src/trinitycore/RASocket.h
+++ b/src/mangosd/RASocket.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/trinitycore/TrinityCore.ico b/src/mangosd/TrinityCore.ico
index 6f0a5721957..6f0a5721957 100644
--- a/src/trinitycore/TrinityCore.ico
+++ b/src/mangosd/TrinityCore.ico
Binary files differ
diff --git a/src/mangosd/WorldRunnable.cpp b/src/mangosd/WorldRunnable.cpp
new file mode 100644
index 00000000000..0229f7f0f5c
--- /dev/null
+++ b/src/mangosd/WorldRunnable.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2009 Trinity <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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/** \file
+ \ingroup Trinityd
+*/
+
+#include "WorldSocketMgr.h"
+#include "Common.h"
+#include "World.h"
+#include "WorldRunnable.h"
+#include "Timer.h"
+#include "ObjectAccessor.h"
+#include "MapManager.h"
+#include "BattleGroundMgr.h"
+
+#include "Database/DatabaseEnv.h"
+
+#ifdef WIN32
+#define WORLD_SLEEP_CONST 50
+#else
+#define WORLD_SLEEP_CONST 100 //Is this still needed?? [On linux some time ago not working 50ms]
+#endif
+
+/// Heartbeat for the World
+void WorldRunnable::run()
+{
+ ///- Init new SQL thread for the world database
+ WorldDatabase.ThreadStart(); // let thread do safe mySQL requests (one connection call enough)
+ sWorld.InitResultQueue();
+
+ uint32 realCurrTime = 0;
+ uint32 realPrevTime = getMSTime();
+
+ uint32 prevSleepTime = 0; // used for balanced full tick time length near WORLD_SLEEP_CONST
+
+ ///- While we have not World::m_stopEvent, update the world
+ while (!World::IsStopped())
+ {
+ ++World::m_worldLoopCounter;
+ realCurrTime = getMSTime();
+
+ uint32 diff = getMSTimeDiff(realPrevTime,realCurrTime);
+
+ sWorld.Update( diff );
+ realPrevTime = realCurrTime;
+
+ // diff (D0) include time of previous sleep (d0) + tick time (t0)
+ // we want that next d1 + t1 == WORLD_SLEEP_CONST
+ // we can't know next t1 and then can use (t0 + d1) == WORLD_SLEEP_CONST requirement
+ // d1 = WORLD_SLEEP_CONST - t0 = WORLD_SLEEP_CONST - (D0 - d0) = WORLD_SLEEP_CONST + d0 - D0
+ if (diff <= WORLD_SLEEP_CONST+prevSleepTime)
+ {
+ prevSleepTime = WORLD_SLEEP_CONST+prevSleepTime-diff;
+ ZThread::Thread::sleep(prevSleepTime);
+ }
+ else
+ prevSleepTime = 0;
+ }
+
+ sWorld.KickAll(); // save and kick all players
+ sWorld.UpdateSessions( 1 ); // real players unload required UpdateSessions call
+
+ // unload battleground templates before different singletons destroyed
+ sBattleGroundMgr.DeleteAlllBattleGrounds();
+
+ sWorldSocketMgr->StopNetwork();
+
+ MapManager::Instance().UnloadAll(); // unload all grids (including locked in memory)
+
+ ///- End the database thread
+ WorldDatabase.ThreadEnd(); // free mySQL thread resources
+}
diff --git a/src/mangosd/WorldRunnable.h b/src/mangosd/WorldRunnable.h
new file mode 100644
index 00000000000..b967d0dac0b
--- /dev/null
+++ b/src/mangosd/WorldRunnable.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2009 Trinity <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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/// \addtogroup Trinityd
+/// @{
+/// \file
+
+#ifndef __WORLDRUNNABLE_H
+#define __WORLDRUNNABLE_H
+
+/// Heartbeat thread for the World
+class WorldRunnable : public ZThread::Runnable
+{
+ public:
+ void run();
+};
+#endif
+/// @}
diff --git a/src/mangosd/mangosd.conf.dist.in b/src/mangosd/mangosd.conf.dist.in
new file mode 100644
index 00000000000..516a6bc2a62
--- /dev/null
+++ b/src/mangosd/mangosd.conf.dist.in
@@ -0,0 +1,1448 @@
+##########################################
+# Trinity Core worldd configuration file #
+##########################################
+ConfVersion=2008080101
+
+###################################################################################################################
+# CONNECTIONS AND DIRECTORIES
+#
+# RealmID
+# RealmID must match the realmlist inside the realmd database
+#
+# DataDir
+# Data directory setting.
+# Important: DataDir needs to be quoted, as it is a string which may contain space characters.
+# Example: "@prefix@/share/trinitycore"
+#
+# LogsDir
+# Logs directory setting.
+# Important: Logs dir must exists, or all logs need to be disabled
+# Default: "" - no log directory prefix, if used log names isn't absolute path
+# then logs will be stored in current directory for run program.
+#
+#
+# LoginDatabaseInfo
+# WorldDatabaseInfo
+# CharacterDatabaseInfo
+# Database connection settings for the world server.
+# Default: hostname;port;username;password;database
+# .;somenumber;username;password;database - use named pipes at Windows
+# Named pipes: mySQL required adding "enable-named-pipe" to [mysqld] section my.ini
+# .;/path/to/unix_socket;username;password;database - use Unix sockets at Unix/Linux
+# Unix sockets: experimental, not tested
+#
+# MaxPingTime
+# Settings for maximum database-ping interval (minutes between pings)
+#
+# WorldServerPort
+# Default WorldServerPort
+#
+# BindIP
+# Bind World Server to IP/hostname
+#
+###################################################################################################################
+
+RealmID = 1
+DataDir = "."
+LogsDir = ""
+LoginDatabaseInfo = "127.0.0.1;3306;trinity;trinity;realmd"
+WorldDatabaseInfo = "127.0.0.1;3306;trinity;trinity;world"
+CharacterDatabaseInfo = "127.0.0.1;3306;trinity;trinity;characters"
+MaxPingTime = 30
+WorldServerPort = 8085
+BindIP = "0.0.0.0"
+
+###################################################################################################################
+# SCRIPTING SETTINGS
+#
+# Locale
+# Setting for current (DBC) locale to use
+#
+# EventAI Error reporting
+# 0 - Only startup (Default)
+# 1 - Startup errors and Runtime event errors
+# 2 - Startup errors, Runtime event errors, and Creation errors
+###################################################################################################################
+
+Locale = 0
+EAIErrorLevel = 2
+
+###################################################################################################################
+# PERFORMANCE SETINGS
+#
+# UseProcessors
+# Used processors mask for multi-processors system (Used only at Windows)
+# Default: 0 (selected by OS)
+# number (bitmask value of selected processors)
+#
+# ProcessPriority
+# Process priority setting (Used only at Windows)
+# Default: 1 (HIGH)
+# 0 (Normal)
+#
+# Compression
+# Compression level for update packages sent to client (1..9)
+# Default: 1 (speed)
+# 9 (best compression)
+#
+# PlayerLimit
+# Maximum number of players in the world. Excluding Mods, GM's and Admins
+# Default: 100
+# 0 (for infinite players)
+# -1 (for Mods, GM's and Admins only)
+# -2 (for GM's and Admins only)
+# -3 (for Admins only)
+#
+# SaveRespawnTimeImmediately
+# Save respawn time for creatures at death and for gameobjects at use/open
+# Default: 1 (save creature/gameobject respawn time without waiting grid unload)
+# 0 (save creature/gameobject respawn time at grid unload)
+#
+# MaxOverspeedPings
+# Maximum overspeed ping count before player kick (minimum is 2, 0 used for disable check)
+# Default: 2
+#
+# GridUnload
+# Unload grids (if you have lot memory you can disable it to speed up player move to new grids second time)
+# Default: 1 (unload grids)
+# 0 (do not unload grids)
+#
+# SocketSelectTime
+# Socket select time (in milliseconds)
+# Default: 10000
+#
+# GridCleanUpDelay
+# Grid clean up delay (in milliseconds)
+# Default: 300000 (5 min)
+#
+# MapUpdateInterval
+# Map update interval (in milliseconds)
+# Default: 100
+#
+# ChangeWeatherInterval
+# Weather update interval (in milliseconds)
+# Default: 600000 (10 min)
+#
+# PlayerSaveInterval
+# Player save interval (in milliseconds)
+# Default: 900000 (15 min)
+#
+# vmap.enableLOS
+# vmap.enableHeight
+# Enable/Disable VMmap support for line of sight and height calculation
+# Default: 1 (true)
+# 0 (false)
+#
+# vmap.ignoreMapIds
+# Map id that will be ignored by VMaps
+# List of ids with delimiter ','
+# If more then one id is defined and spaces are included, the string has to be enclosed by "
+# Example: "369,0,1,530"
+#
+# vmap.ignoreSpellIds
+# These spells are ignored for LoS calculation
+# List of ids with delimiter ','
+#
+# DetectPosCollision
+# Check final move position, summon position, etc for visible collision with other objects or
+# wall (wall only if vmaps are enabled)
+# Default: 1 (enable, required more CPU power usage)
+# 0 (disable, less nice position selection but will less CPU power usage)
+#
+# TargetPosRecalculateRange
+# Max distance from movement target point (+moving unit size) and targeted object (+size)
+# after that new target movmeent point calculated. Max: melee attack range (5), min: contact range (0.5)
+# More distance let have better performence, less distance let have more sensitive reaction at target move.
+# Default: 1.5
+#
+# UpdateUptimeInterval
+# Update realm uptime period in minutes (for save data in 'uptime' table). Must be > 0
+# Default: 10 (minutes)
+#
+# MaxCoreStuckTime
+# Periodically check if the process got freezed, if this is the case force crash after the specified
+# amount of seconds. Must be > 0. Recommended > 10 secs if you use this.
+# Default: 0 (Disabled)
+#
+# AddonChannel
+# Permit/disable the use of the addon channel through the server
+# (some client side addons can stop work correctly with disabled addon channel)
+# Default: 1 (permit addon channel)
+# 0 (do not permit addon channel)
+#
+###################################################################################################################
+
+UseProcessors = 0
+ProcessPriority = 1
+Compression = 1
+PlayerLimit = 100
+SaveRespawnTimeImmediately = 1
+MaxOverspeedPings = 2
+GridUnload = 1
+SocketSelectTime = 10000
+GridCleanUpDelay = 300000
+MapUpdateInterval = 100
+ChangeWeatherInterval = 600000
+PlayerSaveInterval = 900000
+vmap.enableLOS = 0
+vmap.enableHeight = 0
+vmap.ignoreMapIds = "369"
+vmap.ignoreSpellIds = "7720"
+DetectPosCollision = 1
+TargetPosRecalculateRange = 1.5
+UpdateUptimeInterval = 10
+MaxCoreStuckTime = 0
+AddonChannel = 1
+
+###################################################################################################################
+# SERVER LOGGING
+#
+# LogSQL
+# Enable logging of GM commands - all SQL code will be written to a log file
+# All commands are written to a file: YYYY-MM-DD_logSQL.sql
+# If a new day starts (00:00:00) then a new file is created - the old file will not be deleted.
+# Default: 1 - Write SQL code to logfile
+# 0 - Do not log
+#
+# PidFile
+# World daemon PID file
+# Default: "" - do not create PID file
+# "./worldd.pid" - create PID file (recommended name)
+#
+# LogLevel
+# Server console level of logging
+# 0 = Minimum; 1 = Basic&Error; 2 = Detail; 3 = Full/Debug
+# Default: 3
+#
+# LogTime
+# Include time in server console output [hh:mm:ss]
+# Default: 0 (no time)
+# 1 (print time)
+#
+# LogFile
+# Logfile name
+# Default: "Server.log"
+# "" - Empty name disable creating log file
+#
+# LogTimestamp
+# Logfile with timestamp of server start in name
+# Default: 0 - no timestamp in name
+# 1 - add timestamp in name in form Logname_YYYY-MM-DD_HH-MM-SS.Ext for Logname.Ext
+#
+# LogFileLevel
+# Server file level of logging
+# 0 = Minimum; 1 = Error; 2 = Detail; 3 = Full/Debug
+# Default: 0
+#
+# LogFilter_TransportMoves
+# LogFilter_CreatureMoves
+# LogFilter_VisibilityChanges
+# Log filters
+# Default: 1 - not include with any log level
+# 0 - include in log if log level permit
+#
+# WorldLogFile
+# Packet logging file for the worldserver
+# Default: "world.log"
+#
+# DBErrorLogFile
+# Log file of DB errors detected at server run
+# Default: "DBErrors.log"
+#
+# CharLogFile
+# Character operations logfile name
+# Default: "Char.log"
+# "" - Empty name disable creating log file
+#
+# CharLogTimestamp
+# Logfile with timestamp of server start in name
+# Default: 0 - no timestamp in name
+# 1 - add timestamp in name in form Logname_YYYY-MM-DD_HH-MM-SS.Ext for Logname.Ext
+#
+# CharLogDump
+# Write character dump before deleting in Char.log
+# For restoration, cut character data from log starting from
+# line == START DUMP == to line == END DUMP == (without its) in file and load it using loadpdump command
+# Default: 0 - don't include dumping chars to log
+# 1 - include dumping chars to log
+#
+# GmLogFile
+# Log file of gm commands
+# Default: "gm_commands.log"
+# "" - Empty name for disable
+#
+# GmLogTimestamp
+# GM Logfile with timestamp of server start in name
+# Default: 0 - no timestamp in name
+# 1 - add timestamp in name in form Logname_YYYY-MM-DD_HH-MM-SS.Ext for Logname.Ext
+#
+# GmLogPerAccount
+# GM Logfiles with GM account id (Note: logs not created if GmLogFile not set)
+# Default: 0 - add gm log data to single log file
+# 1 - add gm log data to account specific log files with name
+# in form Logname_#ID_YYYY-MM-DD_HH-MM-SS.Ext
+# or form Logname_#ID.Ext
+#
+# RaLogFile
+# Log file of RA commands
+# Default: "Ra.log"
+# "" - Empty name for disable
+#
+# LogColors
+# Color for messages (format "normal_color details_color debug_color error_color")
+# Colors: 0 - BLACK, 1 - RED, 2 - GREEN, 3 - BROWN, 4 - BLUE, 5 - MAGENTA, 6 - CYAN, 7 - GREY,
+# 8 - YELLOW, 9 - LRED, 10 - LGREEN, 11 - LBLUE, 12 - LMAGENTA, 13 - LCYAN, 14 - WHITE
+# Default: "" - none colors
+# Example: "13 7 11 9"
+#
+###################################################################################################################
+
+LogSQL = 1
+PidFile = ""
+LogLevel = 1
+LogTime = 0
+LogFile = "Server.log"
+LogTimestamp = 0
+LogFileLevel = 0
+LogFilter_TransportMoves = 1
+LogFilter_CreatureMoves = 1
+LogFilter_VisibilityChanges = 1
+WorldLogFile = ""
+DBErrorLogFile = "db_errors.log"
+CharLogFile = "characters.log"
+CharLogTimestamp = 0
+CharLogDump = 0
+GmLogFile = "gm_commands.log"
+GmLogTimestamp = 0
+GmLogPerAccount = 0
+RaLogFile = "ra_commands.log"
+LogColors = ""
+
+###################################################################################################################
+# SERVER SETTINGS
+#
+# GameType
+# Server realm style
+# 0 = NORMAL;1 = PVP; 4 = NORMAL; 6 = RP; 8 = RPPVP
+# also custom type: 16 FFA_PVP (free for all pvp mode like arena PvP in all zones except rest
+# activated places and sanctuaries)
+#
+# RealmZone
+# Server realm zone (set allowed alphabet in character names/etc). See also Strict*Names options.
+#
+# 1 Development - any language (Default)
+# 2 United States - extended-Latin
+# 3 Oceanic - extended-Latin
+# 4 Latin America - extended-Latin
+# 5 Tournament - basic-Latin at create, any at login
+# 6 Korea - East-Asian
+# 7 Tournament - basic-Latin at create, any at login
+# 8 English - extended-Latin
+# 9 German - extended-Latin
+# 10 French - extended-Latin
+# 11 Spanish - extended-Latin
+# 12 Russian - Cyrillic
+# 13 Tournament - basic-Latin at create, any at login
+# 14 Taiwan - East-Asian
+# 15 Tournament - basic-Latin at create, any at login
+# 16 China - East-Asian
+# 17 CN1 - basic-Latin at create, any at login
+# 18 CN2 - basic-Latin at create, any at login
+# 19 CN3 - basic-Latin at create, any at login
+# 20 CN4 - basic-Latin at create, any at login
+# 21 CN5 - basic-Latin at create, any at login
+# 22 CN6 - basic-Latin at create, any at login
+# 23 CN7 - basic-Latin at create, any at login
+# 24 CN8 - basic-Latin at create, any at login
+# 25 Tournament - basic-Latin at create, any at login
+# 26 Test Server - any language
+# 27 Tournament - basic-Latin at create, any at login
+# 28 QA Server - any language
+# 29 CN9 - basic-Latin at create, any at login
+#
+# Expansion
+# Allow server use content from expansion
+# Default: 2 - check expansion 2 maps existence, and if client support expansion 2 and account have
+# expansion 2 setting then allow visit expansion 2 maps, allow create new class character)
+# 1 - check expansion 1 maps existence, and if client support expansion 1 and account have
+# expansion 1 setting then allow visit expansion 1 maps, allow create new races character)
+# 0 - not check expansion maps existence, not allow wisit its, not allow create new race or new class
+# characters, ignore account expansion setting)
+#
+# DBC.Locale
+# DBC Language Settings
+# 0 = English; 1 = Korean; 2 = French; 3 = German; 4 = Chinese; 5 = Taiwanese; 6 = Spanish; 7 = Spanish Mexico
+# 8 = Russian; 255 = Auto Detect (Default)
+#
+# DeclinedNames
+# Allow russian clients to set and use declined names
+# Default: 0 - do not use declined names, except when the Russian RealmZone is set
+# 1 - use declined names
+#
+# StrictPlayerNames
+# Limit player name to language specific symbols set, not allow create characters, and set rename request and disconnect at not allowed symbols name
+# Default: 0 disable (but limited server timezone dependent client check)
+# 1 basic latin characters (strict)
+# 2 realm zone specific (strict). See RealmZone setting.
+# Note: In any case if you want correctly see character name at client this client must have apporopriate fonts
+# (included in client by default, with active official localization or custom localization fonts in clientdir/Fonts).
+# 3 basic latin characters + server timezone specific
+#
+# StrictCharterNames
+# Limit guild/arena team charter names to language specific symbols set, not allow create charters with allowed symbols in name
+# Default: 0 disable
+# 1 basic latin characters (strict)
+# 2 realm zone specific (strict). See RealmZone setting.
+# Note: In any case if you want correctly see character name at client this client must have apporopriate fonts
+# (included in client by default, with active official localization or custom localization fonts in clientdir/Fonts).
+# 3 basic latin characters + server timezone specific
+#
+# StrictPetNames
+# Limit pet names to language specific symbols set
+# Default: 0 disable
+# 1 basic latin characters (strict)
+# 2 realm zone specific (strict). See RealmZone setting.
+# Note: In any case if you want correctly see character name at client this client must have apporopriate fonts
+# (included in client by default, with active official localization or custom localization fonts in clientdir/Fonts).
+# 3 basic latin characters + server timezone specific
+#
+# CharactersCreatingDisabled
+# Disable characters creating for specific team or any (non-player accounts not affected)
+# Default: 0 - enabled
+# 1 - disabled only for Alliance
+# 2 - disabled only for Horde
+# 3 - disabled for both teams
+#
+# MaxWhoListReturns
+# Set the maximum number of players returned in the /who list and interface.
+# Default: 49 (stable)
+#
+# CharactersPerAccount
+# Limit numbers of characters per account (at all realms).
+# Note: this setting limit character creating at _current_ realm base at characters amount at all realms
+# Default: 50
+# The number must be >= CharactersPerRealm
+#
+# CharactersPerRealm
+# Limit numbers of characters for account at realm
+# Default: 10 (client limitation)
+# The number must be between 1 and 10
+#
+# HeroicCharactersPerRealm
+# Limit numbers of heroic class characters for account at realm
+# Default: 1
+# The number must be between 0 (not allowed) and 10
+#
+# MinLevelForHeroicCharacterCreating
+# Limit creating heroic characters only for account with another character of specific level (ignored for GM accounts)
+# 0 - not require any existed chaarcter
+# 1 - require at least any character existed
+# Default: 55 - default requirement
+#
+#
+# SkipCinematics
+# Disable in-game script movie at first character's login(allows to prevent buggy intro in case of custom start location coordinates)
+# Default: 0 - show intro for each new characrer
+# 1 - show intro only for first character of selected race
+# 2 - disable intro show in all cases
+#
+# MaxPlayerLevel
+# Max level that can be reached by player for experience (in range from 1 to 100).
+# Change not recommended
+# Default: 80
+#
+# StartPlayerLevel
+# Staring level that have character at creating (in range 1 to MaxPlayerLevel)
+# Default: 1
+#
+# StartHeroicPlayerLevel
+# Staring level that have character of heroic class at creating (in range 1 to MaxPlayerLevel)
+# Default: 55
+#
+# StartPlayerMoney
+# Amount of money that new players will start with.
+# If you want to start with silver, use for example 100 (100 copper = 1 silver)
+# Default: 0
+#
+# MaxHonorPoints
+# Max honor points that player can have.
+# Default: 75000
+#
+# StartHonorPoints
+# Amount of honor that new players will start with
+# Default: 0
+#
+# MaxArenaPoints
+# Max arena points that player can have.
+# Default: 5000
+#
+# StartArenaPoints
+# Amount of arena points that new players will start with
+# Default: 0
+#
+# InstantLogout
+# Enable or disable instant logout for security level (0..4) or high (NOT in combat/while dueling/while falling)
+# Default: 1 (Mods/GMs/Admins)
+#
+# DisableWaterBreath
+# Disable/enable waterbreathing for security level (0..4) or high
+# Default: 4 (None)
+#
+# AllFlightPaths
+# Players will start with all flight paths (Note: ALL flight paths, not only player's team)
+# Default: 0 (true)
+# 1 (false)
+#
+# AlwaysMaxSkillForLevel
+# Players will automatically gain max level dependent (weapon/defense) skill when logging in, leveling up etc.
+# Default: 0 (false)
+# 1 (true)
+#
+# ActivateWeather
+# Activate weather system
+# Default: 1 (true)
+# 0 (false)
+#
+# Battleground.CastDeserter
+# Cast or not Deserter spell at player who leave battleground in progress
+# Default: 1 (true)
+# 0 (false)
+#
+# Battleground.QueueAnnouncer.Enable
+# Enable queue announcer posting to chat
+# Default: 0 (false)
+# 1 (true)
+#
+# Battleground.QueueAnnouncer.PlayerOnly
+# Enable queue announcer posting to chat
+# Default: 0 (false)
+# 1 (true)
+#
+# Arena.QueueAnnouncer.Enable: Enable queue announcer posting to chat
+# Default: 0 (false)
+# 1 (true)
+#
+# CastUnstuck
+# Allow cast or not Unstuck spell at .start or client Help option use
+# Default: 1 (true)
+# 0 (false)
+#
+# Instance.IgnoreLevel
+# Ignore level requirement to enter instance
+# Default: 0 (false)
+# 1 (true)
+#
+# Instance.IgnoreRaid
+# Ignore raid requirement to enter instance
+# Default: 0 (false)
+# 1 (true)
+#
+# Instance.ResetTimeHour
+# The hour of the day (0-23) when the global instance resets occur.
+# Default: 4
+#
+# Instance.UnloadDelay
+# Unload the instance map from memory after some time if no players are inside.
+# Default: 1800000 (miliseconds, i.e 30 minutes)
+# 0 (instance maps are kept in memory until they are reset)
+#
+# Quests.LowLevelHideDiff
+# Quest level difference to hide for player low level quests:
+# if player_level > quest_level + LowLevelQuestsHideDiff then quest "!" mark not show for quest giver
+# Default: 4
+# -1 (show all available quests marks)
+#
+# Quests.HighLevelHideDiff
+# Quest level difference to hide for player high level quests:
+# if player_level < quest_min_level - HighLevelQuestsHideDiff then quest "!" mark not show for quest giver
+# Default: 7
+# -1 (show all available quests marks)
+#
+# MaxPrimaryTradeSkill
+# Max count that player can learn the primary trade skill.
+# Default: 2
+# Max : 10
+#
+# MinPetitionSigns
+# Min signatures count to creating guild (0..9).
+# Default: 9
+#
+# MaxGroupXPDistance
+# Max distance to creature for group memeber to get XP at creature death.
+# Default: 74
+#
+# MailDeliveryDelay
+# Mail delivery delay time for item sending
+# Default: 3600 sec (1 hour)
+#
+# SkillChance.Prospecting
+# For prospecting skillup impossible by default, but can be allowed as custom setting
+# Default: 0 - no skilups
+# 1 - skilups possible
+#
+# SkillChance.Milling
+# For milling skillup impossible by default, but can be allowed as custom setting
+# Default: 0 - no skilups
+# 1 - skilups possible
+#
+# Event.Announce
+# Default: 0 (false)
+# 1 (true)
+#
+# BeepAtStart
+# Beep at core start finished (mostly work only at Unix/Linux systems)
+# Default: 1 (true)
+# 0 (false)
+#
+# Motd
+# Message of the Day. Displayed at worldlogin for every user ('@' for a newline).
+#
+# Server.LoginInfo
+# Enable/disable sending server info (core version) on login.
+# Default: 0 - disable
+# 1 - enable
+#
+###################################################################################################################
+
+GameType = 1
+RealmZone = 1
+Expansion = 2
+DBC.Locale = 255
+DeclinedNames = 0
+StrictPlayerNames = 0
+StrictCharterNames = 0
+StrictPetNames = 0
+MaxWhoListReturns = 49
+CharactersCreatingDisabled = 0
+CharactersPerAccount = 50
+CharactersPerRealm = 10
+HeroicCharactersPerRealm = 1
+MinLevelForHeroicCharacterCreating = 55
+SkipCinematics = 0
+MaxPlayerLevel = 80
+StartPlayerLevel = 1
+StartHeroicPlayerLevel = 55
+StartPlayerMoney = 0
+MaxHonorPoints = 75000
+StartHonorPoints = 0
+MaxArenaPoints = 5000
+StartArenaPoints = 0
+InstantLogout = 1
+DisableWaterBreath = 4
+AllFlightPaths = 0
+AlwaysMaxSkillForLevel = 0
+ActivateWeather = 1
+Battleground.CastDeserter = 1
+Battleground.QueueAnnouncer.Enable = 0
+Battleground.QueueAnnouncer.PlayerOnly = 0
+Arena.QueueAnnouncer.Enable = 0
+CastUnstuck = 1
+Instance.IgnoreLevel = 0
+Instance.IgnoreRaid = 0
+Instance.ResetTimeHour = 4
+Instance.UnloadDelay = 1800000
+Quests.LowLevelHideDiff = 4
+Quests.HighLevelHideDiff = 7
+MaxPrimaryTradeSkill = 2
+MinPetitionSigns = 9
+MaxGroupXPDistance = 74
+MailDeliveryDelay = 3600
+SkillChance.Prospecting = 0
+SkillChance.Milling = 0
+Event.Announce = 0
+BeepAtStart = 1
+Motd = "Welcome to a Trinity Core server."
+Server.LoginInfo = 0
+
+###################################################################################################################
+# PLAYER INTERACTION
+#
+# AllowTwoSide.Accounts
+# Allow or not accounts to create characters in the 2 teams in any game type.
+# Default: 0 (Not allowed)
+# 1 (Allowed)
+#
+# AllowTwoSide.Interaction.Chat
+# AllowTwoSide.Interaction.Channel
+# AllowTwoSide.Interaction.Group
+# AllowTwoSide.Interaction.Guild
+# AllowTwoSide.Interaction.Auction
+# AllowTwoSide.Interaction.Mail
+# Allow or not common :chat(say,yell);channel(chat)group(join)guild(join);merge all auction houses for players from
+# different teams, send mail to different team.
+# Default: 0 (Not allowed)
+# 1 (Allowed)
+#
+# AllowTwoSide.WhoList
+# Allow or not show player from both team in who list.
+# Default: 0 (Not allowed)
+# 1 (Allowed)
+#
+# AllowTwoSide.AddFriend
+# Allow or not adding friends from other team in friend list.
+# Default: 0 (Not allowed)
+# 1 (Allowed)
+#
+# AllowTwoSide.Trade
+# Allow or not trading with other team in party.
+# Default: 0 (Not allowed)
+# 1 (Allowed)
+#
+# TalentsInspecting
+# Allow other players see character talents in inspect dialog (Characters in Gamemaster mode can
+# inspect talents always)
+# Default: 1 (allow)
+# 0 (not allow)
+#
+###################################################################################################################
+
+AllowTwoSide.Accounts = 0
+AllowTwoSide.Interaction.Chat = 0
+AllowTwoSide.Interaction.Channel = 0
+AllowTwoSide.Interaction.Group = 0
+AllowTwoSide.Interaction.Guild = 0
+AllowTwoSide.Interaction.Auction = 0
+AllowTwoSide.Interaction.Mail = 0
+AllowTwoSide.WhoList = 0
+AllowTwoSide.AddFriend = 0
+AllowTwoSide.Trade = 0
+TalentsInspecting = 1
+
+###################################################################################################################
+# CREATURE SETTINGS
+#
+# ThreatRadius
+# Radius for creature to evade after being pulled away from combat start point
+# If ThreatRadius is less than creature aggro radius then aggro radius will be used
+# Default: 60 yards
+#
+# Rate.Creature.Aggro
+# Aggro radius percent or off.
+# Default: 1 - 100%
+# 1.5 - 150%
+# 0 - off (0%)
+#
+# CreatureFamilyAssistanceRadius
+# Creature family assistance radius
+# Default: 10
+# 0 - off
+#
+# CreatureFamilyAssistanceDelay
+# Reaction time for creature assistance call
+# Default: 1500 (1.5s)
+#
+# WorldBossLevelDiff
+# Difference for boss dynamic level with target
+# Default: 3
+#
+# Corpse.Decay.NORMAL
+# Corpse.Decay.RARE
+# Corpse.Decay.ELITE
+# Corpse.Decay.RAREELITE
+# Corpse.Decay.WORLDBOSS
+# Seconds until creature corpse will decay without being looted or skinned.
+# Default: 60, 300, 300, 300, 3600
+#
+# Rate.Corpse.Decay.Looted
+# Controls how long the creature corpse stays after it had been looted, as a multiplier of its Corpse.Decay.* config.
+# Default: 0.5
+#
+# Rate.Creature.Normal.Damage
+# Rate.Creature.Elite.Elite.Damage
+# Rate.Creature.Elite.RAREELITE.Damage
+# Rate.Creature.Elite.WORLDBOSS.Damage
+# Rate.Creature.Elite.RARE.Damage
+# Creature Damage Rates.
+# Examples: 2 - creatures will damage 2x, 1.7 - 1.7x.
+#
+# Rate.Creature.Normal.SpellDamage
+# Rate.Creature.Elite.Elite.SpellDamage
+# Rate.Creature.Elite.RAREELITE.SpellDamage
+# Rate.Creature.Elite.WORLDBOSS.SpellDamag
+# Rate.Creature.Elite.RARE.SpellDamage
+# Creature Spell Damage Rates.
+# Examples: 2 - creatures will damage with spells 2x, 1.7 - 1.7x.
+#
+# Rate.Creature.Normal.HP
+# Rate.Creature.Elite.Elite.HP
+# Rate.Creature.Elite.RAREELITE.HP
+# Rate.Creature.Elite.WORLDBOSS.HP
+# Rate.Creature.Elite.RARE.HP
+# Creature Health Ammount Modifier.
+# Examples: 2 - creatures have 2x health, 1.7 - 1.7x.
+#
+# ListenRange.Say
+# Distance from player to listen text that creature (or other world object) say
+# Default: 25
+#
+# ListenRange.TextEmote
+# Distance from player to listen textemote that creature (or other world object) say
+# Default: 25
+#
+# ListenRange.Yell
+# Distance from player to listen text that creature (or other world object) yell
+# Default: 300
+#
+###################################################################################################################
+
+ThreatRadius = 60
+Rate.Creature.Aggro = 1
+CreatureFamilyAssistanceRadius = 10
+CreatureFamilyAssistanceDelay = 1500
+WorldBossLevelDiff = 3
+Corpse.Decay.NORMAL = 60
+Corpse.Decay.RARE = 300
+Corpse.Decay.ELITE = 300
+Corpse.Decay.RAREELITE = 300
+Corpse.Decay.WORLDBOSS = 3600
+Rate.Corpse.Decay.Looted = 0.5
+Rate.Creature.Normal.Damage = 1
+Rate.Creature.Elite.Elite.Damage = 1
+Rate.Creature.Elite.RAREELITE.Damage = 1
+Rate.Creature.Elite.WORLDBOSS.Damage = 1
+Rate.Creature.Elite.RARE.Damage = 1
+Rate.Creature.Normal.SpellDamage = 1
+Rate.Creature.Elite.Elite.SpellDamage = 1
+Rate.Creature.Elite.RAREELITE.SpellDamage = 1
+Rate.Creature.Elite.WORLDBOSS.SpellDamage = 1
+Rate.Creature.Elite.RARE.SpellDamage = 1
+Rate.Creature.Normal.HP = 1
+Rate.Creature.Elite.Elite.HP = 1
+Rate.Creature.Elite.RAREELITE.HP = 1
+Rate.Creature.Elite.WORLDBOSS.HP = 1
+Rate.Creature.Elite.RARE.HP = 1
+ListenRange.Say = 40
+ListenRange.TextEmote = 40
+ListenRange.Yell = 300
+
+###################################################################################################################
+# CHAT SETTINGS
+#
+# ChatFakeMessagePreventing
+# Chat protection from creating fake messages using a lot spaces (other invisible symbols),
+# not applied to addon language messages, but can prevent working old addons
+# that use normal languages for sending data to another clients.
+# Default: 0 (disible fake messages preventing)
+# 1 (enabled fake messages preventing)
+#
+# ChatFlood.MessageCount
+# Chat anti-flood protection, haste message count to activate protection
+# Default: 10
+# 0 (disible anti-flood protection)
+#
+# ChatFlood.MessageDelay
+# Chat anti-flood protection, minimum message delay to count message
+# Default: 1 (in secs)
+#
+# ChatFlood.MuteTime
+# Chat anti-flood protection, mute time at activation flood protection (not saved)
+# Default: 10 (in secs)
+#
+# Channel.RestrictedLfg
+# Restrict use LookupForGroup channel only registered in LFG tool players
+# Default: 1 (allow join to channel only if active in LFG)
+# 0 (allow join to channel in any time)
+#
+# Channel.SilentlyGMJoin
+# Silently join GM characters (security level > 1) to channels
+# Default: 0 (join announcement in normal way)
+# 1 (GM join without announcement)
+#
+###################################################################################################################
+
+ChatFakeMessagePreventing = 0
+ChatFlood.MessageCount = 10
+ChatFlood.MessageDelay = 1
+ChatFlood.MuteTime = 10
+Channel.RestrictedLfg = 1
+Channel.SilentlyGMJoin = 0
+
+###################################################################################################################
+# GAME MASTER SETTINGS
+#
+# GM.LoginState
+# GM mode at login
+# Default: 2 (last save state)
+# 0 (disable)
+# 1 (enable)
+#
+# GM.Visible
+# GM visibility at login
+# Default: 2 (last save state)
+# 0 (invisible)
+# 1 (visible)
+#
+# GM.AcceptTickets
+# Is GM accepting tickets from player by default or not.
+# Default: 2 (last save state)
+# 0 (disable)
+# 1 (enable)
+#
+# GM.Chat
+# GM chat mode at login
+# Default: 2 (last save state)
+# 0 (disable)
+# 1 (enable)
+#
+# GM.WhisperingTo
+# Is GM accepting whispers from player by default or not.
+# Default: 2 (last save state)
+# 0 (disable)
+# 1 (enable)
+#
+# GM.InGMList
+# Is GM showed in GM list (if visible) in non-GM state (.gmoff)
+# Default: 0 (false)
+# 1 (true)
+#
+# GM.InWhoList
+# Is GM showed in who list (if visible).
+# Default: 0 (false)
+# 1 (true)
+#
+# GM.LogTrade
+# Include GM trade and trade slot enchanting operations in GM log if it enable
+# Default: 1 (include)
+# 0 (not include)
+#
+# GM.StartLevel
+# GM starting level (1-100)
+# Default: 1
+#
+# GM.LowerSecurity
+# Disallow a lower security member to interact with a higher one using commands
+# Default: 0 (disable)
+# 1 (enable)
+#
+# GM.AllowAchievementGain
+# If enabled it allows gaining achievements for GM characters
+# Default: 0 (disable)
+# 1 (enable) (default)
+#
+###################################################################################################################
+
+GM.LoginState = 2
+GM.Visible = 2
+GM.AcceptTickets = 2
+GM.Chat = 2
+GM.WhisperingTo = 2
+GM.InGMList = 0
+GM.InWhoList = 0
+GM.LogTrade = 1
+GM.StartLevel = 80
+GM.LowerSecurity = 0
+GM.AllowAchievementGain = 1
+
+###################################################################################################################
+# VISIBILITY AND RADIUSES
+#
+# Visibility.GroupMode
+# Group visibility modes
+# Default: 0 (standard setting: only members from same group can 100% auto detect invisible player)
+# 1 (raid members 100% auto detect invisible player from same raid)
+# 2 (players from same team can 100% auto detect invisible player)
+#
+# Visibility.Distance.Creature
+# Visibility.Distance.Player
+# Visibility distance for different in game object
+# Max limited by active player zone: ~ 166
+# Min limit dependent from objects
+# Default: 66 (cell size)
+# Min limit is max aggro radius (45) * Rate.Creature.Aggro
+#
+# Visibility.Distance.Object
+# Visible distance for gameobject, dynobject, bodies, corpses, bones
+# Min limit is iteraction distance (5)
+#
+# Visibility.Distance.InFlight
+# Visible distance for player in flight
+# Min limit is 0 (not show any objects)
+#
+# Visibility.Distance.Grey.Unit
+# Visibility grey distance for creatures/players (fast changing objects)
+# addition to appropriate object type Visibility.Distance.* use in case visibility removing to
+# object (except corpse around distences) If D is distance and G is grey distance then object
+# make visible if distance to it <= D but make non visible if distance > D+G
+# Default: 1 (yard)
+#
+# Visibility.Distance.Grey.Object
+# Visibility grey distance for dynobjects/gameobjects/corpses/creature bodies
+# Default: 10 (yards)
+#
+#
+###################################################################################################################
+
+Visibility.GroupMode = 0
+Visibility.Distance.Creature = 66
+Visibility.Distance.Player = 66
+Visibility.Distance.Object = 66
+Visibility.Distance.InFlight = 66
+Visibility.Distance.Grey.Unit = 1
+Visibility.Distance.Grey.Object = 10
+
+###################################################################################################################
+# SERVER RATES
+#
+# Rate.Health
+# Rate.Mana
+# Rate.Rage.Income
+# Rate.Rage.Loss
+# Rate.RunicPower.Income
+# Rate.RunicPower.Loss
+# Rate.Focus
+# Rate.Loyalty
+# Health and power regeneration and rage income from damage.
+# Default: 1
+#
+# Rate.Skill.Discovery
+# Skill Discovery Rates
+# Default: 1
+#
+# Rate.Drop.Item.Poor
+# Rate.Drop.Item.Normal
+# Rate.Drop.Item.Uncommon
+# Rate.Drop.Item.Rare
+# Rate.Drop.Item.Epic
+# Rate.Drop.Item.Legendary
+# Rate.Drop.Item.Artifact
+# Rate.Drop.Item.Referenced
+# Rate.Drop.Money
+# Drop rates (items by quality and money)
+# Default: 1
+#
+# Rate.Drop.Money
+# Drop rates
+# Default: 1
+#
+# Rate.XP.Kill
+# Rate.XP.Quest
+# Rate.XP.Explore
+# XP rates
+# Default: 1
+#
+# Rate.XP.PastLevel70
+# XP needed per level past 70 (Rates below 1 not recommended)
+# Default: 1
+#
+# Rate.Rest.InGame
+# Rate.Rest.Offline.InTavernOrCity
+# Rate.Rest.Offline.InWilderness
+# Resting points grow rates (1 - normal, 2 - double rate, 0.5 - half rate, etc) from standard values
+#
+# Rate.Damage.Fall
+# Damage after fall rate. (1 - standard, 2 - double damage, 0.5 - half damage, etc)
+#
+# Rate.Auction.Time
+# Rate.Auction.Deposit
+# Rate.Auction.Cut
+# Auction rates (auction time, deposit get at auction start, auction cut from price at auction end)
+#
+# Rate.Honor
+# Honor gain rate
+#
+# Rate.Mining.Amount
+# Rate.Mining.Next
+# Mining Rates (Mining.Amount changes minimum/maximum usetimes of a deposit,
+# Mining.Next changes chance to have next use of a deposit)
+#
+# Rate.Talent
+# Talent Point rates
+# Default: 1
+#
+# Rate.Reputation.Gain
+# Reputation Gain rate
+# Default: 1
+#
+# Rate.InstanceResetTime
+# Multiplier for the number of days in between global raid/heroic instance resets.
+# Default: 1
+#
+# SkillGain.Crafting
+# SkillGain.Defense
+# SkillGain.Gathering
+# SkillGain.Weapon
+# crafting/defense/gathering/weapon skills gain at skill grow (1,2,...)
+# Default: 1
+#
+# SkillChance.Orange
+# SkillChance.Yellow
+# SkillChance.Green
+# SkillChance.Grey
+# Skill chance values (0..100)
+# Default: 100-75-25-0
+#
+# SkillChance.MiningSteps
+# SkillChance.SkinningSteps
+# For skinning and Mining chance decrease with skill level.
+# Default: 0 - no decrease
+# 75 - in 2 times each 75 skill points
+#
+# DurabilityLossChance.Damage
+# Chance lost one from equiped items durability point at damage apply or receive.
+# Default: 0.5 (100/0.5 = 200) Each 200 damage apply one from 19 possible equipped items
+#
+# DurabilityLossChance.Absorb
+# Chance lost one from armor items durability point at damage absorb.
+# Default: 0.5 (100/0.5 = 200) Each 200 absorbs apply one from 15 possible armor equipped items
+#
+# DurabilityLossChance.Parry
+# Chance lost weapon durability point at parry.
+# Default: 0.05 (100/0.05 = 2000) Each 2000 parry attacks main weapon lost point
+#
+# DurabilityLossChance.Block
+# Chance lost sheild durability point at damage block.
+# Default: 0.05 (100/0.05 = 2000) Each 2000 partly or full blocked attacks shield lost point
+#
+# Death.SicknessLevel
+# Starting Character start gain sickness at spirit resurrection (1 min)
+# Default: 11
+# -10 - character will have full time (10min) sickness at 1 level
+# maxplayerlevel+1 - chaarcter will not have sickess at any level
+#
+# Death.CorpseReclaimDelay.PvP
+# Death.CorpseReclaimDelay.PvE
+# Enabled/disabled increase corpse reclaim delay at often PvP/PvE deaths
+# Default: 1 (enabled)
+# 0 (disabled)
+#
+# Death.Bones.World
+# Death.Bones.BattlegroundOrArena
+# Enabled/disabled creating bones instead corpse at resurrection (in normal zones/instacnes, or battleground/arenas)
+# Default: 1 (enabled)
+# 0 (disabled)
+#
+###################################################################################################################
+
+Rate.Health = 1
+Rate.Mana = 1
+Rate.Rage.Income = 1
+Rate.Rage.Loss = 1
+Rate.RunicPower.Income = 1
+Rate.RunicPower.Loss = 1
+Rate.Focus = 1
+Rate.Loyalty = 1
+Rate.Skill.Discovery = 1
+Rate.Drop.Item.Poor = 1
+Rate.Drop.Item.Normal = 1
+Rate.Drop.Item.Uncommon = 1
+Rate.Drop.Item.Rare = 1
+Rate.Drop.Item.Epic = 1
+Rate.Drop.Item.Legendary = 1
+Rate.Drop.Item.Artifact = 1
+Rate.Drop.Item.Referenced = 1
+Rate.Drop.Money = 1
+Rate.XP.Kill = 1
+Rate.XP.Quest = 1
+Rate.XP.Explore = 1
+Rate.XP.PastLevel70 = 1
+Rate.Rest.InGame = 1
+Rate.Rest.Offline.InTavernOrCity = 1
+Rate.Rest.Offline.InWilderness = 1
+Rate.Damage.Fall = 1
+Rate.Auction.Time = 1
+Rate.Auction.Deposit = 1
+Rate.Auction.Cut = 1
+Rate.Honor = 1
+Rate.Mining.Amount = 1
+Rate.Mining.Next = 1
+Rate.Talent = 1
+Rate.Reputation.Gain = 1
+Rate.InstanceResetTime = 1
+SkillGain.Crafting = 1
+SkillGain.Defense = 1
+SkillGain.Gathering = 1
+SkillGain.Weapon = 1
+SkillChance.Orange = 100
+SkillChance.Yellow = 75
+SkillChance.Green = 25
+SkillChance.Grey = 0
+SkillChance.MiningSteps = 0
+SkillChance.SkinningSteps = 0
+DurabilityLossChance.Damage = 0.5
+DurabilityLossChance.Absorb = 0.5
+DurabilityLossChance.Parry = 0.05
+DurabilityLossChance.Block = 0.05
+Death.SicknessLevel = 11
+Death.CorpseReclaimDelay.PvP = 1
+Death.CorpseReclaimDelay.PvE = 0
+Death.Bones.World = 1
+Death.Bones.BattlegroundOrArena = 1
+
+###################################################################################################################
+#
+# Rated arena matches config
+#
+# MaxRatingDifference: the maximum rating difference between two groups in rated matches
+# Default: 0 (disable, rating difference is discarded)
+#
+# RatingDiscardTimer: after the specified milliseconds has passed,
+# rating information will be discarded when selecting teams for matches
+# also initiates an update by this timer
+# Default: 60000
+#
+# AutoDistributePoints: set if arena points should be distributed automatically, or by GM command
+# Default: 0 (disable) (recommended): use gm command or sql query to distribute the points
+# 1 (enable): arena points are distributed automatically
+#
+# AutoDistributeInterval: how often should the distribution take place
+# if automatic distribution is enabled
+# in days
+# Default: 7 (weekly)
+#
+# ArenaSeason.ID: current area season id show in client
+# Default: 1
+#
+# ArenaSeason.InProgress: current area season state
+# Default: 1 (active)
+# 0 (finished)
+#
+###################################################################################################################
+
+Arena.MaxRatingDifference = 0
+Arena.RatingDiscardTimer = 60000
+Arena.AutoDistributePoints = 0
+Arena.AutoDistributeInterval = 7
+Arena.ArenaSeason.ID = 1
+Arena.ArenaSeason.InProgress = 1
+
+###################################################################################################################
+#
+# Battleground config
+#
+# PrematureFinishTimer: the time to end the bg if there are less than minplayersperteam on one side
+# in milliseconds
+# Default: 300000
+# 0 - disable
+#
+###################################################################################################################
+
+BattleGround.PrematureFinishTimer = 300000
+
+
+###################################################################################################################
+#
+# NETWORK CONFIG
+#
+# Network.Threads
+# Number of threads for network, recommend 1 thread per 1000 connections.
+# Default: 1
+#
+# Network.OutKBuff
+# The size of the output kernel buffer used ( SO_SNDBUF socket option, tcp manual ).
+# Default: -1 (Use system default setting)
+#
+# Network.OutUBuff
+# Userspace buffer for output. This is amount of memory reserved per each connection.
+# Default: 65536
+#
+# Network.TcpNoDelay:
+# TCP Nagle algorithm setting
+# Default: 0 (enable Nagle algorithm, less traffic, more latency)
+# 1 (TCP_NO_DELAY, disable Nagle algorithm, more traffic but less latency)
+#
+###################################################################################################################
+
+Network.Threads = 1
+Network.OutKBuff = -1
+Network.OutUBuff = 65536
+Network.TcpNodelay = 1
+
+###################################################################################################################
+# AUCTION HOUSE BOT SETTINGS
+#
+# AuctionHouseBot.EnableSeller
+# Enable/Disable the part of AHBot that puts items up for auction
+# Default 0 (disabled)
+#
+# AuctionHouseBot.EnableBuyer
+# Enable/Disable the part of AHBot that buys items from players
+# Default 0 (disabled)
+#
+# Auction House Bot character data
+# AuctionHouseBot.Account is the account number (in realmd->account table) of the player you want to run as the auction bot.
+# AuctionHouseBot.GUID is the GUID (in characters->characters table) of the player you want to run as the auction bot.
+# Default: 0 (Auction House Bot disabled)
+#
+# AuctionHouseBot.VendorItems
+# Include items that can be bought from vendors.
+# Default 0
+#
+# AuctionHouseBot.LootItems
+# Include items that can be looted or fished for.
+# Default 1
+#
+# AuctionHouseBot.OtherItems
+# Include misc. items.
+# Default 0
+#
+# AuctionHouseBot.Bonding_types
+# Indicates which bonding types to allow seller to put up for auction
+# No_Bind
+# Default 1
+# Bind_When_Picked_Up
+# Default 0
+# Bind_When_Equipped
+# Default 1
+# Bind_When_Use
+# Default 1
+# Bind_Quest_Item
+# Default 0
+#
+# AuctionHouseBot.ItemsPerCycle
+# Number of Items to Add/Remove from the AH during mass operations
+# Default 200
+#
+# AuctionHouseBot.UseBuyPriceForSeller
+# Should the Seller use BuyPrice or SellPrice to determine Bid Prices
+# Default 0 (use SellPrice)
+#
+# AuctionHouseBot.UseBuyPriceForBuyer
+# Should the Buyer use BuyPrice or SellPrice to determine Bid Prices
+# Default 0 (use SellPrice)
+#
+# All other settings have been moved to sql
+#
+###################################################################################################################
+
+AuctionHouseBot.EnableSeller = 0
+AuctionHouseBot.EnableBuyer = 0
+AuctionHouseBot.Account = 0
+AuctionHouseBot.GUID = 0
+AuctionHouseBot.VendorItems = 0
+AuctionHouseBot.LootItems = 1
+AuctionHouseBot.OtherItems = 0
+AuctionHouseBot.No_Bind = 1
+AuctionHouseBot.Bind_When_Picked_Up = 0
+AuctionHouseBot.Bind_When_Equipped = 1
+AuctionHouseBot.Bind_When_Use = 1
+AuctionHouseBot.Bind_Quest_Item = 0
+AuctionHouseBot.ItemsPerCycle = 200
+AuctionHouseBot.UseBuyPriceForSeller = 0
+AuctionHouseBot.UseBuyPriceForBuyer = 0
+
+###################################################################################################################
+# CONSOLE AND REMOTE ACCESS
+#
+# Console.Enable
+# Enable console
+# Default: 1 - on
+# 0 - off
+#
+# Ra.Enable
+# Enable remote console
+# Default: 0 - off
+# 1 - on
+#
+# Ra.IP
+# Default remote console ip address, use 0.0.0.0 for every address
+#
+# Ra.Port
+# Default remote console port
+#
+# Ra.MinLevel
+# Minimum level that's required to login,3 by default
+#
+# Ra.Secure
+# Kick client on wrong pass
+#
+###################################################################################################################
+
+Console.Enable = 1
+Ra.Enable = 0
+Ra.IP = 0.0.0.0
+Ra.Port = 3443
+Ra.MinLevel = 3
+Ra.Secure = 1
+
+###################################################################################################################
+# CUSTOM SERVER OPTIONS
+#
+# PlayerStart.AllReputation
+# Players will start with most of the high level reputations that are needed for items, mounts etc.
+# If there are any reputation faction you want to be added, just tell me.
+#
+# PlayerStart.AllSpells
+# If enabled, players will start with all their class spells (not talents). Useful for instant 70 servers.
+# You must import playercreateinfo_spell_custom.sql, it's included in the SQL folder.
+# Default: 0 - off
+# 1 - on
+#
+# PlayerStart.MapsExplored
+# Players will start with all maps explored if enabled
+#
+# MusicInBattleground
+# If enabled, "L70ETC - Power of the horde" will be played when BG starts ;)
+#
+# HonorPointsAfterDuel
+# The amount of honor points the duel winner will get after a duel.
+# Default: 0 - disable
+#
+# AlwaysMaxWeaponSkill
+# Players will automatically gain max weapon/defense skill when logging in, leveling up etc.
+#
+# PvPToken.Enable
+# Enable/disable PvP Token System. Players will get a token after slaying another player that gives honor.
+#
+# PvPToken.MapAllowType
+# Where players can receive the pvp token
+# 4 - In all maps
+# 3 - In battlegrounds only
+# 2 - In FFA areas only (gurubashi arena etc)
+# 1 - In battlegrounds AND FFA areas only
+#
+# PvPToken.ItemID
+# The item players will get after killing someone if PvP Token system is enabled.
+# Default: 29434 - Badge of justice
+#
+# PvPToken.ItemCount
+# Modify the item ID count - Default: 1
+#
+# NoResetTalentsCost
+# Enable or disable no cost when reseting talents
+#
+# ForbiddenMaps
+# map ids that users below SEC_GAMEMASTER cannot enter, with delimiter ','
+# Default: ""
+# example: "538,90"
+# Note that it's HIGHLY DISCOURAGED to forbid starting maps (0, 1, 530)!
+#
+# ShowKickInWorld
+# determines wether a message is broadcasted to the entire server when a player gets kicked
+# Default: 0
+# 1 = Enable
+# 0 = Disable
+#
+# RecordUpdateTimeDiffInterval
+# record update time diff to the log file
+# update diff can be used as a criterion of performance
+# diff < 300: good performance
+# diff > 600: bad performance, may be caused by high cpu usage
+# Default: 60000 (diff is written into log every 60000 ms or 1 minute.
+# >0 = Interval
+# 0 = Disable
+#
+# MinRecordUpdateTimeDiff
+# only record update time diff which is greater than this value
+#
+# PlayerStart.String
+# If set to anything else than "", this string will be displayed to players when they login
+# to a newly created character.
+# Default: "" - send no text
+#
+###################################################################################################################
+
+PlayerStart.AllReputation = 0
+PlayerStart.AllSpells = 0
+PlayerStart.MapsExplored = 0
+MusicInBattleground = 0
+HonorPointsAfterDuel = 0
+AlwaysMaxWeaponSkill = 0
+PvPToken.Enable = 0
+PvPToken.MapAllowType = 4
+PvPToken.ItemID = 29434
+PvPToken.ItemCount = 1
+NoResetTalentsCost = 0
+ShowKickInWorld = 0
+RecordUpdateTimeDiffInterval = 60000
+MinRecordUpdateTimeDiff = 10
+PlayerStart.String = ""
diff --git a/src/trinitycore/TrinityCore.rc b/src/mangosd/mangosd.rc
index 4e6510c0407..0acad1e4ba2 100644
--- a/src/trinitycore/TrinityCore.rc
+++ b/src/mangosd/mangosd.rc
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.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
diff --git a/src/trinitycore/monitor-mangosd b/src/mangosd/monitor-mangosd
index a740ae5e8fa..a740ae5e8fa 100644
--- a/src/trinitycore/monitor-mangosd
+++ b/src/mangosd/monitor-mangosd
diff --git a/src/mangosd/resource.h b/src/mangosd/resource.h
new file mode 100644
index 00000000000..7e7d8e4b76f
--- /dev/null
+++ b/src/mangosd/resource.h
@@ -0,0 +1,15 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by TrinityCore.rc
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/src/trinitycore/run-mangosd b/src/mangosd/run-mangosd
index f307bd9e1ad..f307bd9e1ad 100644
--- a/src/trinitycore/run-mangosd
+++ b/src/mangosd/run-mangosd
diff --git a/src/realmd/AuthCodes.h b/src/realmd/AuthCodes.h
new file mode 100644
index 00000000000..3745c6c6214
--- /dev/null
+++ b/src/realmd/AuthCodes.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2009 Trinity <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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/** \file
+ \ingroup realmd
+*/
+
+#ifndef _AUTHCODES_H
+#define _AUTHCODES_H
+
+enum eAuthResults
+{
+ REALM_AUTH_SUCCESS = 0x00,
+ REALM_AUTH_FAILURE = 0x01, ///< Unable to connect
+ REALM_AUTH_UNKNOWN1 = 0x02, ///< Unable to connect
+ REALM_AUTH_ACCOUNT_BANNED = 0x03, ///< This <game> account has been closed and is no longer available for use. Please go to <site>/banned.html for further information.
+ REALM_AUTH_NO_MATCH = 0x04, ///< The information you have entered is not valid. Please check the spelling of the account name and password. If you need help in retrieving a lost or stolen password, see <site> for more information
+ REALM_AUTH_UNKNOWN2 = 0x05, ///< The information you have entered is not valid. Please check the spelling of the account name and password. If you need help in retrieving a lost or stolen password, see <site> for more information
+ REALM_AUTH_ACCOUNT_IN_USE = 0x06, ///< This account is already logged into <game>. Please check the spelling and try again.
+ REALM_AUTH_PREPAID_TIME_LIMIT = 0x07, ///< You have used up your prepaid time for this account. Please purchase more to continue playing
+ REALM_AUTH_SERVER_FULL = 0x08, ///< Could not log in to <game> at this time. Please try again later.
+ REALM_AUTH_WRONG_BUILD_NUMBER = 0x09, ///< Unable to validate game version. This may be caused by file corruption or interference of another program. Please visit <site> for more information and possible solutions to this issue.
+ REALM_AUTH_UPDATE_CLIENT = 0x0a, ///< Downloading
+ REALM_AUTH_UNKNOWN3 = 0x0b, ///< Unable to connect
+ REALM_AUTH_ACCOUNT_FREEZED = 0x0c, ///< This <game> account has been temporarily suspended. Please go to <site>/banned.html for further information
+ REALM_AUTH_UNKNOWN4 = 0x0d, ///< Unable to connect
+ REALM_AUTH_UNKNOWN5 = 0x0e, ///< Connected.
+ REALM_AUTH_PARENTAL_CONTROL = 0x0f ///< Access to this account has been blocked by parental controls. Your settings may be changed in your account preferences at <site>
+};
+
+enum LoginResult
+{
+ LOGIN_OK = 0x00,
+ LOGIN_FAILED = 0x01,
+ LOGIN_FAILED2 = 0x02,
+ LOGIN_BANNED = 0x03,
+ LOGIN_UNKNOWN_ACCOUNT = 0x04,
+ LOGIN_UNKNOWN_ACCOUNT3 = 0x05,
+ LOGIN_ALREADYONLINE = 0x06,
+ LOGIN_NOTIME = 0x07,
+ LOGIN_DBBUSY = 0x08,
+ LOGIN_BADVERSION = 0x09,
+ LOGIN_DOWNLOAD_FILE = 0x0A,
+ LOGIN_FAILED3 = 0x0B,
+ LOGIN_SUSPENDED = 0x0C,
+ LOGIN_FAILED4 = 0x0D,
+ LOGIN_CONNECTED = 0x0E,
+ LOGIN_PARENTALCONTROL = 0x0F,
+ LOGIN_LOCKED_ENFORCED = 0x10,
+};
+
+// we need to stick to 1 version or half of the stuff will work for someone
+// others will not and opposite
+// will only support WoW, WoW:TBC and WoW:WotLK 3.0.8 client build 9506...
+
+#define EXPECTED_TRINITY_CLIENT_BUILD {9506, 0}
+
+#endif
diff --git a/src/realmd/AuthSocket.cpp b/src/realmd/AuthSocket.cpp
new file mode 100644
index 00000000000..c5c81593737
--- /dev/null
+++ b/src/realmd/AuthSocket.cpp
@@ -0,0 +1,1094 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2009 Trinity <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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/** \file
+ \ingroup realmd
+*/
+
+#include "Common.h"
+#include "Database/DatabaseEnv.h"
+#include "ByteBuffer.h"
+#include "Config/ConfigEnv.h"
+#include "Log.h"
+#include "RealmList.h"
+#include "AuthSocket.h"
+#include "AuthCodes.h"
+#include <openssl/md5.h>
+#include "Auth/Sha1.h"
+//#include "Util.h" -- for commented utf8ToUpperOnlyLatin
+
+extern RealmList m_realmList;
+
+extern DatabaseType LoginDatabase;
+
+#define ChunkSize 2048
+
+enum eAuthCmd
+{
+ //AUTH_NO_CMD = 0xFF,
+ AUTH_LOGON_CHALLENGE = 0x00,
+ AUTH_LOGON_PROOF = 0x01,
+ AUTH_RECONNECT_CHALLENGE = 0x02,
+ AUTH_RECONNECT_PROOF = 0x03,
+ //update srv =4
+ REALM_LIST = 0x10,
+ XFER_INITIATE = 0x30,
+ XFER_DATA = 0x31,
+ XFER_ACCEPT = 0x32,
+ XFER_RESUME = 0x33,
+ XFER_CANCEL = 0x34
+};
+
+enum eStatus
+{
+ STATUS_CONNECTED = 0,
+ STATUS_AUTHED
+};
+
+// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some paltform
+#if defined( __GNUC__ )
+#pragma pack(1)
+#else
+#pragma pack(push,1)
+#endif
+
+typedef struct AUTH_LOGON_CHALLENGE_C
+{
+ uint8 cmd;
+ uint8 error;
+ uint16 size;
+ uint8 gamename[4];
+ uint8 version1;
+ uint8 version2;
+ uint8 version3;
+ uint16 build;
+ uint8 platform[4];
+ uint8 os[4];
+ uint8 country[4];
+ uint32 timezone_bias;
+ uint32 ip;
+ uint8 I_len;
+ uint8 I[1];
+} sAuthLogonChallenge_C;
+
+//typedef sAuthLogonChallenge_C sAuthReconnectChallenge_C;
+/*
+typedef struct
+{
+ uint8 cmd;
+ uint8 error;
+ uint8 unk2;
+ uint8 B[32];
+ uint8 g_len;
+ uint8 g[1];
+ uint8 N_len;
+ uint8 N[32];
+ uint8 s[32];
+ uint8 unk3[16];
+} sAuthLogonChallenge_S;
+*/
+
+typedef struct AUTH_LOGON_PROOF_C
+{
+ uint8 cmd;
+ uint8 A[32];
+ uint8 M1[20];
+ uint8 crc_hash[20];
+ uint8 number_of_keys;
+ uint8 unk; // Added in 1.12.x client branch
+} sAuthLogonProof_C;
+/*
+typedef struct
+{
+ uint16 unk1;
+ uint32 unk2;
+ uint8 unk3[4];
+ uint16 unk4[20];
+} sAuthLogonProofKey_C;
+*/
+typedef struct AUTH_LOGON_PROOF_S
+{
+ uint8 cmd;
+ uint8 error;
+ uint8 M2[20];
+ uint32 unk1;
+ uint32 unk2;
+ uint16 unk3;
+} sAuthLogonProof_S;
+
+typedef struct AUTH_RECONNECT_PROOF_C
+{
+ uint8 cmd;
+ uint8 R1[16];
+ uint8 R2[20];
+ uint8 R3[20];
+ uint8 number_of_keys;
+} sAuthReconnectProof_C;
+
+typedef struct XFER_INIT
+{
+ uint8 cmd; // XFER_INITIATE
+ uint8 fileNameLen; // strlen(fileName);
+ uint8 fileName[5]; // fileName[fileNameLen]
+ uint64 file_size; // file size (bytes)
+ uint8 md5[MD5_DIGEST_LENGTH]; // MD5
+}XFER_INIT;
+
+typedef struct XFER_DATA
+{
+ uint8 opcode;
+ uint16 data_size;
+ uint8 data[ChunkSize];
+}XFER_DATA_STRUCT;
+
+typedef struct AuthHandler
+{
+ eAuthCmd cmd;
+ uint32 status;
+ bool (AuthSocket::*handler)(void);
+}AuthHandler;
+
+// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some paltform
+#if defined( __GNUC__ )
+#pragma pack()
+#else
+#pragma pack(pop)
+#endif
+
+/// Launch a thread to transfer a patch to the client
+class PatcherRunnable: public ZThread::Runnable
+{
+ public:
+ PatcherRunnable(class AuthSocket *);
+ void run();
+
+ private:
+ AuthSocket * mySocket;
+};
+
+typedef struct PATCH_INFO
+{
+ uint8 md5[MD5_DIGEST_LENGTH];
+}PATCH_INFO;
+
+/// Caches MD5 hash of client patches present on the server
+class Patcher
+{
+ public:
+ typedef std::map<std::string, PATCH_INFO*> Patches;
+ ~Patcher();
+ Patcher();
+ Patches::const_iterator begin() const { return _patches.begin(); }
+ Patches::const_iterator end() const { return _patches.end(); }
+ void LoadPatchMD5(char*);
+ bool GetHash(char * pat,uint8 mymd5[16]);
+
+ private:
+ void LoadPatchesInfo();
+ Patches _patches;
+};
+
+const AuthHandler table[] =
+{
+ { AUTH_LOGON_CHALLENGE, STATUS_CONNECTED, &AuthSocket::_HandleLogonChallenge },
+ { AUTH_LOGON_PROOF, STATUS_CONNECTED, &AuthSocket::_HandleLogonProof },
+ { AUTH_RECONNECT_CHALLENGE, STATUS_CONNECTED, &AuthSocket::_HandleReconnectChallenge},
+ { AUTH_RECONNECT_PROOF, STATUS_CONNECTED, &AuthSocket::_HandleReconnectProof },
+ { REALM_LIST, STATUS_AUTHED, &AuthSocket::_HandleRealmList },
+ { XFER_ACCEPT, STATUS_CONNECTED, &AuthSocket::_HandleXferAccept },
+ { XFER_RESUME, STATUS_CONNECTED, &AuthSocket::_HandleXferResume },
+ { XFER_CANCEL, STATUS_CONNECTED, &AuthSocket::_HandleXferCancel }
+};
+
+#define AUTH_TOTAL_COMMANDS sizeof(table)/sizeof(AuthHandler)
+
+///Holds the MD5 hash of client patches present on the server
+Patcher PatchesCache;
+
+/// Constructor - set the N and g values for SRP6
+AuthSocket::AuthSocket(ISocketHandler &h) : TcpSocket(h)
+{
+ N.SetHexStr("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7");
+ g.SetDword(7);
+ _authed = false;
+ pPatch = NULL;
+
+ _accountSecurityLevel = SEC_PLAYER;
+}
+
+/// Close patch file descriptor before leaving
+AuthSocket::~AuthSocket()
+{
+ ZThread::Guard<ZThread::Mutex> g(patcherLock);
+ if(pPatch)
+ fclose(pPatch);
+}
+
+/// Accept the connection and set the s random value for SRP6
+void AuthSocket::OnAccept()
+{
+ sLog.outBasic("Accepting connection from '%s:%d'",
+ GetRemoteAddress().c_str(), GetRemotePort());
+
+ s.SetRand(s_BYTE_SIZE * 8);
+}
+
+/// Read the packet from the client
+void AuthSocket::OnRead()
+{
+ ///- Read the packet
+ TcpSocket::OnRead();
+ uint8 _cmd;
+ while (1)
+ {
+ if (!ibuf.GetLength())
+ return;
+
+ ///- Get the command out of it
+ ibuf.SoftRead((char *)&_cmd, 1); // UQ1: No longer exists in new net code ???
+ //ibuf.Read((char *)&_cmd, 1);
+ /*char *command = (char *)malloc(1);
+
+ ibuf.Read(command, 1);
+
+ _cmd = (uint8)command;*/
+ // assert(0);
+ size_t i;
+
+ ///- Circle through known commands and call the correct command handler
+ for (i=0;i<AUTH_TOTAL_COMMANDS; i++)
+ {
+ if ((uint8)table[i].cmd == _cmd &&
+ (table[i].status == STATUS_CONNECTED ||
+ (_authed && table[i].status == STATUS_AUTHED)))
+ {
+ DEBUG_LOG("[Auth] got data for cmd %u ibuf length %u", (uint32)_cmd, ibuf.GetLength());
+
+ if (!(*this.*table[i].handler)())
+ {
+ DEBUG_LOG("Command handler failed for cmd %u ibuf length %u", (uint32)_cmd, ibuf.GetLength());
+ return;
+ }
+ break;
+ }
+ }
+
+ ///- Report unknown commands in the debug log
+ if (i==AUTH_TOTAL_COMMANDS)
+ {
+ DEBUG_LOG("[Auth] got unknown packet %u", (uint32)_cmd);
+ return;
+ }
+ }
+}
+
+/// Make the SRP6 calculation from hash in dB
+void AuthSocket::_SetVSFields(const std::string& rI)
+{
+ BigNumber I;
+ I.SetHexStr(rI.c_str());
+
+ //In case of leading zeroes in the rI hash, restore them
+ uint8 mDigest[SHA_DIGEST_LENGTH];
+ memset(mDigest,0,SHA_DIGEST_LENGTH);
+ if (I.GetNumBytes() <= SHA_DIGEST_LENGTH)
+ memcpy(mDigest,I.AsByteArray(),I.GetNumBytes());
+
+ std::reverse(mDigest,mDigest+SHA_DIGEST_LENGTH);
+
+ Sha1Hash sha;
+ sha.UpdateData(s.AsByteArray(), s.GetNumBytes());
+ sha.UpdateData(mDigest, SHA_DIGEST_LENGTH);
+ sha.Finalize();
+ BigNumber x;
+ x.SetBinary(sha.GetDigest(), sha.GetLength());
+ v = g.ModExp(x, N);
+ // No SQL injection (username escaped)
+ const char *v_hex, *s_hex;
+ v_hex = v.AsHexStr();
+ s_hex = s.AsHexStr();
+ LoginDatabase.PExecute("UPDATE account SET v = '%s', s = '%s' WHERE username = '%s'",v_hex,s_hex, _safelogin.c_str() );
+ OPENSSL_free((void*)v_hex);
+ OPENSSL_free((void*)s_hex);
+}
+
+/// Logon Challenge command handler
+bool AuthSocket::_HandleLogonChallenge()
+{
+ DEBUG_LOG("Entering _HandleLogonChallenge");
+ if (ibuf.GetLength() < sizeof(sAuthLogonChallenge_C))
+ return false;
+
+ ///- Read the first 4 bytes (header) to get the length of the remaining of the packet
+ std::vector<uint8> buf;
+ buf.resize(4);
+
+ ibuf.Read((char *)&buf[0], 4);
+
+ EndianConvert(*((uint16*)(buf[0])));
+ uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size;
+ DEBUG_LOG("[AuthChallenge] got header, body is %#04x bytes", remaining);
+
+ if ((remaining < sizeof(sAuthLogonChallenge_C) - buf.size()) || (ibuf.GetLength() < remaining))
+ return false;
+
+ //No big fear of memory outage (size is int16, i.e. < 65536)
+ buf.resize(remaining + buf.size() + 1);
+ buf[buf.size() - 1] = 0;
+ sAuthLogonChallenge_C *ch = (sAuthLogonChallenge_C*)&buf[0];
+
+ // BigEndian code, nop in little endian case
+ // size already converted
+ EndianConvert(*((uint32*)(&ch->gamename[0])));
+ EndianConvert(ch->build);
+ EndianConvert(*((uint32*)(&ch->platform[0])));
+ EndianConvert(*((uint32*)(&ch->os[0])));
+ EndianConvert(*((uint32*)(&ch->country[0])));
+ EndianConvert(ch->timezone_bias);
+ EndianConvert(ch->ip);
+
+ ///- Read the remaining of the packet
+ ibuf.Read((char *)&buf[4], remaining);
+ DEBUG_LOG("[AuthChallenge] got full packet, %#04x bytes", ch->size);
+ DEBUG_LOG("[AuthChallenge] name(%d): '%s'", ch->I_len, ch->I);
+
+ ByteBuffer pkt;
+
+ _login = (const char*)ch->I;
+ _build = ch->build;
+
+ ///- Normalize account name
+ //utf8ToUpperOnlyLatin(_login); -- client already send account in expected form
+
+ //Escape the user login to avoid further SQL injection
+ //Memory will be freed on AuthSocket object destruction
+ _safelogin=_login;
+ LoginDatabase.escape_string(_safelogin);
+
+ pkt << (uint8) AUTH_LOGON_CHALLENGE;
+ pkt << (uint8) 0x00;
+
+ ///- Verify that this IP is not in the ip_banned table
+ // No SQL injection possible (paste the IP address as passed by the socket)
+ LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
+
+ std::string address = GetRemoteAddress();
+ LoginDatabase.escape_string(address);
+ QueryResult *result = LoginDatabase.PQuery( "SELECT * FROM ip_banned WHERE ip = '%s'",address.c_str());
+ if(result)
+ {
+ pkt << (uint8)REALM_AUTH_ACCOUNT_BANNED;
+ sLog.outBasic("[AuthChallenge] Banned ip %s tries to login!",GetRemoteAddress().c_str ());
+ delete result;
+ }
+ else
+ {
+ ///- Get the account details from the account table
+ // No SQL injection (escaped user name)
+
+ result = LoginDatabase.PQuery("SELECT sha_pass_hash,id,locked,last_ip,gmlevel FROM account WHERE username = '%s'",_safelogin.c_str ());
+ if( result )
+ {
+ ///- If the IP is 'locked', check that the player comes indeed from the correct IP address
+ bool locked = false;
+ if((*result)[2].GetUInt8() == 1) // if ip is locked
+ {
+ DEBUG_LOG("[AuthChallenge] Account '%s' is locked to IP - '%s'", _login.c_str(), (*result)[3].GetString());
+ DEBUG_LOG("[AuthChallenge] Player address is '%s'", GetRemoteAddress().c_str());
+ if ( strcmp((*result)[3].GetString(),GetRemoteAddress().c_str()) )
+ {
+ DEBUG_LOG("[AuthChallenge] Account IP differs");
+ pkt << (uint8) REALM_AUTH_ACCOUNT_FREEZED;
+ locked=true;
+ }
+ else
+ {
+ DEBUG_LOG("[AuthChallenge] Account IP matches");
+ }
+ }
+ else
+ {
+ DEBUG_LOG("[AuthChallenge] Account '%s' is not locked to ip", _login.c_str());
+ }
+
+ if (!locked)
+ {
+ //set expired bans to inactive
+ LoginDatabase.Execute("UPDATE account_banned SET active = 0 WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
+ ///- If the account is banned, reject the logon attempt
+ QueryResult *banresult = LoginDatabase.PQuery("SELECT bandate,unbandate FROM account_banned WHERE id = %u AND active = 1", (*result)[1].GetUInt32());
+ if(banresult)
+ {
+ if((*banresult)[0].GetUInt64() == (*banresult)[1].GetUInt64())
+ {
+ pkt << (uint8) REALM_AUTH_ACCOUNT_BANNED;
+ sLog.outBasic("[AuthChallenge] Banned account %s tries to login!",_login.c_str ());
+ }
+ else
+ {
+ pkt << (uint8) REALM_AUTH_ACCOUNT_FREEZED;
+ sLog.outBasic("[AuthChallenge] Temporarily banned account %s tries to login!",_login.c_str ());
+ }
+
+ delete banresult;
+ }
+ else
+ {
+ ///- Get the password from the account table, upper it, and make the SRP6 calculation
+ std::string rI = (*result)[0].GetCppString();
+ _SetVSFields(rI);
+
+ b.SetRand(19 * 8);
+ BigNumber gmod=g.ModExp(b, N);
+ B = ((v * 3) + gmod) % N;
+
+ ASSERT(gmod.GetNumBytes() <= 32);
+
+ BigNumber unk3;
+ unk3.SetRand(16*8);
+
+ ///- Fill the response packet with the result
+ pkt << (uint8)REALM_AUTH_SUCCESS;
+
+ // B may be calculated < 32B so we force minnimal length to 32B
+ pkt.append(B.AsByteArray(32), 32); // 32 bytes
+ pkt << (uint8)1;
+ pkt.append(g.AsByteArray(), 1);
+ pkt << (uint8)32;
+ pkt.append(N.AsByteArray(), 32);
+ pkt.append(s.AsByteArray(), s.GetNumBytes()); // 32 bytes
+ pkt.append(unk3.AsByteArray(), 16);
+ pkt << (uint8)0; // Added in 1.12.x client branch
+
+ uint8 secLevel = (*result)[4].GetUInt8();
+ _accountSecurityLevel = secLevel <= SEC_ADMINISTRATOR ? AccountTypes(secLevel) : SEC_ADMINISTRATOR;
+
+ _localizationName.resize(4);
+ for(int i = 0; i <4; ++i)
+ _localizationName[i] = ch->country[4-i-1];
+
+ sLog.outBasic("[AuthChallenge] account %s is using '%c%c%c%c' locale (%u)", _login.c_str (), ch->country[3],ch->country[2],ch->country[1],ch->country[0], GetLocaleByName(_localizationName));
+ }
+ }
+ delete result;
+ }
+ else //no account
+ {
+ pkt<< (uint8) REALM_AUTH_NO_MATCH;
+ }
+ }
+ SendBuf((char const*)pkt.contents(), pkt.size());
+ return true;
+}
+
+/// Logon Proof command handler
+bool AuthSocket::_HandleLogonProof()
+{
+ DEBUG_LOG("Entering _HandleLogonProof");
+ ///- Read the packet
+ if (ibuf.GetLength() < sizeof(sAuthLogonProof_C))
+ return false;
+ sAuthLogonProof_C lp;
+ ibuf.Read((char *)&lp, sizeof(sAuthLogonProof_C));
+
+ ///- Check if the client has one of the expected version numbers
+ bool valid_version=false;
+ int accepted_versions[]=EXPECTED_TRINITY_CLIENT_BUILD;
+ for(int i=0;accepted_versions[i];i++)
+ {
+ if(_build==accepted_versions[i])
+ {
+ valid_version=true;
+ break;
+ }
+ }
+
+ /// <ul><li> If the client has no valid version
+ if(!valid_version)
+ {
+ ///- Check if we have the apropriate patch on the disk
+
+ // 24 = len("./patches/65535enGB.mpq")+1
+ char tmp[24];
+ // No buffer overflow (fixed length of arguments)
+ sprintf(tmp,"./patches/%d%s.mpq",_build, _localizationName.c_str());
+ // This will be closed at the destruction of the AuthSocket (client deconnection)
+ FILE *pFile=fopen(tmp,"rb");
+
+ if(!pFile)
+ {
+ ByteBuffer pkt;
+ pkt << (uint8) AUTH_LOGON_CHALLENGE;
+ pkt << (uint8) 0x00;
+ pkt << (uint8) REALM_AUTH_WRONG_BUILD_NUMBER;
+ DEBUG_LOG("[AuthChallenge] %u is not a valid client version!", _build);
+ DEBUG_LOG("[AuthChallenge] Patch %s not found",tmp);
+ SendBuf((char const*)pkt.contents(), pkt.size());
+ return true;
+ }
+ else // have patch
+ {
+ pPatch=pFile;
+ XFER_INIT xferh;
+
+ ///- Get the MD5 hash of the patch file (get it from preloaded Patcher cache or calculate it)
+ if(PatchesCache.GetHash(tmp,(uint8*)&xferh.md5))
+ {
+ DEBUG_LOG("\n[AuthChallenge] Found precached patch info for patch %s",tmp);
+ }
+ else
+ { //calculate patch md5
+ printf("\n[AuthChallenge] Patch info for %s was not cached.",tmp);
+ PatchesCache.LoadPatchMD5(tmp);
+ PatchesCache.GetHash(tmp,(uint8*)&xferh.md5);
+ }
+
+ ///- Send a packet to the client with the file length and MD5 hash
+ uint8 data[2]={AUTH_LOGON_PROOF,REALM_AUTH_UPDATE_CLIENT};
+ SendBuf((const char*)data,sizeof(data));
+
+ memcpy(&xferh,"0\x05Patch",7);
+ xferh.cmd=XFER_INITIATE;
+ fseek(pPatch,0,SEEK_END);
+ xferh.file_size=ftell(pPatch);
+
+ SendBuf((const char*)&xferh,sizeof(xferh));
+ return true;
+ }
+ }
+ /// </ul>
+
+ ///- Continue the SRP6 calculation based on data received from the client
+ BigNumber A;
+ A.SetBinary(lp.A, 32);
+
+ Sha1Hash sha;
+ sha.UpdateBigNumbers(&A, &B, NULL);
+ sha.Finalize();
+ BigNumber u;
+ u.SetBinary(sha.GetDigest(), 20);
+ BigNumber S = (A * (v.ModExp(u, N))).ModExp(b, N);
+
+ uint8 t[32];
+ uint8 t1[16];
+ uint8 vK[40];
+ memcpy(t, S.AsByteArray(), 32);
+ for (int i = 0; i < 16; i++)
+ {
+ t1[i] = t[i*2];
+ }
+ sha.Initialize();
+ sha.UpdateData(t1, 16);
+ sha.Finalize();
+ for (int i = 0; i < 20; i++)
+ {
+ vK[i*2] = sha.GetDigest()[i];
+ }
+ for (int i = 0; i < 16; i++)
+ {
+ t1[i] = t[i*2+1];
+ }
+ sha.Initialize();
+ sha.UpdateData(t1, 16);
+ sha.Finalize();
+ for (int i = 0; i < 20; i++)
+ {
+ vK[i*2+1] = sha.GetDigest()[i];
+ }
+ K.SetBinary(vK, 40);
+
+ uint8 hash[20];
+
+ sha.Initialize();
+ sha.UpdateBigNumbers(&N, NULL);
+ sha.Finalize();
+ memcpy(hash, sha.GetDigest(), 20);
+ sha.Initialize();
+ sha.UpdateBigNumbers(&g, NULL);
+ sha.Finalize();
+ for (int i = 0; i < 20; i++)
+ {
+ hash[i] ^= sha.GetDigest()[i];
+ }
+ BigNumber t3;
+ t3.SetBinary(hash, 20);
+
+ sha.Initialize();
+ sha.UpdateData(_login);
+ sha.Finalize();
+ uint8 t4[SHA_DIGEST_LENGTH];
+ memcpy(t4, sha.GetDigest(), SHA_DIGEST_LENGTH);
+
+ sha.Initialize();
+ sha.UpdateBigNumbers(&t3, NULL);
+ sha.UpdateData(t4, SHA_DIGEST_LENGTH);
+ sha.UpdateBigNumbers(&s, &A, &B, &K, NULL);
+ sha.Finalize();
+ BigNumber M;
+ M.SetBinary(sha.GetDigest(), 20);
+
+ ///- Check if SRP6 results match (password is correct), else send an error
+ if (!memcmp(M.AsByteArray(), lp.M1, 20))
+ {
+ sLog.outBasic("User '%s' successfully authenticated", _login.c_str());
+
+ ///- Update the sessionkey, last_ip, last login time and reset number of failed logins in the account table for this account
+ // No SQL injection (escaped user name) and IP address as received by socket
+ const char* K_hex = K.AsHexStr();
+ LoginDatabase.PExecute("UPDATE account SET sessionkey = '%s', last_ip = '%s', last_login = NOW(), locale = '%u', failed_logins = 0 WHERE username = '%s'", K_hex, GetRemoteAddress().c_str(), GetLocaleByName(_localizationName), _safelogin.c_str() );
+ OPENSSL_free((void*)K_hex);
+
+ ///- Finish SRP6 and send the final result to the client
+ sha.Initialize();
+ sha.UpdateBigNumbers(&A, &M, &K, NULL);
+ sha.Finalize();
+
+ sAuthLogonProof_S proof;
+ memcpy(proof.M2, sha.GetDigest(), 20);
+ proof.cmd = AUTH_LOGON_PROOF;
+ proof.error = 0;
+ proof.unk1 = 0x00800000;
+ proof.unk2 = 0x00;
+ proof.unk3 = 0x00;
+
+ SendBuf((char *)&proof, sizeof(proof));
+
+ ///- Set _authed to true!
+ _authed = true;
+ }
+ else
+ {
+ char data[4]={AUTH_LOGON_PROOF,REALM_AUTH_NO_MATCH,3,0};
+ SendBuf(data,sizeof(data));
+ sLog.outBasic("[AuthChallenge] account %s tried to login with wrong password!",_login.c_str ());
+
+ uint32 MaxWrongPassCount = sConfig.GetIntDefault("WrongPass.MaxCount", 0);
+ if(MaxWrongPassCount > 0)
+ {
+ //Increment number of failed logins by one and if it reaches the limit temporarily ban that account or IP
+ LoginDatabase.PExecute("UPDATE account SET failed_logins = failed_logins + 1 WHERE username = '%s'",_safelogin.c_str());
+
+ if(QueryResult *loginfail = LoginDatabase.PQuery("SELECT id, failed_logins FROM account WHERE username = '%s'", _safelogin.c_str()))
+ {
+ Field* fields = loginfail->Fetch();
+ uint32 failed_logins = fields[1].GetUInt32();
+
+ if( failed_logins >= MaxWrongPassCount )
+ {
+ uint32 WrongPassBanTime = sConfig.GetIntDefault("WrongPass.BanTime", 600);
+ bool WrongPassBanType = sConfig.GetBoolDefault("WrongPass.BanType", false);
+
+ if(WrongPassBanType)
+ {
+ uint32 acc_id = fields[0].GetUInt32();
+ LoginDatabase.PExecute("INSERT INTO account_banned VALUES ('%u',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','Trinity realmd','Failed login autoban',1)",
+ acc_id, WrongPassBanTime);
+ sLog.outBasic("[AuthChallenge] account %s got banned for '%u' seconds because it failed to authenticate '%u' times",
+ _login.c_str(), WrongPassBanTime, failed_logins);
+ }
+ else
+ {
+ std::string current_ip = GetRemoteAddress();
+ LoginDatabase.escape_string(current_ip);
+ LoginDatabase.PExecute("INSERT INTO ip_banned VALUES ('%s',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','Trinity realmd','Failed login autoban')",
+ current_ip.c_str(), WrongPassBanTime);
+ sLog.outBasic("[AuthChallenge] IP %s got banned for '%u' seconds because account %s failed to authenticate '%u' times",
+ current_ip.c_str(), WrongPassBanTime, _login.c_str(), failed_logins);
+ }
+ }
+ delete loginfail;
+ }
+ }
+ }
+ return true;
+}
+
+/// Reconnect Challenge command handler
+bool AuthSocket::_HandleReconnectChallenge()
+{
+ DEBUG_LOG("Entering _HandleReconnectChallenge");
+ if (ibuf.GetLength() < sizeof(sAuthLogonChallenge_C))
+ return false;
+
+ ///- Read the first 4 bytes (header) to get the length of the remaining of the packet
+ std::vector<uint8> buf;
+ buf.resize(4);
+
+ ibuf.Read((char *)&buf[0], 4);
+
+ EndianConvert(*((uint16*)(buf[0])));
+ uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size;
+ DEBUG_LOG("[ReconnectChallenge] got header, body is %#04x bytes", remaining);
+
+ if ((remaining < sizeof(sAuthLogonChallenge_C) - buf.size()) || (ibuf.GetLength() < remaining))
+ return false;
+
+ //No big fear of memory outage (size is int16, i.e. < 65536)
+ buf.resize(remaining + buf.size() + 1);
+ buf[buf.size() - 1] = 0;
+ sAuthLogonChallenge_C *ch = (sAuthLogonChallenge_C*)&buf[0];
+
+ ///- Read the remaining of the packet
+ ibuf.Read((char *)&buf[4], remaining);
+ DEBUG_LOG("[ReconnectChallenge] got full packet, %#04x bytes", ch->size);
+ DEBUG_LOG("[ReconnectChallenge] name(%d): '%s'", ch->I_len, ch->I);
+
+ _login = (const char*)ch->I;
+ _safelogin = _login;
+
+ QueryResult *result = LoginDatabase.PQuery ("SELECT sessionkey FROM account WHERE username = '%s'", _safelogin.c_str ());
+
+ // Stop if the account is not found
+ if (!result)
+ {
+ sLog.outError("[ERROR] user %s tried to login and we cannot find his session key in the database.", _login.c_str());
+ SetCloseAndDelete();
+ return false;
+ }
+
+ Field* fields = result->Fetch ();
+ K.SetHexStr (fields[0].GetString ());
+ delete result;
+
+ ///- Sending response
+ ByteBuffer pkt;
+ pkt << (uint8) AUTH_RECONNECT_CHALLENGE;
+ pkt << (uint8) 0x00;
+ _reconnectProof.SetRand(16*8);
+ pkt.append(_reconnectProof.AsByteBuffer()); // 16 bytes random
+ pkt << (uint64) 0x00 << (uint64) 0x00; // 16 bytes zeros
+ SendBuf((char const*)pkt.contents(), pkt.size());
+ return true;
+}
+
+/// Reconnect Proof command handler
+bool AuthSocket::_HandleReconnectProof()
+{
+ DEBUG_LOG("Entering _HandleReconnectProof");
+ ///- Read the packet
+ if (ibuf.GetLength() < sizeof(sAuthReconnectProof_C))
+ return false;
+ if (_login.empty() || !_reconnectProof.GetNumBytes() || !K.GetNumBytes())
+ return false;
+ sAuthReconnectProof_C lp;
+ ibuf.Read((char *)&lp, sizeof(sAuthReconnectProof_C));
+
+ BigNumber t1;
+ t1.SetBinary(lp.R1, 16);
+
+ Sha1Hash sha;
+ sha.Initialize();
+ sha.UpdateData(_login);
+ sha.UpdateBigNumbers(&t1, &_reconnectProof, &K, NULL);
+ sha.Finalize();
+
+ if (!memcmp(sha.GetDigest(), lp.R2, SHA_DIGEST_LENGTH))
+ {
+ ///- Sending response
+ ByteBuffer pkt;
+ pkt << (uint8) AUTH_RECONNECT_PROOF;
+ pkt << (uint8) 0x00;
+ pkt << (uint16) 0x00; // 2 bytes zeros
+ SendBuf((char const*)pkt.contents(), pkt.size());
+
+ ///- Set _authed to true!
+ _authed = true;
+
+ return true;
+ }
+ else
+ {
+ sLog.outError("[ERROR] user %s tried to login, but session invalid.", _login.c_str());
+ SetCloseAndDelete();
+ return false;
+ }
+}
+
+/// %Realm List command handler
+bool AuthSocket::_HandleRealmList()
+{
+ DEBUG_LOG("Entering _HandleRealmList");
+ if (ibuf.GetLength() < 5)
+ return false;
+
+ ibuf.Remove(5);
+
+ ///- Get the user id (else close the connection)
+ // No SQL injection (escaped user name)
+
+ QueryResult *result = LoginDatabase.PQuery("SELECT id,sha_pass_hash FROM account WHERE username = '%s'",_safelogin.c_str());
+ if(!result)
+ {
+ sLog.outError("[ERROR] user %s tried to login and we cannot find him in the database.",_login.c_str());
+ SetCloseAndDelete();
+ return false;
+ }
+
+ uint32 id = (*result)[0].GetUInt32();
+ std::string rI = (*result)[1].GetCppString();
+ delete result;
+
+ ///- Update realm list if need
+ m_realmList.UpdateIfNeed();
+
+ ///- Circle through realms in the RealmList and construct the return packet (including # of user characters in each realm)
+ ByteBuffer pkt;
+ pkt << (uint32) 0;
+ pkt << (uint16) m_realmList.size();
+ RealmList::RealmMap::const_iterator i;
+ for( i = m_realmList.begin(); i != m_realmList.end(); i++ )
+ {
+ uint8 AmountOfCharacters;
+
+ // No SQL injection. id of realm is controlled by the database.
+ result = LoginDatabase.PQuery( "SELECT numchars FROM realmcharacters WHERE realmid = '%d' AND acctid='%u'",i->second.m_ID,id);
+ if( result )
+ {
+ Field *fields = result->Fetch();
+ AmountOfCharacters = fields[0].GetUInt8();
+ delete result;
+ }
+ else
+ AmountOfCharacters = 0;
+
+ uint8 lock = (i->second.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0;
+
+ pkt << i->second.icon; // realm type
+ pkt << lock; // if 1, then realm locked
+ pkt << i->second.color; // if 2, then realm is offline
+ pkt << i->first;
+ pkt << i->second.address;
+ pkt << i->second.populationLevel;
+ pkt << AmountOfCharacters;
+ pkt << i->second.timezone; // realm category
+ pkt << (uint8) 0x2C; // unk, may be realm number/id?
+ }
+ pkt << (uint8) 0x10;
+ pkt << (uint8) 0x00;
+
+ ByteBuffer hdr;
+ hdr << (uint8) REALM_LIST;
+ hdr << (uint16)pkt.size();
+ hdr.append(pkt);
+
+ SendBuf((char const*)hdr.contents(), hdr.size());
+
+ // Set check field before possible relogin to realm
+ _SetVSFields(rI);
+ return true;
+}
+
+/// Resume patch transfer
+bool AuthSocket::_HandleXferResume()
+{
+ DEBUG_LOG("Entering _HandleXferResume");
+ ///- Check packet length and patch existence
+ if (ibuf.GetLength()<9 || !pPatch)
+ {
+ sLog.outError("Error while resuming patch transfer (wrong packet)");
+ return false;
+ }
+
+ ///- Launch a PatcherRunnable thread starting at given patch file offset
+ uint64 start;
+ ibuf.Remove(1);
+ ibuf.Read((char*)&start,sizeof(start));
+ fseek(pPatch,start,0);
+
+ ZThread::Thread u(new PatcherRunnable(this));
+ return true;
+}
+
+/// Cancel patch transfer
+bool AuthSocket::_HandleXferCancel()
+{
+ DEBUG_LOG("Entering _HandleXferCancel");
+
+ ///- Close and delete the socket
+ ibuf.Remove(1); //clear input buffer
+
+ //ZThread::Thread::sleep(15);
+ SetCloseAndDelete();
+
+ return true;
+}
+
+/// Accept patch transfer
+bool AuthSocket::_HandleXferAccept()
+{
+ DEBUG_LOG("Entering _HandleXferAccept");
+
+ ///- Check packet length and patch existence
+ if (!pPatch)
+ {
+ sLog.outError("Error while accepting patch transfer (wrong packet)");
+ return false;
+ }
+
+ ///- Launch a PatcherRunnable thread, starting at the begining of the patch file
+ ibuf.Remove(1); //clear input buffer
+ fseek(pPatch,0,0);
+
+ ZThread::Thread u(new PatcherRunnable(this));
+
+ return true;
+}
+
+/// Check if there is lag on the connection to the client
+bool AuthSocket::IsLag()
+{
+ return (TCP_BUFSIZE_READ-GetOutputLength()< 2*ChunkSize);
+}
+
+PatcherRunnable::PatcherRunnable(class AuthSocket * as)
+{
+ mySocket=as;
+}
+
+/// Send content of patch file to the client
+void PatcherRunnable::run()
+{
+ ZThread::Guard<ZThread::Mutex> g(mySocket->patcherLock);
+ XFER_DATA_STRUCT xfdata;
+ xfdata.opcode = XFER_DATA;
+
+ while(!feof(mySocket->pPatch) && mySocket->Ready())
+ {
+ ///- Wait until output buffer is reasonably empty
+ while(mySocket->Ready() && mySocket->IsLag())
+ {
+ ZThread::Thread::sleep(1);
+ }
+ ///- And send content of the patch file to the client
+ xfdata.data_size=fread(&xfdata.data,1,ChunkSize,mySocket->pPatch);
+ mySocket->SendBuf((const char*)&xfdata,xfdata.data_size +(sizeof(XFER_DATA_STRUCT)-ChunkSize));
+ }
+}
+
+/// Preload MD5 hashes of existing patch files on server
+#ifndef _WIN32
+#include <dirent.h>
+#include <errno.h>
+void Patcher::LoadPatchesInfo()
+{
+ DIR * dirp;
+ //int errno;
+ struct dirent * dp;
+ dirp = opendir("./patches/");
+ if(!dirp)
+ return;
+ while (dirp)
+ {
+ errno = 0;
+ if ((dp = readdir(dirp)) != NULL)
+ {
+ int l=strlen(dp->d_name);
+ if(l<8)continue;
+ if(!memcmp(&dp->d_name[l-4],".mpq",4))
+ LoadPatchMD5(dp->d_name);
+ }
+ else
+ {
+ if(errno != 0)
+ {
+ closedir(dirp);
+ return;
+ }
+ break;
+ }
+ }
+
+ if(dirp)
+ closedir(dirp);
+}
+
+#else
+void Patcher::LoadPatchesInfo()
+{
+ WIN32_FIND_DATA fil;
+ HANDLE hFil=FindFirstFile("./patches/*.mpq",&fil);
+ if(hFil==INVALID_HANDLE_VALUE)
+ return; //no patches were found
+
+ do
+ {
+ LoadPatchMD5(fil.cFileName);
+ }
+ while(FindNextFile(hFil,&fil));
+}
+#endif
+
+/// Calculate and store MD5 hash for a given patch file
+void Patcher::LoadPatchMD5(char * szFileName)
+{
+ ///- Try to open the patch file
+ std::string path = "./patches/";
+ path += szFileName;
+ FILE * pPatch=fopen(path.c_str(),"rb");
+ sLog.outDebug("Loading patch info from %s\n",path.c_str());
+ if(!pPatch)
+ {
+ sLog.outError("Error loading patch %s\n",path.c_str());
+ return;
+ }
+
+ ///- Calculate the MD5 hash
+ MD5_CTX ctx;
+ MD5_Init(&ctx);
+ uint8* buf = new uint8[512*1024];
+
+ while (!feof(pPatch))
+ {
+ size_t read = fread(buf, 1, 512*1024, pPatch);
+ MD5_Update(&ctx, buf, read);
+ }
+ delete [] buf;
+ fclose(pPatch);
+
+ ///- Store the result in the internal patch hash map
+ _patches[path] = new PATCH_INFO;
+ MD5_Final((uint8 *)&_patches[path]->md5 , &ctx);
+}
+
+/// Get cached MD5 hash for a given patch file
+bool Patcher::GetHash(char * pat,uint8 mymd5[16])
+{
+ for( Patches::iterator i = _patches.begin(); i != _patches.end(); i++ )
+ if(!stricmp(pat,i->first.c_str () ))
+ {
+ memcpy(mymd5,i->second->md5,16);
+ return true;
+ }
+
+ return false;
+}
+
+/// Launch the patch hashing mechanism on object creation
+Patcher::Patcher()
+{
+ LoadPatchesInfo();
+}
+
+/// Empty and delete the patch map on termination
+Patcher::~Patcher()
+{
+ for(Patches::iterator i = _patches.begin(); i != _patches.end(); i++ )
+ delete i->second;
+}
diff --git a/src/trinityrealm/AuthSocket.h b/src/realmd/AuthSocket.h
index f704283c215..3cae54c7789 100644
--- a/src/trinityrealm/AuthSocket.h
+++ b/src/realmd/AuthSocket.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/realmd/CMakeLists.txt b/src/realmd/CMakeLists.txt
new file mode 100644
index 00000000000..ab03c3143a5
--- /dev/null
+++ b/src/realmd/CMakeLists.txt
@@ -0,0 +1,45 @@
+########### next target ###############
+
+SET(trinity-realm_SRCS
+AuthCodes.h
+AuthSocket.cpp
+AuthSocket.h
+Main.cpp
+RealmList.cpp
+RealmList.h
+)
+
+add_executable(trinity-realm ${trinity-realm_SRCS})
+add_definitions(
+-D_TRINITY_REALM_CONFIG='"${CONF_DIR}/trinityrealm.conf"'
+)
+IF (DO_MYSQL)
+ #SET_TARGET_PROPERTIES(mangos-realmd PROPERTIES LINK_FLAGS ${MYSQL_LIBS})
+ SET_TARGET_PROPERTIES(trinity-realm PROPERTIES LINK_FLAGS "-pthread")
+ENDIF(DO_MYSQL)
+IF (DO_POSTGRE)
+ SET_TARGET_PROPERTIES(trinity-realmd PROPERTIES LINK_FLAGS ${POSTGRE_LIBS})
+ENDIF(DO_POSTGRE)
+
+
+target_link_libraries(
+trinity-realm
+shared
+trinityframework
+trinitysockets
+trinitydatabase
+trinityauth
+trinityconfig
+ZThread
+zlib
+${SSLLIB}
+${MYSQL_LIBRARIES}
+)
+
+install(TARGETS trinity-realm DESTINATION bin)
+
+
+########### install files ###############
+
+install(FILES realmd.conf.dist.in DESTINATION etc)
+
diff --git a/src/realmd/Main.cpp b/src/realmd/Main.cpp
new file mode 100644
index 00000000000..f36558e6fba
--- /dev/null
+++ b/src/realmd/Main.cpp
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2009 Trinity <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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/// \addtogroup realmd Realm Daemon
+/// @{
+/// \file
+
+#include "Common.h"
+#include "Database/DatabaseEnv.h"
+#include "RealmList.h"
+
+#include "Config/ConfigEnv.h"
+#include "Log.h"
+#include "sockets/ListenSocket.h"
+#include "AuthSocket.h"
+#include "SystemConfig.h"
+#include "Util.h"
+
+// Format is YYYYMMDDRR where RR is the change in the conf file
+// for that day.
+#ifndef _REALMDCONFVERSION
+# define _REALMDCONFVERSION 2007062001
+#endif
+
+#ifndef _TRINITY_REALM_CONFIG
+# define _TRINITY_REALM_CONFIG "TrinityRealm.conf"
+#endif //_TRINITY_REALM_CONFIG
+
+#ifdef WIN32
+#include "ServiceWin32.h"
+char serviceName[] = "TrinityRealm";
+char serviceLongName[] = "Trinity realm service";
+char serviceDescription[] = "Massive Network Game Object Server";
+/*
+ * -1 - not in service mode
+ * 0 - stopped
+ * 1 - running
+ * 2 - paused
+ */
+int m_ServiceStatus = -1;
+#endif
+
+bool StartDB(std::string &dbstring);
+void UnhookSignals();
+void HookSignals();
+
+bool stopEvent = false; ///< Setting it to true stops the server
+RealmList m_realmList; ///< Holds the list of realms for this server
+
+DatabaseType LoginDatabase; ///< Accessor to the realm server database
+
+/// Print out the usage string for this program on the console.
+void usage(const char *prog)
+{
+ sLog.outString("Usage: \n %s [<options>]\n"
+ " -c config_file use config_file as configuration file\n\r"
+ #ifdef WIN32
+ " Running as service functions:\n\r"
+ " --service run as service\n\r"
+ " -s install install service\n\r"
+ " -s uninstall uninstall service\n\r"
+ #endif
+ ,prog);
+}
+
+/// Launch the realm server
+extern int main(int argc, char **argv)
+{
+ ///- Command line parsing to get the configuration file name
+ char const* cfg_file = _TRINITY_REALM_CONFIG;
+ int c=1;
+ while( c < argc )
+ {
+ if( strcmp(argv[c],"-c") == 0)
+ {
+ if( ++c >= argc )
+ {
+ sLog.outError("Runtime-Error: -c option requires an input argument");
+ usage(argv[0]);
+ return 1;
+ }
+ else
+ cfg_file = argv[c];
+ }
+
+ #ifdef WIN32
+ ////////////
+ //Services//
+ ////////////
+ if( strcmp(argv[c],"-s") == 0)
+ {
+ if( ++c >= argc )
+ {
+ sLog.outError("Runtime-Error: -s option requires an input argument");
+ usage(argv[0]);
+ return 1;
+ }
+ if( strcmp(argv[c],"install") == 0)
+ {
+ if (WinServiceInstall())
+ sLog.outString("Installing service");
+ return 1;
+ }
+ else if( strcmp(argv[c],"uninstall") == 0)
+ {
+ if(WinServiceUninstall())
+ sLog.outString("Uninstalling service");
+ return 1;
+ }
+ else
+ {
+ sLog.outError("Runtime-Error: unsupported option %s",argv[c]);
+ usage(argv[0]);
+ return 1;
+ }
+ }
+ if( strcmp(argv[c],"--service") == 0)
+ {
+ WinServiceRun();
+ }
+ ////
+ #endif
+ ++c;
+ }
+
+ if (!sConfig.SetSource(cfg_file))
+ {
+ sLog.outError("Could not find configuration file %s.", cfg_file);
+ return 1;
+ }
+ sLog.outString("Using configuration file %s.", cfg_file);
+
+ ///- Check the version of the configuration file
+ uint32 confVersion = sConfig.GetIntDefault("ConfVersion", 0);
+ if (confVersion < _REALMDCONFVERSION)
+ {
+ sLog.outError("*****************************************************************************");
+ sLog.outError(" WARNING: Your trinityrealm.conf version indicates your conf file is out of date!");
+ sLog.outError(" Please check for updates, as your current default values may cause");
+ sLog.outError(" strange behavior.");
+ sLog.outError("*****************************************************************************");
+ clock_t pause = 3000 + clock();
+
+ while (pause > clock()) {}
+ }
+
+ sLog.outString( "%s (realm-daemon)", _FULLVERSION );
+ sLog.outString( "<Ctrl-C> to stop.\n" );
+
+ /// realmd PID file creation
+ std::string pidfile = sConfig.GetStringDefault("PidFile", "");
+ if(!pidfile.empty())
+ {
+ uint32 pid = CreatePIDFile(pidfile);
+ if( !pid )
+ {
+ sLog.outError( "Cannot create PID file %s.\n", pidfile.c_str() );
+ return 1;
+ }
+
+ sLog.outString( "Daemon PID: %u\n", pid );
+ }
+
+ ///- Initialize the database connection
+ std::string dbstring;
+ if(!StartDB(dbstring))
+ return 1;
+
+ ///- Get the list of realms for the server
+ m_realmList.Initialize(sConfig.GetIntDefault("RealmsStateUpdateDelay", 20));
+ if (m_realmList.size() == 0)
+ {
+ sLog.outError("No valid realms specified.");
+ return 1;
+ }
+
+ ///- Launch the listening network socket
+ port_t rmport = sConfig.GetIntDefault( "RealmServerPort", DEFAULT_REALMSERVER_PORT );
+ std::string bind_ip = sConfig.GetStringDefault("BindIP", "0.0.0.0");
+
+ SocketHandler h;
+ ListenSocket<AuthSocket> authListenSocket(h);
+ if ( authListenSocket.Bind(bind_ip.c_str(),rmport))
+ {
+ sLog.outError( "Trinity realm can not bind to %s:%d",bind_ip.c_str(), rmport );
+ return 1;
+ }
+
+ h.Add(&authListenSocket);
+
+ ///- Catch termination signals
+ HookSignals();
+
+ ///- Handle affinity for multiple processors and process priority on Windows
+ #ifdef WIN32
+ {
+ HANDLE hProcess = GetCurrentProcess();
+
+ uint32 Aff = sConfig.GetIntDefault("UseProcessors", 0);
+ if(Aff > 0)
+ {
+ ULONG_PTR appAff;
+ ULONG_PTR sysAff;
+
+ if(GetProcessAffinityMask(hProcess,&appAff,&sysAff))
+ {
+ ULONG_PTR curAff = Aff & appAff; // remove non accessible processors
+
+ if(!curAff )
+ {
+ sLog.outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for realmd. Accessible processors bitmask (hex): %x",Aff,appAff);
+ }
+ else
+ {
+ if(SetProcessAffinityMask(hProcess,curAff))
+ sLog.outString("Using processors (bitmask, hex): %x", curAff);
+ else
+ sLog.outError("Can't set used processors (hex): %x", curAff);
+ }
+ }
+ sLog.outString();
+ }
+
+ bool Prio = sConfig.GetBoolDefault("ProcessPriority", false);
+
+ if(Prio)
+ {
+ if(SetPriorityClass(hProcess,HIGH_PRIORITY_CLASS))
+ sLog.outString("TrinityRealm process priority class set to HIGH");
+ else
+ sLog.outError("ERROR: Can't set realmd process priority class.");
+ sLog.outString();
+ }
+ }
+ #endif
+
+ // maximum counter for next ping
+ uint32 numLoops = (sConfig.GetIntDefault( "MaxPingTime", 30 ) * (MINUTE * 1000000 / 100000));
+ uint32 loopCounter = 0;
+
+ ///- Wait for termination signal
+ while (!stopEvent)
+ {
+
+ h.Select(0, 100000);
+
+ if( (++loopCounter) == numLoops )
+ {
+ loopCounter = 0;
+ sLog.outDetail("Ping MySQL to keep connection alive");
+ delete LoginDatabase.Query("SELECT 1 FROM realmlist LIMIT 1");
+ }
+#ifdef WIN32
+ if (m_ServiceStatus == 0) stopEvent = true;
+ while (m_ServiceStatus == 2) Sleep(1000);
+#endif
+ }
+
+ ///- Wait for the delay thread to exit
+ LoginDatabase.HaltDelayThread();
+
+ ///- Remove signal handling before leaving
+ UnhookSignals();
+
+ sLog.outString( "Halting process..." );
+ return 0;
+}
+
+/// Handle termination signals
+/** Put the global variable stopEvent to 'true' if a termination signal is caught **/
+void OnSignal(int s)
+{
+ switch (s)
+ {
+ case SIGINT:
+ case SIGTERM:
+ stopEvent = true;
+ break;
+ #ifdef _WIN32
+ case SIGBREAK:
+ stopEvent = true;
+ break;
+ #endif
+ }
+
+ signal(s, OnSignal);
+}
+
+/// Initialize connection to the database
+bool StartDB(std::string &dbstring)
+{
+ if(!sConfig.GetString("LoginDatabaseInfo", &dbstring))
+ {
+ sLog.outError("Database not specified");
+ return false;
+ }
+
+ sLog.outString("Database: %s", dbstring.c_str() );
+ if(!LoginDatabase.Initialize(dbstring.c_str()))
+ {
+ sLog.outError("Cannot connect to database");
+ return false;
+ }
+
+ return true;
+}
+
+/// Define hook 'OnSignal' for all termination signals
+void HookSignals()
+{
+ signal(SIGINT, OnSignal);
+ signal(SIGTERM, OnSignal);
+ #ifdef _WIN32
+ signal(SIGBREAK, OnSignal);
+ #endif
+}
+
+/// Unhook the signals before leaving
+void UnhookSignals()
+{
+ signal(SIGINT, 0);
+ signal(SIGTERM, 0);
+ #ifdef _WIN32
+ signal(SIGBREAK, 0);
+ #endif
+}
+
+/// @}
diff --git a/src/realmd/Makefile.am b/src/realmd/Makefile.am
new file mode 100644
index 00000000000..a14b50c847a
--- /dev/null
+++ b/src/realmd/Makefile.am
@@ -0,0 +1,59 @@
+# Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+#
+# Copyright (C) 2008-2009 Trinity <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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+## Process this file with automake to produce Makefile.in
+
+## CPP flags for includes, defines, etc.
+AM_CPPFLAGS = $(TRINI_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir)/../../dep/include -I$(srcdir)/../framework -I$(srcdir)/../shared -I$(srcdir) -DSYSCONFDIR=\"$(sysconfdir)/\"
+
+## Build realm list daemon as standalone program
+bin_PROGRAMS = trinity-realmd
+trinity_realmd_SOURCES = \
+ AuthCodes.h \
+ AuthSocket.cpp \
+ AuthSocket.h \
+ Main.cpp \
+ RealmList.cpp \
+ RealmList.h
+
+## Link realm list daemon against the shared library
+trinity_realmd_LDADD = ../shared/Database/libmangosdatabase.a ../shared/Config/libmangosconfig.a ../shared/Auth/libmangosauth.a ../shared/libmangosshared.a ../framework/libmangosframework.a ../../dep/src/sockets/libmangossockets.a ../../dep/src/zthread/libZThread.la
+trinity_realmd_LDFLAGS = -L../../dep/src/sockets -L../../dep/src/zthread -L$(libdir) $(TRINI_LIBS)
+
+## Additional files to include when running 'make dist'
+# Include realm list daemon configuration
+EXTRA_DIST = \
+ realmd.conf.dist
+
+## Additional files to install
+sysconf_DATA = \
+ realmd.conf.dist
+
+install-data-hook:
+ @list='$(sysconf_DATA)'; for p in $$list; do \
+ dest=`echo $$p | sed -e s/.dist//`; \
+ if test -f $(DESTDIR)$(sysconfdir)/$$dest; then \
+ echo "$@ will not overwrite existing $(DESTDIR)$(sysconfdir)/$$dest"; \
+ else \
+ echo " $(INSTALL_DATA) $$p $(DESTDIR)$(sysconfdir)/$$dest"; \
+ $(INSTALL_DATA) $$p $(DESTDIR)$(sysconfdir)/$$dest; \
+ fi; \
+ done
+
+clean-local:
+ rm -f $(sysconf_DATA)
diff --git a/src/realmd/RealmList.cpp b/src/realmd/RealmList.cpp
new file mode 100644
index 00000000000..936f7bcd703
--- /dev/null
+++ b/src/realmd/RealmList.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2009 Trinity <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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/** \file
+ \ingroup realmd
+*/
+
+#include "Common.h"
+#include "RealmList.h"
+#include "Policies/SingletonImp.h"
+#include "Database/DatabaseEnv.h"
+
+INSTANTIATE_SINGLETON_1( RealmList );
+
+extern DatabaseType LoginDatabase;
+
+RealmList::RealmList( ) : m_UpdateInterval(0), m_NextUpdateTime(time(NULL))
+{
+}
+
+/// Load the realm list from the database
+void RealmList::Initialize(uint32 updateInterval)
+{
+ m_UpdateInterval = updateInterval;
+
+ ///- Get the content of the realmlist table in the database
+ UpdateRealms(true);
+}
+
+void RealmList::UpdateRealm( uint32 ID, const std::string& name, const std::string& address, uint32 port, uint8 icon, uint8 color, uint8 timezone, AccountTypes allowedSecurityLevel, float popu)
+{
+ ///- Create new if not exist or update existed
+ Realm& realm = m_realms[name];
+
+ realm.m_ID = ID;
+ realm.icon = icon;
+ realm.color = color;
+ realm.timezone = timezone;
+ realm.allowedSecurityLevel = allowedSecurityLevel;
+ realm.populationLevel = popu;
+
+ ///- Append port to IP address.
+ std::ostringstream ss;
+ ss << address << ":" << port;
+ realm.address = ss.str();
+}
+
+void RealmList::UpdateIfNeed()
+{
+ // maybe disabled or updated recently
+ if(!m_UpdateInterval || m_NextUpdateTime > time(NULL))
+ return;
+
+ m_NextUpdateTime = time(NULL) + m_UpdateInterval;
+
+ // Clears Realm list
+ m_realms.clear();
+
+ // Get the content of the realmlist table in the database
+ UpdateRealms(false);
+}
+
+void RealmList::UpdateRealms(bool init)
+{
+ sLog.outDetail("Updating Realm List...");
+
+ QueryResult *result = LoginDatabase.Query( "SELECT id, name, address, port, icon, color, timezone, allowedSecurityLevel, population FROM realmlist WHERE color <> 3 ORDER BY name" );
+
+ ///- Circle through results and add them to the realm map
+ if(result)
+ {
+ do
+ {
+ Field *fields = result->Fetch();
+
+ uint8 allowedSecurityLevel = fields[7].GetUInt8();
+
+ UpdateRealm(fields[0].GetUInt32(), fields[1].GetCppString(),fields[2].GetCppString(),fields[3].GetUInt32(),fields[4].GetUInt8(), fields[5].GetUInt8(), fields[6].GetUInt8(), (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), fields[8].GetFloat() );
+ if(init)
+ sLog.outString("Added realm \"%s\".", fields[1].GetString());
+ } while( result->NextRow() );
+ delete result;
+ }
+}
diff --git a/src/realmd/RealmList.h b/src/realmd/RealmList.h
new file mode 100644
index 00000000000..b830a0827a7
--- /dev/null
+++ b/src/realmd/RealmList.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2009 Trinity <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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/// \addtogroup realmd
+/// @{
+/// \file
+
+#ifndef _REALMLIST_H
+#define _REALMLIST_H
+
+#include "Common.h"
+
+/// Storage object for a realm
+struct Realm
+{
+ std::string address;
+ uint8 icon;
+ uint8 color;
+ uint8 timezone;
+ uint32 m_ID;
+ AccountTypes allowedSecurityLevel;
+ float populationLevel;
+};
+
+/// Storage object for the list of realms on the server
+class RealmList
+{
+ public:
+ typedef std::map<std::string, Realm> RealmMap;
+
+ RealmList();
+ ~RealmList() {}
+
+ void Initialize(uint32 updateInterval);
+
+ void UpdateIfNeed();
+
+ RealmMap::const_iterator begin() const { return m_realms.begin(); }
+ RealmMap::const_iterator end() const { return m_realms.end(); }
+ uint32 size() const { return m_realms.size(); }
+ private:
+ void UpdateRealms(bool init);
+ void UpdateRealm( uint32 ID, const std::string& name, const std::string& address, uint32 port, uint8 icon, uint8 color, uint8 timezone, AccountTypes allowedSecurityLevel, float popu);
+ private:
+ RealmMap m_realms; ///< Internal map of realms
+ uint32 m_UpdateInterval;
+ time_t m_NextUpdateTime;
+};
+#endif
+/// @}
diff --git a/src/trinityrealm/TrinityRealm.ico b/src/realmd/TrinityRealm.ico
index da318f48a8c..da318f48a8c 100644
--- a/src/trinityrealm/TrinityRealm.ico
+++ b/src/realmd/TrinityRealm.ico
Binary files differ
diff --git a/src/trinityrealm/trinityrealm.conf.dist b/src/realmd/realmd.conf.dist.in
index 72ef1c9012e..72ef1c9012e 100644
--- a/src/trinityrealm/trinityrealm.conf.dist
+++ b/src/realmd/realmd.conf.dist.in
diff --git a/src/trinityrealm/TrinityRealm.rc b/src/realmd/realmd.rc
index 33c7eef719a..bcd37f240c5 100644
--- a/src/trinityrealm/TrinityRealm.rc
+++ b/src/realmd/realmd.rc
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.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
diff --git a/src/realmd/resource.h b/src/realmd/resource.h
new file mode 100644
index 00000000000..7e7d8e4b76f
--- /dev/null
+++ b/src/realmd/resource.h
@@ -0,0 +1,15 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by TrinityCore.rc
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/src/shared/Auth/AuthCrypt.cpp b/src/shared/Auth/AuthCrypt.cpp
index d45c56817ba..2d8bd824fd1 100644
--- a/src/shared/Auth/AuthCrypt.cpp
+++ b/src/shared/Auth/AuthCrypt.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -50,9 +50,8 @@ void AuthCrypt::DecryptRecv(uint8 *data, size_t len)
void AuthCrypt::EncryptSend(uint8 *data, size_t len)
{
if (!_initialized) return;
- if (len < CRYPTED_SEND_LEN) return;
- for (size_t t = 0; t < CRYPTED_SEND_LEN; t++)
+ for (size_t t = 0; t < len; t++)
{
_send_i %= _key.size();
uint8 x = (data[t] ^ _key[_send_i]) + _send_j;
@@ -67,7 +66,7 @@ void AuthCrypt::SetKey(BigNumber *bn)
GenerateKey(key, bn);
_key.resize(SHA_DIGEST_LENGTH);
std::copy(key, key + SHA_DIGEST_LENGTH, _key.begin());
- delete key;
+ delete[] key;
}
AuthCrypt::~AuthCrypt()
diff --git a/src/shared/Auth/AuthCrypt.h b/src/shared/Auth/AuthCrypt.h
index b007e8c3d0e..7a0b0a4d219 100644
--- a/src/shared/Auth/AuthCrypt.h
+++ b/src/shared/Auth/AuthCrypt.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -32,7 +32,6 @@ class AuthCrypt
AuthCrypt();
~AuthCrypt();
- const static size_t CRYPTED_SEND_LEN = 4;
const static size_t CRYPTED_RECV_LEN = 6;
void Init();
diff --git a/src/shared/Auth/BigNumber.cpp b/src/shared/Auth/BigNumber.cpp
index 2baba88e9e0..becbe44c0ed 100644
--- a/src/shared/Auth/BigNumber.cpp
+++ b/src/shared/Auth/BigNumber.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Auth/BigNumber.h b/src/shared/Auth/BigNumber.h
index 37979bdd76f..9ce18ea3047 100644
--- a/src/shared/Auth/BigNumber.h
+++ b/src/shared/Auth/BigNumber.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Auth/Hmac.cpp b/src/shared/Auth/Hmac.cpp
index 91c065d3640..5f97ee65cc2 100644
--- a/src/shared/Auth/Hmac.cpp
+++ b/src/shared/Auth/Hmac.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Auth/Hmac.h b/src/shared/Auth/Hmac.h
index 1c19ec2238d..b8ab30f2dc7 100644
--- a/src/shared/Auth/Hmac.h
+++ b/src/shared/Auth/Hmac.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Auth/Makefile.am b/src/shared/Auth/Makefile.am
index 9c71613a0de..2d4cc03902d 100644
--- a/src/shared/Auth/Makefile.am
+++ b/src/shared/Auth/Makefile.am
@@ -1,6 +1,6 @@
-# Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+# Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
#
-# Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+# Copyright (C) 2008-2009 Trinity <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
@@ -9,19 +9,19 @@
#
# 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
+# 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, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
## Process this file with automake to produce Makefile.in
## Sub-directories to parse
## CPP flags for includes, defines, etc.
-AM_CPPFLAGS = $(MYSQL_INCLUDES) $(POSTGRE_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(srcdir)/../../../dep/include -I$(srcdir)/../../framework -I$(srcdir)/../../shared -I$(srcdir)/../../../dep/include/g3dlite
+AM_CPPFLAGS = $(TRINI_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(srcdir)/../../../dep/include -I$(srcdir)/../../framework -I$(srcdir)/../../shared -I$(srcdir)/../../../dep/include/g3dlite
## Build MaNGOS shared library and its parts as convenience library.
# All libraries will be convenience libraries. Might be changed to shared
@@ -29,13 +29,13 @@ AM_CPPFLAGS = $(MYSQL_INCLUDES) $(POSTGRE_INCLUDES) -I$(top_builddir)/src/shared
noinst_LIBRARIES = libmangosauth.a
libmangosauth_a_SOURCES = \
- AuthCrypt.cpp \
- AuthCrypt.h \
- BigNumber.cpp \
- BigNumber.h \
- Hmac.cpp \
- Hmac.h \
- Sha1.cpp \
- Sha1.h \
- md5.c \
- md5.h
+ AuthCrypt.cpp \
+ AuthCrypt.h \
+ BigNumber.cpp \
+ BigNumber.h \
+ Hmac.cpp \
+ Hmac.h \
+ Sha1.cpp \
+ Sha1.h \
+ md5.c \
+ md5.h
diff --git a/src/shared/Auth/Sha1.cpp b/src/shared/Auth/Sha1.cpp
index 73fcf90bfa8..f367c2919b3 100644
--- a/src/shared/Auth/Sha1.cpp
+++ b/src/shared/Auth/Sha1.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Auth/Sha1.h b/src/shared/Auth/Sha1.h
index d748dc6d747..811ccc2053a 100644
--- a/src/shared/Auth/Sha1.h
+++ b/src/shared/Auth/Sha1.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/ByteBuffer.h b/src/shared/ByteBuffer.h
index 3d0d19d9120..2dd01e8a022 100644
--- a/src/shared/ByteBuffer.h
+++ b/src/shared/ByteBuffer.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -243,6 +243,32 @@ class ByteBuffer
_rpos += len;
}
+ bool readPackGUID(uint64& guid)
+ {
+ if(rpos()+1 > size())
+ return false;
+
+ guid = 0;
+
+ uint8 guidmark=0;
+ (*this) >> guidmark;
+
+ for(int i=0;i<8;i++)
+ {
+ if(guidmark & (uint8(1) << i))
+ {
+ if(rpos()+1 > size())
+ return false;
+
+ uint8 bit;
+ (*this) >> bit;
+ guid |= (uint64(bit) << (i*8));
+ }
+ }
+
+ return true;
+ }
+
const uint8 *contents() const { return &_storage[0]; }
size_t size() const { return _storage.size(); }
diff --git a/src/shared/Common.cpp b/src/shared/Common.cpp
index db039b93a82..e70dc8358c2 100644
--- a/src/shared/Common.cpp
+++ b/src/shared/Common.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Common.h b/src/shared/Common.h
index c97de30ed46..a0884a8455e 100644
--- a/src/shared/Common.h
+++ b/src/shared/Common.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -80,6 +80,8 @@
#pragma warning(disable:4305)
#pragma warning(disable:4005)
+
+#pragma warning(disable:4522)//warning when class has 2 constructosr
#endif // __SHOW_STUPID_WARNINGS__
#endif // __GNUC__
diff --git a/src/shared/Config/Config.cpp b/src/shared/Config/Config.cpp
index 1dacb55b670..b3a3b13d652 100644
--- a/src/shared/Config/Config.cpp
+++ b/src/shared/Config/Config.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Config/Config.h b/src/shared/Config/Config.h
index 7347d3ee7a1..424c369bd92 100644
--- a/src/shared/Config/Config.h
+++ b/src/shared/Config/Config.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Config/ConfigEnv.h b/src/shared/Config/ConfigEnv.h
index 09877cbd296..6c3a54a45fc 100644
--- a/src/shared/Config/ConfigEnv.h
+++ b/src/shared/Config/ConfigEnv.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Config/Makefile.am b/src/shared/Config/Makefile.am
index 23188ba3447..4854095b98c 100644
--- a/src/shared/Config/Makefile.am
+++ b/src/shared/Config/Makefile.am
@@ -1,6 +1,6 @@
-# Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+# Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
#
-# Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+# Copyright (C) 2008-2009 Trinity <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
@@ -9,19 +9,19 @@
#
# 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
+# 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, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
## Process this file with automake to produce Makefile.in
## Sub-directories to parse
## CPP flags for includes, defines, etc.
-AM_CPPFLAGS = $(MYSQL_INCLUDES) $(POSTGRE_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(srcdir)/../../../dep/include -I$(srcdir)/../../framework -I$(srcdir)/../../shared -I$(srcdir)/../../../dep/include/g3dlite
+AM_CPPFLAGS = $(TRINI_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(srcdir)/../../../dep/include -I$(srcdir)/../../framework -I$(srcdir)/../../shared -I$(srcdir)/../../../dep/include/g3dlite
## Build MaNGOS shared library and its parts as convenience library.
# All libraries will be convenience libraries. Might be changed to shared
diff --git a/src/shared/Config/dotconfpp/dotconfpp.cpp b/src/shared/Config/dotconfpp/dotconfpp.cpp
index 543e8acf1f4..c46b1fe6fb9 100644
--- a/src/shared/Config/dotconfpp/dotconfpp.cpp
+++ b/src/shared/Config/dotconfpp/dotconfpp.cpp
@@ -138,7 +138,7 @@ int DOTCONFDocument::cleanupLine(char * line)
quoted = !quoted;
++line; continue;
}
- if(isspace(*line) && !quoted){
+ if(isspace((unsigned char)*line) && !quoted){
*bg++ = 0;
if(strlen(start)){
@@ -154,7 +154,7 @@ int DOTCONFDocument::cleanupLine(char * line)
words.push_back(word);
}
start = bg;
- while(isspace(*++line)) {}
+ while(isspace((unsigned char)*++line)) {}
continue;
}
diff --git a/src/shared/Database/DBCEnums.h b/src/shared/Database/DBCEnums.h
index 1d54616a2b5..e546b1f7828 100644
--- a/src/shared/Database/DBCEnums.h
+++ b/src/shared/Database/DBCEnums.h
@@ -1,5 +1,5 @@
/*
-* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
+* 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
@@ -34,28 +34,190 @@ enum AreaTeams
AREATEAM_HORDE = 4
};
+enum AchievementFactionFlags
+{
+ ACHIEVEMENT_FACTION_FLAG_HORDE = 0x00000000,
+ ACHIEVEMENT_FACTION_FLAG_ALLIANCE = 0x00000001,
+};
+
+enum AchievementFlags
+{
+ ACHIEVEMENT_FLAG_COUNTER = 0x00000001,
+ ACHIEVEMENT_FLAG_REACH_LEVEL = 0x00000004,
+ ACHIEVEMENT_FLAG_RERERED_MAX = 0x00000010, // displays the maximum criteria of a refered achievement
+ ACHIEVEMENT_FLAG_AVERAGE = 0x00000040,
+ ACHIEVEMENT_FLAG_REALM_FIRST_REACH= 0x00000100,
+ ACHIEVEMENT_FLAG_REALM_FIRST_KILL = 0x00000200,
+};
+
+enum AchievementCriteriaCondition
+{
+ ACHIEVEMENT_CRITERIA_CONDITION_NONE = 0,
+ ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH = 1,
+ ACHIEVEMENT_CRITERIA_CONDITION_UNK1 = 2, // only used in "Complete a daily quest every day for five consecutive days"
+ ACHIEVEMENT_CRITERIA_CONDITION_MAP = 3, // requires you to be on specific map
+ ACHIEVEMENT_CRITERIA_CONDITION_NO_LOOSE = 4, // only used in "Win 10 arenas without losing"
+ ACHIEVEMENT_CRITERIA_CONDITION_UNK2 = 9, // unk
+ ACHIEVEMENT_CRITERIA_CONDITION_UNK3 = 13, // unk
+};
+
+enum AchievementCriteriaCompletionFlags
+{
+ // some Achievements (like 698) have several criteria but only one has to be fulfilled. These are identified by this flag.
+ ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL = 2,
+};
+
+enum AchievementCriteriaGroupFlags
+{
+ // you mustn't be in a group while fulfilling this achievement
+ ACHIEVEMENT_CRITERIA_GROUP_NOT_IN_GROUP = 2,
+};
+
+enum AchievementCriteriaTypes
+{
+ ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE = 0,
+ ACHIEVEMENT_CRITERIA_TYPE_WIN_BG = 1,
+ 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,
+ // you have to complete a daily quest x times in a row
+ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY = 10,
+ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE = 11,
+ ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE = 13,
+ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST = 14,
+ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND= 15,
+ ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP= 16,
+ // TODO: this can be both arena and total deaths. Where is this difference in the dbc?
+ ACHIEVEMENT_CRITERIA_TYPE_DEATH= 17,
+ ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON = 18,
+ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID = 19,
+ ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE = 20,
+ ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER = 23,
+ ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING = 24,
+ ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM = 26,
+ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST = 27,
+ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET = 28,
+ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL= 29,
+ ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE = 30,
+ ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA = 31,
+ ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA = 32,
+ ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA = 33,
+ ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL = 34,
+ // TODO: this criteria has additional conditions which can not be found in the dbcs
+ ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL = 35,
+ ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM = 36,
+ // TODO: the archievements 1162 and 1163 requires a special rating which can't be found in the dbc
+ ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA = 37,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING = 38,
+ ACHIEVEMENT_CRITERIA_TYPE_REACH_TEAM_RATING = 39,
+ ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL = 40,
+ ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM = 41,
+ ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM= 42,
+ ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA = 43,
+ ACHIEVEMENT_CRITERIA_TYPE_OWN_RANK= 44,
+ ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT= 45,
+ ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION= 46,
+ ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION= 47,
+ // noted: rewarded as soon as the player payed, not at taking place at the seat
+ ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP= 48,
+ ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM = 49,
+ // TODO: itemlevel is mentioned in text but not present in dbc
+ ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT = 50,
+ ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT= 51,
+ ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS = 52,
+ ACHIEVEMENT_CRITERIA_TYPE_HK_RACE = 53,
+ ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE = 54,
+ ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE = 55,
+ // TODO: in some cases map not present, and in some cases need do without die
+ ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS = 56,
+ ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM = 57,
+ ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS = 59,
+ ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS = 60,
+ ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS = 61,
+ ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD = 62,
+ ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING = 63,
+ ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER = 65,
+ ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL = 66,
+ ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY = 67,
+ ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT = 68,
+ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2= 69,
+ ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL= 70,
+ ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT = 72,
+ // TODO: title id is not mentioned in dbc
+ ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE = 74,
+ ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS= 75,
+ ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL = 76,
+ ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL = 77,
+ // TODO: creature type (demon, undead etc.) is not stored in dbc
+ ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE = 78,
+ ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS= 80,
+ ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION= 82,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID= 83,
+ ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS= 84,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD = 85,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_GOLD_VALUE_OWNED = 86,
+ ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION = 87,
+ ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION = 88,
+ ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS = 89,
+ ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM = 90,
+ 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,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CASTED = 104,
+ ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED = 105,
+ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALING_RECEIVED = 106,
+ ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED = 107,
+ ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN = 108,
+ ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE = 109,
+ // TODO: target entry is missing
+ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2 = 110,
+ ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE= 112,
+ ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL = 113,
+ ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS = 114,
+ // 0..114 => 115 criteria types total
+ ACHIEVEMENT_CRITERIA_TYPE_TOTAL = 115,
+};
+
enum AreaFlags
{
AREA_FLAG_SNOW = 0x00000001, // snow (only Dun Morogh, Naxxramas, Razorfen Downs and Winterspring)
- AREA_FLAG_UNK1 = 0x00000002, // unknown, (only Naxxramas and Razorfen Downs)
- AREA_FLAG_UNK2 = 0x00000004, // Only used on development map
- AREA_FLAG_SLAVE_CAPITAL = 0x00000008, // slave capital city flag?
- AREA_FLAG_UNK3 = 0x00000010, // unknown
+ AREA_FLAG_UNK1 = 0x00000002, // may be necropolis?
+ 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_UNK4 = 0x00000040, // many zones have this flag
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, // outland zones? (only Eye of the Storm not have this flag, but have 0x00004000 flag)
+ 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, // only Netherwing Ledge, Socrethar's Seat, Tempest Keep, The Arcatraz, The Botanica, The Mechanar, Sorrow Wing Point, Dragonspine Ridge, Netherwing Mines, Dragonmaw Base Camp, Dragonmaw Skyway
- AREA_FLAG_UNUSED1 = 0x00002000, // not used now (no area/zones with this flag set in 2.4.2)
- AREA_FLAG_OUTLAND2 = 0x00004000, // outland zones? (only Circle of Blood Arena not have this flag, but have 0x00000400 flag)
+ AREA_FLAG_UNUSED1 = 0x00002000, // not used now (no area/zones with this flag set in 3.0.3)
+ AREA_FLAG_OUTLAND2 = 0x00004000, // expansion zones? (only Circle of Blood Arena not have this flag, but have 0x00000400 flag)
AREA_FLAG_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, // not used now (no area/zones with this flag set in 2.4.2)
- AREA_FLAG_UNK5 = 0x00040000, // just used for Amani Pass, Hatchet Hills
- AREA_FLAG_LOWLEVEL = 0x00100000 // used for some starting areas with area_level <=15
+ AREA_FLAG_UNUSED2 = 0x00020000, // not used now (no area/zones with this flag set in 3.0.3)
+ AREA_FLAG_UNK5 = 0x00040000, // only used for Amani Pass, Hatchet Hills
+ 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_UNK7 = 0x00400000, // Warsong Hold, Acherus: The Ebon Hold, New Agamand Inn, Vengeance Landing Inn
+ AREA_FLAG_UNK8 = 0x00800000, // Westguard Inn, Acherus: The Ebon Hold, Valgarde
+ AREA_FLAG_OUTDOOR_PVP = 0x01000000, // Wintergrasp and it's subzones
+ AREA_FLAG_UNK9 = 0x02000000, // unknown
+ AREA_FLAG_UNK10 = 0x04000000, // unknown
+ AREA_FLAG_OUTDOOR_PVP2 = 0x08000000 // Wintergrasp and it's subzones
};
enum FactionTemplateFlags
@@ -89,13 +251,15 @@ enum AbilytyLearnType
enum ItemEnchantmentType
{
- ITEM_ENCHANTMENT_TYPE_NONE = 0,
- ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL = 1,
- ITEM_ENCHANTMENT_TYPE_DAMAGE = 2,
- ITEM_ENCHANTMENT_TYPE_EQUIP_SPELL = 3,
- ITEM_ENCHANTMENT_TYPE_RESISTANCE = 4,
- ITEM_ENCHANTMENT_TYPE_STAT = 5,
- ITEM_ENCHANTMENT_TYPE_TOTEM = 6
+ ITEM_ENCHANTMENT_TYPE_NONE = 0,
+ ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL = 1,
+ ITEM_ENCHANTMENT_TYPE_DAMAGE = 2,
+ ITEM_ENCHANTMENT_TYPE_EQUIP_SPELL = 3,
+ ITEM_ENCHANTMENT_TYPE_RESISTANCE = 4,
+ ITEM_ENCHANTMENT_TYPE_STAT = 5,
+ ITEM_ENCHANTMENT_TYPE_TOTEM = 6,
+ ITEM_ENCHANTMENT_TYPE_USE_SPELL = 7,
+ ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET = 8
};
enum TotemCategoryType
@@ -109,4 +273,51 @@ enum TotemCategoryType
TOTEM_CATEGORY_TYPE_SPANNER = 24
};
+// SummonProperties.dbc, col 1
+/*enum SummonGroup
+{
+ SUMMON_GROUP_UNKNOWN1 = 0, // 1160 spells in 3.0.3
+ SUMMON_GROUP_UNKNOWN2 = 1, // 861 spells in 3.0.3
+ SUMMON_GROUP_PETS = 2, // 52 spells in 3.0.3, pets mostly
+ SUMMON_GROUP_CONTROLLABLE = 3, // 13 spells in 3.0.3, mostly controllable
+ SUMMON_GROUP_UNKNOWN3 = 4 // 86 spells in 3.0.3, taxi/mounts
+};
+
+// SummonProperties.dbc, col 3
+enum SummonType
+{
+ SUMMON_TYPE_UNKNOWN = 0, // different summons, 1330 spells in 3.0.3
+ SUMMON_TYPE_SUMMON = 1, // generic summons, 49 spells in 3.0.3
+ SUMMON_TYPE_GUARDIAN = 2, // summon guardian, 393 spells in 3.0.3
+ SUMMON_TYPE_ARMY = 3, // summon army, 5 spells in 3.0.3
+ SUMMON_TYPE_TOTEM = 4, // summon totem, 169 spells in 3.0.3
+ SUMMON_TYPE_CRITTER = 5, // critter/minipet, 195 spells in 3.0.3
+ SUMMON_TYPE_DK = 6, // summon DRW/Ghoul, 2 spells in 3.0.3
+ SUMMON_TYPE_BOMB = 7, // summon bot/bomb, 4 spells in 3.0.3
+ SUMMON_TYPE_PHASING = 8, // something todo with DK prequest line, 2 spells in 3.0.3
+ SUMMON_TYPE_SIEGE_VEH = 9, // summon different vehicles, 14 spells in 3.0.3
+ SUMMON_TYPE_DRAKE_VEH = 10, // summon drake (vehicle), 3 spells
+ SUMMON_TYPE_LIGHTWELL = 11 // summon lightwell, 6 spells in 3.0.3
+};
+
+// SummonProperties.dbc, col 5
+enum SummonFlags
+{
+ SUMMON_FLAG_NONE = 0x0000, // 1342 spells in 3.0.3
+ SUMMON_FLAG_UNK1 = 0x0001, // 75 spells in 3.0.3, something unfriendly
+ SUMMON_FLAG_UNK2 = 0x0002, // 616 spells in 3.0.3, something friendly
+ SUMMON_FLAG_UNK3 = 0x0004, // 22 spells in 3.0.3, no idea...
+ SUMMON_FLAG_UNK4 = 0x0008, // 49 spells in 3.0.3, some mounts
+ SUMMON_FLAG_UNK5 = 0x0010, // 25 spells in 3.0.3, quest related?
+ SUMMON_FLAG_UNK6 = 0x0020, // 0 spells in 3.0.3, unused
+ SUMMON_FLAG_UNK7 = 0x0040, // 12 spells in 3.0.3, no idea
+ SUMMON_FLAG_UNK8 = 0x0080, // 4 spells in 3.0.3, no idea
+ SUMMON_FLAG_UNK9 = 0x0100, // 51 spells in 3.0.3, no idea, many quest related
+ SUMMON_FLAG_UNK10 = 0x0200, // 51 spells in 3.0.3, something defensive
+ SUMMON_FLAG_UNK11 = 0x0400, // 3 spells, requires something near?
+ SUMMON_FLAG_UNK12 = 0x0800, // 30 spells in 3.0.3, no idea
+ SUMMON_FLAG_UNK13 = 0x1000, // 8 spells in 3.0.3, siege vehicle
+ SUMMON_FLAG_UNK14 = 0x2000, // 2 spells in 3.0.3, escort?
+};
+*/
#endif
diff --git a/src/shared/Database/DBCStores.cpp b/src/shared/Database/DBCStores.cpp
index fb132c75768..9a5605060fb 100644
--- a/src/shared/Database/DBCStores.cpp
+++ b/src/shared/Database/DBCStores.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -32,12 +32,16 @@ typedef std::map<uint16,uint32> AreaFlagByAreaID;
typedef std::map<uint32,uint32> AreaFlagByMapID;
DBCStorage <AreaTableEntry> sAreaStore(AreaTableEntryfmt);
+DBCStorage <AreaGroupEntry> sAreaGroupStore(AreaGroupEntryfmt);
static AreaFlagByAreaID sAreaFlagByAreaID;
static AreaFlagByMapID sAreaFlagByMapID; // for instances without generated *.map files
+DBCStorage <AchievementEntry> sAchievementStore(Achievementfmt);
+DBCStorage <AchievementCriteriaEntry> sAchievementCriteriaStore(AchievementCriteriafmt);
DBCStorage <AreaTriggerEntry> sAreaTriggerStore(AreaTriggerEntryfmt);
DBCStorage <BankBagSlotPricesEntry> sBankBagSlotPricesStore(BankBagSlotPricesEntryfmt);
DBCStorage <BattlemasterListEntry> sBattlemasterListStore(BattlemasterListEntryfmt);
+DBCStorage <BarberShopStyleEntry> sBarberShopStyleStore(BarberShopStyleEntryfmt);
DBCStorage <CharStartOutfitEntry> sCharStartOutfitStore(CharStartOutfitEntryfmt);
DBCStorage <CharTitlesEntry> sCharTitlesStore(CharTitlesEntryfmt);
DBCStorage <ChatChannelsEntry> sChatChannelsStore(ChatChannelsEntryfmt);
@@ -46,6 +50,7 @@ DBCStorage <ChrRacesEntry> sChrRacesStore(ChrRacesEntryfmt);
DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore(CreatureDisplayInfofmt);
DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore(CreatureFamilyfmt);
DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore(CreatureSpellDatafmt);
+DBCStorage <CreatureTypeEntry> sCreatureTypeStore(CreatureTypefmt);
DBCStorage <DurabilityQualityEntry> sDurabilityQualityStore(DurabilityQualityfmt);
DBCStorage <DurabilityCostsEntry> sDurabilityCostsStore(DurabilityCostsfmt);
@@ -58,7 +63,10 @@ DBCStorage <FactionEntry> sFactionStore(FactionEntryfmt);
DBCStorage <FactionTemplateEntry> sFactionTemplateStore(FactionTemplateEntryfmt);
DBCStorage <GemPropertiesEntry> sGemPropertiesStore(GemPropertiesEntryfmt);
+DBCStorage <GlyphPropertiesEntry> sGlyphPropertiesStore(GlyphPropertiesfmt);
+DBCStorage <GlyphSlotEntry> sGlyphSlotStore(GlyphSlotfmt);
+DBCStorage <GtBarberShopCostBaseEntry> sGtBarberShopCostBaseStore(GtBarberShopCostBasefmt);
DBCStorage <GtCombatRatingsEntry> sGtCombatRatingsStore(GtCombatRatingsfmt);
DBCStorage <GtChanceToMeleeCritBaseEntry> sGtChanceToMeleeCritBaseStore(GtChanceToMeleeCritBasefmt);
DBCStorage <GtChanceToMeleeCritEntry> sGtChanceToMeleeCritStore(GtChanceToMeleeCritfmt);
@@ -84,6 +92,8 @@ DBCStorage <MapEntry> sMapStore(MapEntryfmt);
DBCStorage <QuestSortEntry> sQuestSortStore(QuestSortEntryfmt);
DBCStorage <RandomPropertiesPointsEntry> sRandomPropertiesPointsStore(RandomPropertiesPointsfmt);
+DBCStorage <ScalingStatDistributionEntry> sScalingStatDistributionStore(ScalingStatDistributionfmt);
+DBCStorage <ScalingStatValuesEntry> sScalingStatValuesStore(ScalingStatValuesfmt);
DBCStorage <SkillLineEntry> sSkillLineStore(SkillLinefmt);
DBCStorage <SkillLineAbilityEntry> sSkillLineAbilityStore(SkillLineAbilityfmt);
@@ -101,8 +111,10 @@ 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 <StableSlotPricesEntry> sStableSlotPricesStore(StableSlotPricesfmt);
+//DBCStorage <SummonPropertiesEntry> sSummonPropertiesStore(SummonPropertiesfmt);
DBCStorage <TalentEntry> sTalentStore(TalentEntryfmt);
TalentSpellPosMap sTalentSpellPosMap;
DBCStorage <TalentTabEntry> sTalentTabStore(TalentTabEntryfmt);
@@ -125,8 +137,11 @@ TaxiPathNodesByPath sTaxiPathNodesByPath;
static DBCStorage <TaxiPathNodeEntry> sTaxiPathNodeStore(TaxiPathNodeEntryfmt);
DBCStorage <TotemCategoryEntry> sTotemCategoryStore(TotemCategoryEntryfmt);
+DBCStorage <VehicleEntry> sVehicleStore(VehicleEntryfmt);
+DBCStorage <VehicleSeatEntry> sVehicleSeatStore(VehicleSeatEntryfmt);
DBCStorage <WorldMapAreaEntry> sWorldMapAreaStore(WorldMapAreaEntryfmt);
DBCStorage <WorldSafeLocsEntry> sWorldSafeLocsStore(WorldSafeLocsEntryfmt);
+DBCStorage <WorldMapOverlayEntry> sWorldMapOverlayStore(WorldMapOverlayEntryfmt);
typedef std::list<std::string> StoreProblemList;
@@ -178,7 +193,7 @@ void LoadDBCStores(const std::string& dataPath)
{
std::string dbcPath = dataPath+"dbc/";
- const uint32 DBCFilesCount = 56;
+ const uint32 DBCFilesCount = 70;
barGoLink bar( DBCFilesCount );
@@ -196,14 +211,18 @@ void LoadDBCStores(const std::string& dataPath)
sAreaFlagByAreaID.insert(AreaFlagByAreaID::value_type(uint16(area->ID),area->exploreFlag));
// fill MapId->DBC records ( skip sub zones and continents )
- if(area->zone==0 && area->mapid != 0 && area->mapid != 1 && area->mapid != 530 )
+ if(area->zone==0 && area->mapid != 0 && area->mapid != 1 && area->mapid != 530 && area->mapid != 571 )
sAreaFlagByMapID.insert(AreaFlagByMapID::value_type(area->mapid,area->exploreFlag));
}
}
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAchievementStore, dbcPath,"Achievement.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAchievementCriteriaStore, dbcPath,"Achievement_Criteria.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaTriggerStore, dbcPath,"AreaTrigger.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaGroupStore, dbcPath,"AreaGroup.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBankBagSlotPricesStore, dbcPath,"BankBagSlotPrices.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBattlemasterListStore, dbcPath,"BattlemasterList.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBarberShopStyleStore, dbcPath,"BarberShopStyle.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharStartOutfitStore, dbcPath,"CharStartOutfit.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharTitlesStore, dbcPath,"CharTitles.dbc");
@@ -213,6 +232,7 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureDisplayInfoStore, dbcPath,"CreatureDisplayInfo.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureFamilyStore, dbcPath,"CreatureFamily.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureSpellDataStore, dbcPath,"CreatureSpellData.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureTypeStore, dbcPath,"CreatureType.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sDurabilityCostsStore, dbcPath,"DurabilityCosts.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sDurabilityQualityStore, dbcPath,"DurabilityQuality.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sEmotesTextStore, dbcPath,"EmotesText.dbc");
@@ -229,7 +249,10 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sFactionTemplateStore, dbcPath,"FactionTemplate.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGemPropertiesStore, dbcPath,"GemProperties.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGlyphPropertiesStore, dbcPath,"GlyphProperties.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGlyphSlotStore, dbcPath,"GlyphSlot.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtBarberShopCostBaseStore,dbcPath,"gtBarberShopCostBase.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtCombatRatingsStore, dbcPath,"gtCombatRatings.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToMeleeCritBaseStore, dbcPath,"gtChanceToMeleeCritBase.dbc");
@@ -254,6 +277,8 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMapStore, dbcPath,"Map.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestSortStore, dbcPath,"QuestSort.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sRandomPropertiesPointsStore, dbcPath,"RandPropPoints.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sScalingStatDistributionStore, dbcPath,"ScalingStatDistribution.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sScalingStatValuesStore, dbcPath,"ScalingStatValues.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSkillLineStore, dbcPath,"SkillLine.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSkillLineAbilityStore, dbcPath,"SkillLineAbility.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSoundEntriesStore, dbcPath,"SoundEntries.dbc");
@@ -264,11 +289,11 @@ void LoadDBCStores(const std::string& dataPath)
if(spell && spell->Category)
sSpellCategoryStore[spell->Category].insert(i);
- // DBC not support uint64 fields but SpellEntry have SpellFamilyFlags mapped at 2 uint32 fields
+ /*// DBC not support uint64 fields but SpellEntry have SpellFamilyFlags mapped at 2 uint32 fields
// uint32 field already converted to bigendian if need, but must be swapped for correct uint64 bigendian view
#if TRINITY_ENDIAN == TRINITY_BIGENDIAN
std::swap(*((uint32*)(&spell->SpellFamilyFlags)),*(((uint32*)(&spell->SpellFamilyFlags))+1));
- #endif
+ #endif*/
}
for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
@@ -303,8 +328,10 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellItemEnchantmentConditionStore,dbcPath,"SpellItemEnchantmentCondition.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRadiusStore, dbcPath,"SpellRadius.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRangeStore, dbcPath,"SpellRange.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRuneCostStore, dbcPath,"SpellRuneCost.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellShapeshiftStore, dbcPath,"SpellShapeshiftForm.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sStableSlotPricesStore, dbcPath,"StableSlotPrices.dbc");
+ //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSummonPropertiesStore, dbcPath,"SummonProperties.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTalentStore, dbcPath,"Talent.dbc");
// create talent spells set
@@ -382,18 +409,6 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiNodesStore, dbcPath,"TaxiNodes.dbc");
- // Initialize global taxinodes mask
- memset(sTaxiNodesMask,0,sizeof(sTaxiNodesMask));
- for(uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i)
- {
- if(sTaxiNodesStore.LookupEntry(i))
- {
- uint8 field = (uint8)((i - 1) / 32);
- uint32 submask = 1<<((i-1)%32);
- sTaxiNodesMask[field] |= submask;
- }
- }
-
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiPathStore, dbcPath,"TaxiPath.dbc");
for(uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i)
if(TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i))
@@ -407,7 +422,10 @@ void LoadDBCStores(const std::string& dataPath)
pathLength.resize(pathCount); // 0 and some other indexes not used
for(uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i)
if(TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i))
- ++pathLength[entry->path];
+ {
+ if (pathLength[entry->path] < entry->index + 1)
+ pathLength[entry->path] = entry->index + 1;
+ }
// Set path length
sTaxiPathNodesByPath.resize(pathCount); // 0 and some other indexes not used
for(uint32 i = 1; i < sTaxiPathNodesByPath.size(); ++i)
@@ -418,9 +436,53 @@ void LoadDBCStores(const std::string& dataPath)
sTaxiPathNodesByPath[entry->path][entry->index] = TaxiPathNode(entry->mapid,entry->x,entry->y,entry->z,entry->actionFlag,entry->delay);
sTaxiPathNodeStore.Clear();
+ // Initialize global taxinodes mask
+ // 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 < 3; ++j)
+ if(sInfo->Effect[j]==123 /*SPELL_EFFECT_SEND_TAXI*/)
+ spellPaths.insert(sInfo->EffectMiscValue[j]);
+
+ memset(sTaxiNodesMask,0,sizeof(sTaxiNodesMask));
+ for(uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i)
+ {
+ if(!sTaxiNodesStore.LookupEntry(i))
+ continue;
+
+ TaxiPathSetBySource::const_iterator src_i = sTaxiPathSetBySource.find(i);
+ if(src_i!=sTaxiPathSetBySource.end() && !src_i->second.empty())
+ {
+ bool ok = false;
+ for(TaxiPathSetForSource::const_iterator dest_i = src_i->second.begin();dest_i != src_i->second.end(); ++dest_i)
+ {
+ // not spell path
+ if(spellPaths.find(dest_i->second.ID)==spellPaths.end())
+ {
+ ok = true;
+ break;
+ }
+ }
+
+ if(!ok)
+ continue;
+ }
+
+ // valid taxi netowrk node
+ uint8 field = (uint8)((i - 1) / 32);
+ uint32 submask = 1<<((i-1)%32);
+ sTaxiNodesMask[field] |= submask;
+ }
+ }
+
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTotemCategoryStore, dbcPath,"TotemCategory.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sVehicleStore, dbcPath,"Vehicle.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sVehicleSeatStore, dbcPath,"VehicleSeat.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldMapAreaStore, dbcPath,"WorldMapArea.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldSafeLocsStore, dbcPath,"WorldSafeLocs.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldMapOverlayStore, dbcPath,"WorldMapOverlay.dbc");
// error checks
if(bad_dbc_files.size() >= DBCFilesCount )
@@ -438,28 +500,22 @@ void LoadDBCStores(const std::string& dataPath)
exit(1);
}
- // check at up-to-date DBC files (53085 is last added spell in 2.4.3)
- // check at up-to-date DBC files (17514 is last ID in SkillLineAbilities in 2.4.3)
- // check at up-to-date DBC files (598 is last map added in 2.4.3)
- // check at up-to-date DBC files (1127 is last gem property added in 2.4.3)
- // check at up-to-date DBC files (2425 is last item extended cost added in 2.4.3)
- // check at up-to-date DBC files (71 is last char title added in 2.4.3)
- // check at up-to-date DBC files (1768 is last area added in 2.4.3)
- if( !sSpellStore.LookupEntry(53085) ||
- !sSkillLineAbilityStore.LookupEntry(17514) ||
- !sMapStore.LookupEntry(598) ||
- !sGemPropertiesStore.LookupEntry(1127) ||
- !sItemExtendedCostStore.LookupEntry(2425) ||
- !sCharTitlesStore.LookupEntry(71) ||
- !sAreaStore.LookupEntry(1768) )
+ // Check loaded DBC files proper version
+ if( !sSpellStore.LookupEntry(54909) || // last added spell in 3.0.8a
+ !sSpellStore.LookupEntry(49184) || // last added spell in 3.0.8a
+ sSpellStore.LookupEntry(49184)->RecoveryTime!=5000||// last changed spell in 3.0.8a
+ !sMapStore.LookupEntry(624) || // last map added in 3.0.8a
+ !sGemPropertiesStore.LookupEntry(1557) || // last gem property added in 3.0.8a
+ !sItemExtendedCostStore.LookupEntry(2589) || // last item extended cost added in 3.0.8a
+ !sCharTitlesStore.LookupEntry(144) || // last char title added in 3.0.8a
+ !sAreaStore.LookupEntry(2769) ) // last area (areaflag) added in 3.0.8a
{
sLog.outError("\nYou have _outdated_ DBC files. Please extract correct versions from current using client.");
exit(1);
}
sLog.outString();
- sLog.outString( ">> Loaded %d data stores", DBCFilesCount );
- sLog.outString();
+ sLog.outString( ">> Initialized %d data stores", DBCFilesCount );
}
SimpleFactionsList const* GetFactionTeamList(uint32 faction)
@@ -537,7 +593,7 @@ uint32 GetAreaFlagByMapId(uint32 mapid)
uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId)
{
- if(mapid != 530) // speed for most cases
+ if(mapid != 530 && mapid != 571) // speed for most cases
return mapid;
if(WorldMapAreaEntry const* wma = sWorldMapAreaStore.LookupEntry(zoneId))
diff --git a/src/shared/Database/DBCStores.h b/src/shared/Database/DBCStores.h
index 98a54fbeccf..dbe5e9d3bf4 100644
--- a/src/shared/Database/DBCStores.h
+++ b/src/shared/Database/DBCStores.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -132,9 +132,13 @@ class DBCStorage
StringPoolList m_stringPoolList;
};
+extern DBCStorage <AchievementEntry> sAchievementStore;
+extern DBCStorage <AchievementCriteriaEntry> sAchievementCriteriaStore;
extern DBCStorage <AreaTableEntry> sAreaStore;// recommend access using functions
+extern DBCStorage <AreaGroupEntry> sAreaGroupStore;
extern DBCStorage <AreaTriggerEntry> sAreaTriggerStore;
extern DBCStorage <BankBagSlotPricesEntry> sBankBagSlotPricesStore;
+extern DBCStorage <BarberShopStyleEntry> sBarberShopStyleStore;
extern DBCStorage <BattlemasterListEntry> sBattlemasterListStore;
//extern DBCStorage <ChatChannelsEntry> sChatChannelsStore; -- accessed using function, no usable index
extern DBCStorage <CharStartOutfitEntry> sCharStartOutfitStore;
@@ -144,13 +148,17 @@ extern DBCStorage <ChrRacesEntry> sChrRacesStore;
extern DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore;
extern DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore;
extern DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore;
+extern DBCStorage <CreatureTypeEntry> sCreatureTypeStore;
extern DBCStorage <DurabilityCostsEntry> sDurabilityCostsStore;
extern DBCStorage <DurabilityQualityEntry> sDurabilityQualityStore;
extern DBCStorage <EmotesTextEntry> sEmotesTextStore;
extern DBCStorage <FactionEntry> sFactionStore;
extern DBCStorage <FactionTemplateEntry> sFactionTemplateStore;
extern DBCStorage <GemPropertiesEntry> sGemPropertiesStore;
+extern DBCStorage <GlyphPropertiesEntry> sGlyphPropertiesStore;
+extern DBCStorage <GlyphSlotEntry> sGlyphSlotStore;
+extern DBCStorage <GtBarberShopCostBaseEntry> sGtBarberShopCostBaseStore;
extern DBCStorage <GtCombatRatingsEntry> sGtCombatRatingsStore;
extern DBCStorage <GtChanceToMeleeCritBaseEntry> sGtChanceToMeleeCritBaseStore;
extern DBCStorage <GtChanceToMeleeCritEntry> sGtChanceToMeleeCritStore;
@@ -171,6 +179,8 @@ extern DBCStorage <MailTemplateEntry> sMailTemplateStore;
extern DBCStorage <MapEntry> sMapStore;
extern DBCStorage <QuestSortEntry> sQuestSortStore;
extern DBCStorage <RandomPropertiesPointsEntry> sRandomPropertiesPointsStore;
+extern DBCStorage <ScalingStatDistributionEntry> sScalingStatDistributionStore;
+extern DBCStorage <ScalingStatValuesEntry> sScalingStatValuesStore;
extern DBCStorage <SkillLineEntry> sSkillLineStore;
extern DBCStorage <SkillLineAbilityEntry> sSkillLineAbilityStore;
extern DBCStorage <SoundEntriesEntry> sSoundEntriesStore;
@@ -183,9 +193,11 @@ extern SpellCategoryStore sSpellCategoryStore;
extern PetFamilySpellsStore sPetFamilySpellsStore;
extern DBCStorage <SpellRadiusEntry> sSpellRadiusStore;
extern DBCStorage <SpellRangeEntry> sSpellRangeStore;
+extern DBCStorage <SpellRuneCostEntry> sSpellRuneCostStore;
extern DBCStorage <SpellShapeshiftEntry> sSpellShapeshiftStore;
extern DBCStorage <SpellEntry> sSpellStore;
extern DBCStorage <StableSlotPricesEntry> sStableSlotPricesStore;
+//extern DBCStorage <SummonPropertiesEntry> sSummonPropertiesStore;
extern DBCStorage <TalentEntry> sTalentStore;
extern DBCStorage <TalentTabEntry> sTalentTabStore;
extern DBCStorage <TaxiNodesEntry> sTaxiNodesStore;
@@ -194,8 +206,11 @@ extern TaxiMask sTaxiNodesMask;
extern TaxiPathSetBySource sTaxiPathSetBySource;
extern TaxiPathNodesByPath sTaxiPathNodesByPath;
extern DBCStorage <TotemCategoryEntry> sTotemCategoryStore;
+extern DBCStorage <VehicleEntry> sVehicleStore;
+extern DBCStorage <VehicleSeatEntry> sVehicleSeatStore;
//extern DBCStorage <WorldMapAreaEntry> sWorldMapAreaStore; -- use Zone2MapCoordinates and Map2ZoneCoordinates
extern DBCStorage <WorldSafeLocsEntry> sWorldSafeLocsStore;
+extern DBCStorage <WorldMapOverlayEntry> sWorldMapOverlayStore;
void LoadDBCStores(const std::string& dataPath);
diff --git a/src/shared/Database/DBCStructure.h b/src/shared/Database/DBCStructure.h
index f2dc8222a72..d041f8fa3b2 100644
--- a/src/shared/Database/DBCStructure.h
+++ b/src/shared/Database/DBCStructure.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -23,6 +23,7 @@
#include "DBCEnums.h"
#include "Platform/Define.h"
+#include "Util.h"
#include <map>
#include <set>
@@ -37,57 +38,519 @@
#pragma pack(push,1)
#endif
-struct AreaTableEntry
+struct AchievementEntry
+{
+ uint32 ID; // 0
+ uint32 factionFlag; // 1 -1=all, 0=horde, 1=alliance
+ uint32 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 Criteria for complete
+ uint32 refAchievement; // 61 - related achievement?
+};
+
+struct AchievementCategoryEntry
{
uint32 ID; // 0
- 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
+ uint32 parentCategory; // 1 -1 for main category
+ //char *name[16]; // 2-17
+ //uint32 name_flags; // 18
+ //uint32 sortOrder; // 19
+};
+
+struct AchievementCriteriaEntry
+{
+ uint32 ID; // 0
+ uint32 referredAchievement; // 1
+ uint32 requiredType; // 2
+ union
+ {
+ // ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE = 0
+ // TODO: also used for player deaths..
+ struct
+ {
+ uint32 creatureID; // 3
+ uint32 creatureCount; // 4
+ } kill_creature;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_WIN_BG = 1
+ // TODO: there are further criterias instead just winning
+ struct
+ {
+ uint32 bgMapID; // 3
+ uint32 winCount; // 4
+ } win_bg;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL = 5
+ struct
+ {
+ uint32 unused; // 3
+ uint32 level; // 4
+ } reach_level;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL = 7
+ struct
+ {
+ uint32 skillID; // 3
+ uint32 skillLevel; // 4
+ } reach_skill_level;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT = 8
+ struct
+ {
+ uint32 linkedAchievement; // 3
+ } complete_achievement;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT = 9
+ struct
+ {
+ uint32 unused; // 3
+ uint32 totalQuestCount; // 4
+ } complete_quest_count;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY = 10
+ struct
+ {
+ uint32 unused; // 3
+ uint32 numberOfDays; // 4
+ } complete_daily_quest_daily;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE = 11
+ struct
+ {
+ uint32 zoneID; // 3
+ uint32 questCount; // 4
+ } complete_quests_in_zone;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST = 14
+ struct
+ {
+ uint32 unused; // 3
+ uint32 questCount; // 4
+ } complete_daily_quest;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND= 15
+ struct
+ {
+ uint32 mapID; // 3
+ } complete_battleground;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP= 16
+ struct
+ {
+ uint32 mapID; // 3
+ } death_at_map;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID = 19
+ struct
+ {
+ uint32 groupSize; // 3 can be 5, 10 or 25
+ } complete_raid;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE = 20
+ struct
+ {
+ uint32 creatureEntry; // 3
+ } killed_by_creature;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING = 24
+ struct
+ {
+ uint32 unused; // 3
+ uint32 fallHeight; // 4
+ } fall_without_dying;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM = 26
+ struct
+ {
+ uint32 type; // 0 - fatigue, 1 - drowning, 2 - falling, 3 - ??, 5 - fire and lava
+ } deaths;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST = 27
+ struct
+ {
+ uint32 questID; // 3
+ uint32 questCount; // 4
+ } complete_quest;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET = 28
+ // ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2= 69
+ struct
+ {
+ uint32 spellID; // 3
+ uint32 spellCount; // 4
+ } be_spell_target;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL= 29
+ // ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2 = 110
+ struct
+ {
+ uint32 spellID; // 3
+ uint32 castCount; // 4
+ } cast_spell;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA = 31
+ struct
+ {
+ uint32 areaID; // 3 Reference to AreaTable.dbc
+ uint32 killCount; // 4
+ } honorable_kill_at_area;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA = 32
+ struct
+ {
+ uint32 mapID; // 3 Reference to Map.dbc
+ } win_arena;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA = 33
+ struct
+ {
+ uint32 mapID; // 3 Reference to Map.dbc
+ } play_arena;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL = 34
+ struct
+ {
+ uint32 spellID; // 3 Reference to Map.dbc
+ } learn_spell;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM = 36
+ struct
+ {
+ uint32 itemID; // 3
+ uint32 itemCount; // 4
+ } own_item;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA = 37
+ struct
+ {
+ uint32 unused; // 3
+ uint32 count; // 4
+ uint32 flag; // 5 4=in a row
+ } win_rated_arena;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING = 38
+ struct
+ {
+ uint32 teamtype; // 3 {2,3,5}
+ } highest_team_rating;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_REACH_TEAM_RATING = 39
+ struct
+ {
+ uint32 teamtype; // 3 {2,3,5}
+ uint32 teamrating; // 4
+ } reach_team_rating;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL = 40
+ struct
+ {
+ uint32 skillID; // 3
+ uint32 skillLevel; // 4 apprentice=1, journeyman=2, expert=3, artisan=4, master=5, grand master=6
+ } learn_skill_level;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM = 41
+ struct
+ {
+ uint32 itemID; // 3
+ uint32 itemCount; // 4
+ } use_item;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM = 42
+ struct
+ {
+ uint32 itemID; // 3
+ uint32 itemCount; // 4
+ } loot_item;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA = 43
+ struct
+ {
+ // TODO: This rank is _NOT_ the index from AreaTable.dbc
+ uint32 areaReference; // 3
+ } explore_area;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_OWN_RANK= 44
+ struct
+ {
+ // TODO: This rank is _NOT_ the index from CharTitles.dbc
+ uint32 rank; // 3
+ } own_rank;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT= 45
+ struct
+ {
+ uint32 unused; // 3
+ uint32 numberOfSlots; // 4
+ } buy_bank_slot;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION= 46
+ struct
+ {
+ uint32 factionID; // 3
+ uint32 reputationAmount; // 4 Total reputation amount, so 42000 = exalted
+ } gain_reputation;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION= 47
+ struct
+ {
+ uint32 unused; // 3
+ uint32 numberOfExaltedFactions; // 4
+ } gain_exalted_reputation;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP = 48
+ struct
+ {
+ uint32 unused; // 3
+ uint32 numberOfVisits; // 4
+ } visit_barber;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM = 49
+ // TODO: where is the required itemlevel stored?
+ struct
+ {
+ uint32 itemSlot; // 3
+ } equip_epic_item;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT= 50
+ struct
+ {
+ uint32 rollValue; // 3
+ uint32 count; // 4
+ } roll_need_on_loot;
+ // ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT= 51
+ struct
+ {
+ uint32 rollValue; // 3
+ uint32 count; // 4
+ } roll_greed_on_loot;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS = 52
+ struct
+ {
+ uint32 classID; // 3
+ uint32 count; // 4
+ } hk_class;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_HK_RACE = 53
+ struct
+ {
+ uint32 raceID; // 3
+ uint32 count; // 4
+ } hk_race;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE = 54
+ // TODO: where is the information about the target stored?
+ struct
+ {
+ uint32 emoteID; // 3
+ } 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
+ uint32 count; // 4
+ uint32 flag; // 5 =3 for battleground healing
+ uint32 mapid; // 6
+ } healing_done;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM = 57
+ struct
+ {
+ uint32 itemID; // 3
+ } equip_item;
+
+
+ // ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY = 67
+ struct
+ {
+ uint32 unused; // 3
+ uint32 goldInCopper; // 4
+ } loot_money;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT = 68
+ struct
+ {
+ uint32 goEntry; // 3
+ uint32 useCount; // 4
+ } use_gameobject;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL= 70
+ // TODO: are those special criteria stored in the dbc or do we have to add another sql table?
+ struct
+ {
+ uint32 unused; // 3
+ uint32 killCount; // 4
+ } special_pvp_kill;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT = 72
+ struct
+ {
+ uint32 goEntry; // 3
+ uint32 lootCount; // 4
+ } fish_in_gameobject;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS= 75
+ struct
+ {
+ uint32 skillLine; // 3
+ uint32 spellCount; // 4
+ } learn_skilline_spell;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL = 76
+ struct
+ {
+ uint32 unused; // 3
+ uint32 duelCount; // 4
+ } win_duel;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_POWER = 96
+ struct
+ {
+ uint32 powerType; // 3 mana=0, 1=rage, 3=energy, 6=runic power
+ } highest_power;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_STAT = 97
+ struct
+ {
+ uint32 statType; // 3 4=spirit, 3=int, 2=stamina, 1=agi, 0=strength
+ } highest_stat;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_SPELLPOWER = 98
+ struct
+ {
+ uint32 spellSchool; // 3
+ } highest_spellpower;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_RATING = 100
+ struct
+ {
+ uint32 ratingType; // 3
+ } highest_rating;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE = 109
+ struct
+ {
+ uint32 lootType; // 3 3=fishing, 2=pickpocket, 4=disentchant
+ uint32 lootTypeCount; // 4
+ } loot_type;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE= 112
+ struct
+ {
+ uint32 skillLine; // 3
+ uint32 spellCount; // 4
+ } learn_skill_line;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL = 113
+ struct
+ {
+ uint32 unused; // 3
+ uint32 killCount; // 4
+ } honorable_kill;
+
+ struct
+ {
+ uint32 field3; // 3 main requirement
+ uint32 field4; // 4 main requirement count
+ uint32 additionalRequirement1_type; // 5 additional requirement 1 type
+ uint32 additionalRequirement1_value; // 6 additional requirement 1 value
+ uint32 additionalRequirement2_type; // 7 additional requirement 2 type
+ uint32 additionalRequirement2_value; // 8 additional requirement 1 value
+ } raw;
+ };
+ //char* name[16]; // 9-24
+ //uint32 name_flags; // 25
+ uint32 completionFlag; // 26
+ uint32 groupFlag; // 27
+ //uint32 unk1; // 28
+ uint32 timeLimit; // 29 time limit in seconds
+ //uint32 showOrder; // 30 show order
+};
+
+struct AreaTableEntry
+{
+ uint32 ID; // 0
+ 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
- int32 area_level; // 10
- char* area_name[16]; // 11-26
+ int32 area_level; // 10
+ char* area_name[16]; // 11-26
// 27, string flags, unused
- uint32 team; // 28
+ uint32 team; // 28
+};
+
+struct AreaGroupEntry
+{
+ uint32 AreaGroupId; // 0
+ uint32 AreaId[7]; // 1-7
};
struct AreaTriggerEntry
{
- uint32 id; // 0
- uint32 mapid; // 1
- float x; // 2
- float y; // 3
- float z; // 4
- float radius; // 5
- float box_x; // 6 extent x edge
- float box_y; // 7 extent y edge
- float box_z; // 8 extent z edge
- float box_orientation; // 9 extent rotation by about z axis
+ uint32 id; // 0 m_ID
+ uint32 mapid; // 1 m_ContinentID
+ 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
};
struct BankBagSlotPricesEntry
{
- uint32 ID;
- uint32 price;
+ uint32 ID;
+ uint32 price;
+};
+
+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
};
struct BattlemasterListEntry
{
- uint32 id; // 0
- uint32 mapid[3]; // 1-3 mapid
- // 4-8 unused
- uint32 type; // 9 (3 - BG, 4 - arena)
- uint32 minlvl; // 10
- uint32 maxlvl; // 11
- uint32 maxplayersperteam; // 12
- // 13-14 unused
- char* name[16]; // 15-30
- // 31 string flag, unused
- // 32 unused
+ uint32 id; // 0
+ int32 mapid[8]; // 1-8 mapid
+ uint32 type; // 9 (3 - BG, 4 - arena)
+ uint32 minlvl; // 10
+ uint32 maxlvl; // 11
+ uint32 maxplayersperteam; // 12
+ // 13 minplayers
+ // 14 0 or 9
+ // 15
+ char* name[16]; // 16-31
+ // 32 string flag, unused
+ // 33 unused
};
-#define MAX_OUTFIT_ITEMS 12
-// #define MAX_OUTFIT_ITEMS 24 // 12->24 in 3.0.x
+#define MAX_OUTFIT_ITEMS 24
struct CharStartOutfitEntry
{
@@ -103,20 +566,20 @@ struct CharStartOutfitEntry
struct CharTitlesEntry
{
- uint32 ID; // 0, title ids, for example in Quest::GetCharTitleId()
+ uint32 ID; // 0, title ids, for example in Quest::GetCharTitleId()
//uint32 unk1; // 1 flags?
//char* name[16]; // 2-17, unused
// 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
+ uint32 bit_index; // 36 used in PLAYER_CHOSEN_TITLE and 1<<index in PLAYER__FIELD_KNOWN_TITLES
};
struct ChatChannelsEntry
{
- uint32 ChannelID; // 0
- uint32 flags; // 1
- char* pattern[16]; // 3-18
+ 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
@@ -124,20 +587,21 @@ struct ChatChannelsEntry
struct ChrClassesEntry
{
- uint32 ClassID; // 0
- // 1-2, unused
- uint32 powerType; // 3
- // 4, unused
+ uint32 ClassID; // 0
+ // 1, unused
+ uint32 powerType; // 2
+ // 3-4, unused
//char* name[16]; // 5-20 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
+ uint32 spellfamily; // 56
// 57, unused
+ uint32 CinematicSequence; // 58 id from CinematicSequences.dbc
+ uint32 addon; // 59 (0 - original race, 1 - tbc addon, ...)
};
struct ChrRacesEntry
@@ -151,7 +615,7 @@ struct ChrRacesEntry
// 6-7 unused
uint32 TeamID; // 8 (7-Alliance 1-Horde)
// 9-12 unused
- uint32 startmovie; // 13 id from CinematicCamera.dbc
+ uint32 CinematicSequence; // 13 id from CinematicSequences.dbc
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
@@ -164,30 +628,51 @@ struct ChrRacesEntry
struct CreatureDisplayInfoEntry
{
- uint32 Displayid; // 0
- // 1-3,unused
- float scale; // 4
- // 5-13,unused
+ uint32 Displayid; // 0 m_ID
+ // 1 m_modelID
+ // 2 m_soundID
+ // 3 m_extendedDisplayInfoID
+ float scale; // 4 m_creatureModelScale
+ // 5 m_creatureModelAlpha
+ // 6-8 m_textureVariation[3]
+ // 9 m_portraitTextureName
+ // 10 m_sizeClass
+ // 11 m_bloodID
+ // 12 m_NPCSoundID
+ // 13 m_particleColorID
+ // 14 m_creatureGeosetData
+ // 15 m_objectEffectPackageID
};
struct CreatureFamilyEntry
{
- uint32 ID; // 0
- float minScale; // 1
- uint32 minScaleLevel; // 2 0/1
- float maxScale; // 3
- uint32 maxScaleLevel; // 4 0/60
- uint32 skillLine[2]; // 5-6
- uint32 petFoodMask; // 7
- char* Name[16]; // 8-23
- // 24 string flags, unused
- // 25 icon, unused
+ uint32 ID; // 0 m_ID
+ float minScale; // 1 m_minScale
+ uint32 minScaleLevel; // 2 m_minScaleLevel
+ float maxScale; // 3 m_maxScale
+ uint32 maxScaleLevel; // 4 m_maxScaleLevel
+ uint32 skillLine[2]; // 5-6 m_skillLine
+ 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
};
struct CreatureSpellDataEntry
{
- uint32 ID; // 0
- //uint32 spellId[4]; // 1-4 hunter pet learned spell (for later use)
+ uint32 ID; // 0 m_ID
+ //uint32 spellId[4]; // 1-4 m_spells[4]
+ //uint32 availability[4]; // 4-7 m_availability[4]
+};
+
+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.
};
struct DurabilityCostsEntry
@@ -204,41 +689,35 @@ struct DurabilityQualityEntry
struct EmotesTextEntry
{
- uint32 Id;
- uint32 textid;
+ uint32 Id;
+ uint32 textid;
};
struct FactionEntry
{
- uint32 ID; // 0
- int32 reputationListID; // 1
- uint32 BaseRepRaceMask[4]; // 2-5 Base reputation race masks (see enum Races)
- uint32 BaseRepClassMask[4]; // 6-9 Base reputation class masks (see enum Classes)
- int32 BaseRepValue[4]; // 10-13 Base reputation values
- uint32 ReputationFlags[4]; // 14-17 Default flags to apply
- uint32 team; // 18 enum Team
- char* name[16]; // 19-34
- // 35 string flags, unused
- //char* description[16]; // 36-51 unused
- // 52 string flags, unused
+ uint32 ID; // 0 m_ID
+ int32 reputationListID; // 1 m_reputationIndex
+ uint32 BaseRepRaceMask[4]; // 2-5 m_reputationRaceMask
+ uint32 BaseRepClassMask[4]; // 6-9 m_reputationClassMask
+ int32 BaseRepValue[4]; // 10-13 m_reputationBase
+ uint32 ReputationFlags[4]; // 14-17 m_reputationFlags
+ uint32 team; // 18 m_parentFactionID
+ char* name[16]; // 19-34 m_name_lang
+ // 35 string flags
+ //char* description[16]; // 36-51 m_description_lang
+ // 52 string flags
};
struct FactionTemplateEntry
{
- uint32 ID; // 0
- uint32 faction; // 1
- uint32 factionFlags; // 2 specific flags for that faction
- uint32 ourMask; // 3 if mask set (see FactionMasks) then faction included in masked team
- uint32 friendlyMask; // 4 if mask set (see FactionMasks) then faction friendly to masked team
- uint32 hostileMask; // 5 if mask set (see FactionMasks) then faction hostile to masked team
- uint32 enemyFaction1; // 6
- uint32 enemyFaction2; // 7
- uint32 enemyFaction3; // 8
- uint32 enemyFaction4; // 9
- uint32 friendFaction1; // 10
- uint32 friendFaction2; // 11
- uint32 friendFaction3; // 12
- uint32 friendFaction4; // 13
+ uint32 ID; // 0 m_ID
+ uint32 faction; // 1 m_faction
+ uint32 factionFlags; // 2 m_flags
+ uint32 ourMask; // 3 m_factionGroup
+ uint32 friendlyMask; // 4 m_friendGroup
+ uint32 hostileMask; // 5 m_enemyGroup
+ uint32 enemyFaction[4]; // 6 m_enemies[4]
+ uint32 friendFaction[4]; // 10 m_friend[4]
//------------------------------------------------------- end structure
// helpers
@@ -246,9 +725,9 @@ struct FactionTemplateEntry
{
if(ID == entry.ID)
return true;
- if(enemyFaction1 == entry.faction || enemyFaction2 == entry.faction || enemyFaction3 == entry.faction || enemyFaction4 == entry.faction )
+ if(enemyFaction[0] == entry.faction || enemyFaction[1] == entry.faction || enemyFaction[2] == entry.faction || enemyFaction[3] == entry.faction )
return false;
- if(friendFaction1 == entry.faction || friendFaction2 == entry.faction || friendFaction3 == entry.faction || friendFaction4 == entry.faction )
+ if(friendFaction[0] == entry.faction || friendFaction[1] == entry.faction || friendFaction[2] == entry.faction || friendFaction[3] == entry.faction )
return true;
return (friendlyMask & entry.ourMask) || (ourMask & entry.friendlyMask);
}
@@ -256,14 +735,14 @@ struct FactionTemplateEntry
{
if(ID == entry.ID)
return false;
- if(enemyFaction1 == entry.faction || enemyFaction2 == entry.faction || enemyFaction3 == entry.faction || enemyFaction4 == entry.faction )
+ if(enemyFaction[0] == entry.faction || enemyFaction[1] == entry.faction || enemyFaction[2] == entry.faction || enemyFaction[3] == entry.faction )
return true;
- if(friendFaction1 == entry.faction || friendFaction2 == entry.faction || friendFaction3 == entry.faction || friendFaction4 == entry.faction )
+ if(friendFaction[0] == entry.faction || friendFaction[1] == entry.faction || friendFaction[2] == entry.faction || friendFaction[3] == entry.faction )
return false;
return (hostileMask & entry.ourMask) != 0;
}
bool IsHostileToPlayers() const { return (hostileMask & FACTION_MASK_PLAYER) !=0; }
- bool IsNeutralToAll() const { return hostileMask == 0 && friendlyMask == 0 && enemyFaction1==0 && enemyFaction2==0 && enemyFaction3==0 && enemyFaction4==0; }
+ bool IsNeutralToAll() const { return hostileMask == 0 && friendlyMask == 0 && enemyFaction[0]==0 && enemyFaction[1]==0 && enemyFaction[2]==0 && enemyFaction[3]==0; }
bool IsContestedGuardFaction() const { return (factionFlags & FACTION_TEMPLATE_FLAG_CONTESTED_GUARD)!=0; }
};
@@ -274,9 +753,29 @@ struct GemPropertiesEntry
uint32 color;
};
+struct GlyphPropertiesEntry
+{
+ uint32 Id;
+ uint32 SpellId;
+ uint32 TypeFlags;
+ uint32 Unk1; // GlyphIconId (SpellIcon.dbc)
+};
+
+struct GlyphSlotEntry
+{
+ uint32 Id;
+ uint32 TypeFlags;
+ uint32 Order;
+};
+
// All Gt* DBC store data for 100 levels, some by 100 per class/race
#define GT_MAX_LEVEL 100
+struct GtBarberShopCostBaseEntry
+{
+ float cost;
+};
+
struct GtCombatRatingsEntry
{
float ratio;
@@ -324,24 +823,38 @@ struct GtRegenMPPerSptEntry
struct ItemEntry
{
- uint32 ID;
- uint32 DisplayId;
- uint32 InventoryType;
- uint32 Sheath;
+ uint32 ID; // 0
+ uint32 Class; // 1
+ //uint32 SubClass; // 2 some items have strnage subclasses
+ int32 Unk0; // 3
+ int32 Material; // 4
+ uint32 DisplayId; // 5
+ uint32 InventoryType; // 6
+ uint32 Sheath; // 7
};
struct ItemDisplayInfoEntry
{
- uint32 ID;
- uint32 randomPropertyChance;
+ uint32 ID; // 0 m_ID
+ // 1 m_modelName[2]
+ // 2 m_modelTexture[2]
+ // 3 m_inventoryIcon
+ // 4 m_geosetGroup[3]
+ // 5 m_flags
+ // 6 m_spellVisualID
+ // 7 m_groupSoundIndex
+ // 8 m_helmetGeosetVis[2]
+ // 9 m_texture[2]
+ // 10 m_itemVisual[8]
+ // 11 m_particleColorID
};
//struct ItemCondExtCostsEntry
//{
// uint32 ID;
-// uint32 condExtendedCost; // ItemPrototype::CondExtendedCost
-// uint32 itemextendedcostentry; // ItemPrototype::ExtendedCost
-// uint32 arenaseason; // arena season number(1-4)
+// uint32 condExtendedCost; // ItemPrototype::CondExtendedCost
+// uint32 itemextendedcostentry; // ItemPrototype::ExtendedCost
+// uint32 arenaseason; // arena season number(1-4)
//};
struct ItemExtendedCostEntry
@@ -356,47 +869,42 @@ struct ItemExtendedCostEntry
struct ItemRandomPropertiesEntry
{
- uint32 ID; // 0
- //char* internalName // 1 unused
- uint32 enchant_id[3]; // 2-4
- // 5-6 unused, 0 only values, reserved for additional enchantments?
- //char* nameSuffix[16] // 7-22, unused
- // 23 nameSufix flags, unused
+ uint32 ID; // 0 m_ID
+ //char* internalName // 1 m_Name
+ uint32 enchant_id[5]; // 2-6 m_Enchantment
+ //char* nameSuffix[16] // 7-22 m_name_lang
+ // 23 name flags
};
struct ItemRandomSuffixEntry
{
- uint32 ID; // 0
- //char* name[16] // 1-16 unused
- // 17, name flags, unused
- // 18 unused
- uint32 enchant_id[3]; // 19-21
- uint32 prefix[3]; // 22-24
+ uint32 ID; // 0 m_ID
+ //char* name[16] // 1-16 m_name_lang
+ // 17, name flags
+ // 18 m_internalName
+ uint32 enchant_id[5]; // 19-21 m_enchantment
+ uint32 prefix[5]; // 22-24 m_allocationPct
};
struct ItemSetEntry
{
- //uint32 id // 0 item set ID
- char* name[16]; // 1-16
+ //uint32 id // 0 m_ID
+ char* name[16]; // 1-16 m_name_lang
// 17 string flags, unused
- // 18-28 items from set, but not have all items listed, use ItemPrototype::ItemSet instead
- // 29-34 unused
- uint32 spells[8]; // 35-42
- uint32 items_to_triggerspell[8]; // 43-50
- uint32 required_skill_id; // 51
- uint32 required_skill_value; // 52
+ //uint32 itemId[17]; // 18-34 m_itemID
+ uint32 spells[8]; // 35-42 m_setSpellID
+ uint32 items_to_triggerspell[8]; // 43-50 m_setThreshold
+ uint32 required_skill_id; // 51 m_requiredSkill
+ uint32 required_skill_value; // 52 m_requiredSkillRank
};
struct LockEntry
{
- uint32 ID; // 0
- uint32 keytype[5]; // 1-5
- // 6-8, not used
- uint32 key[5]; // 9-13
- // 14-16, not used
- uint32 requiredminingskill; // 17
- uint32 requiredlockskill; // 18
- // 19-32, not used
+ uint32 ID; // 0 m_ID
+ uint32 Type[8]; // 1-8 m_Type
+ uint32 Index[8]; // 9-16 m_Index
+ uint32 Skill[8]; // 17-24 m_Skill
+ //uint32 Action[8]; // 25-32 m_Action
};
struct MailTemplateEntry
@@ -409,35 +917,34 @@ struct MailTemplateEntry
struct MapEntry
{
- uint32 MapID; // 0
+ uint32 MapID; // 0
//char* internalname; // 1 unused
- uint32 map_type; // 2
- // 3 unused
- char* name[16]; // 4-19
+ uint32 map_type; // 2
+ // 3 0 or 1 for battlegrounds (not arenas)
+ char* name[16]; // 4-19
// 20 name flags, unused
- // 21-23 unused (something PvPZone related - levels?)
- // 24-26
- uint32 linked_zone; // 27 common zone for instance and continent map
- //char* hordeIntro // 28-43 text for PvP Zones
- // 44 intro text flags
- //char* allianceIntro // 45-60 text for PvP Zones
- // 46 intro text flags
- // 47-61 not used
- uint32 multimap_id; // 62
- // 63-65 not used
- //chat* unknownText1 // 66-81 unknown empty text fields, possible normal Intro text.
- // 82 text flags
- //chat* heroicIntroText // 83-98 heroic mode requirement text
- // 99 text flags
- //chat* unknownText2 // 100-115 unknown empty text fields
- // 116 text flags
- int32 entrance_map; // 117 map_id of entrance map
- float entrance_x; // 118 entrance x coordinate (if exist single entry)
- float entrance_y; // 119 entrance y coordinate (if exist single entry)
- uint32 resetTimeRaid; // 120
- uint32 resetTimeHeroic; // 121
- // 122-123
- uint32 addon; // 124 (0-original maps,1-tbc addon)
+ uint32 linked_zone; // 21 common zone for instance and continent map
+ //char* hordeIntro[16]; // 23-37 text for PvP Zones
+ // 38 intro text flags
+ //char* allianceIntro[16]; // 39-54 text for PvP Zones
+ // 55 intro text flags
+ uint32 multimap_id; // 56
+ // 57
+ //chat* unknownText1[16]; // 58-73 unknown empty text fields, possible normal Intro text.
+ // 74 text flags
+ //chat* heroicIntroText[16]; // 75-90 heroic mode requirement text
+ // 91 text flags
+ //chat* unknownText2[16]; // 92-107 unknown empty text fields
+ // 108 text flags
+ int32 entrance_map; // 109 map_id of entrance map
+ float entrance_x; // 110 entrance x coordinate (if exist single entry)
+ float entrance_y; // 111 entrance y coordinate (if exist single entry)
+ uint32 resetTimeRaid; // 112
+ uint32 resetTimeHeroic; // 113
+ // 114 all 0
+ // 115 -1, 0 and 720
+ uint32 addon; // 116 (0-original maps,1-tbc addon)
+ // 117 some kind of time?
// Helpers
uint32 Expansion() const { return addon; }
@@ -449,22 +956,29 @@ struct MapEntry
bool IsBattleGround() const { return map_type == MAP_BATTLEGROUND; }
bool IsBattleArena() const { return map_type == MAP_ARENA; }
bool IsBattleGroundOrArena() const { return map_type == MAP_BATTLEGROUND || map_type == MAP_ARENA; }
- bool SupportsHeroicMode() const { return resetTimeHeroic && !resetTimeRaid; }
+ bool SupportsHeroicMode() const { return resetTimeHeroic != 0; }
bool HasResetTime() const { return resetTimeHeroic || resetTimeRaid; }
bool IsMountAllowed() const
{
return !IsDungeon() ||
- MapID==568 || MapID==309 || MapID==209 || MapID==534 ||
- MapID==560 || MapID==509 || MapID==269;
+ MapID==209 || MapID==269 || MapID==309 || // TanarisInstance, CavernsOfTime, Zul'gurub
+ MapID==509 || MapID==534 || MapID==560 || // AhnQiraj, HyjalPast, HillsbradPast
+ MapID==568 || MapID==580 || MapID==615 || // ZulAman, Sunwell Plateau, Obsidian Sanctrum
+ MapID==616; // Eye Of Eternity
+ }
+
+ bool IsContinent() const
+ {
+ return MapID == 0 || MapID == 1 || MapID == 530 || MapID == 571;
}
};
struct QuestSortEntry
{
- uint32 id; // 0, sort id
- //char* name[16]; // 1-16, unused
- // 17 name flags, unused
+ uint32 id; // 0 m_ID
+ //char* name[16]; // 1-16 m_SortName_lang
+ // 17 name flags
};
struct RandomPropertiesPointsEntry
@@ -476,172 +990,198 @@ struct RandomPropertiesPointsEntry
uint32 UncommonPropertiesPoints[5]; // 12-16
};
+struct ScalingStatDistributionEntry
+{
+ uint32 Id;
+ uint32 StatMod[10];
+ uint32 Modifier[10];
+ uint32 MaxLevel;
+};
+
+struct ScalingStatValuesEntry
+{
+ uint32 Id;
+ uint32 Level;
+ uint32 Multiplier[17];
+};
+
//struct SkillLineCategoryEntry{
-// uint32 id; // 0 hidden key
-// char* name[16]; // 1 - 17 Category name
-// // 18 string flag
-// uint32 displayOrder; // Display order in character tab
+// uint32 id; // 0 m_ID
+// char* name[16]; // 1-17 m_name_lang
+// // 18 string flag
+// uint32 displayOrder; // 19 m_sortIndex
//};
//struct SkillRaceClassInfoEntry{
-// uint32 id; // 0
-// uint32 skillId; // 1 present some refrences to unknown skill
-// uint32 raceMask; // 2
-// uint32 classMask; // 3
-// uint32 flags; // 4 mask for some thing
-// uint32 reqLevel; // 5
-// uint32 skillTierId; // 6
-// uint32 skillCostID; // 7
+// uint32 id; // 0 m_ID
+// uint32 skillId; // 1 m_skillID
+// uint32 raceMask; // 2 m_raceMask
+// uint32 classMask; // 3 m_classMask
+// uint32 flags; // 4 m_flags
+// uint32 reqLevel; // 5 m_minLevel
+// uint32 skillTierId; // 6 m_skillTierID
+// uint32 skillCostID; // 7 m_skillCostIndex
//};
//struct SkillTiersEntry{
-// uint32 id; // 0
-// uint32 skillValue[16]; // 1-17 unknown possibly add value on learn?
-// uint32 maxSkillValue[16]; // Max value for rank
+// uint32 id; // 0 m_ID
+// uint32 skillValue[16]; // 1-17 m_cost
+// uint32 maxSkillValue[16]; // 18-32 m_valueMax
//};
struct SkillLineEntry
{
- uint32 id; // 0
- uint32 categoryId; // 1 (index from SkillLineCategory.dbc)
- //uint32 skillCostID; // 2 not used
- char* name[16]; // 3-18
- // 19 string flags, not used
- //char* description[16]; // 20-35, not used
- // 36 string flags, not used
- uint32 spellIcon; // 37
+ 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
+ // 55 m_canLink
};
struct SkillLineAbilityEntry
{
- uint32 id; // 0, INDEX
- uint32 skillId; // 1
- uint32 spellId; // 2
- uint32 racemask; // 3
- uint32 classmask; // 4
- //uint32 racemaskNot; // 5 always 0 in 2.4.2
- //uint32 classmaskNot; // 6 always 0 in 2.4.2
- uint32 req_skill_value; // 7 for trade skill.not for training.
- uint32 forward_spellid; // 8
- uint32 learnOnGetSkill; // 9 can be 1 or 2 for spells learned on get skill
- uint32 max_value; // 10
- uint32 min_value; // 11
- // 12-13, unknown, always 0
- uint32 reqtrainpoints; // 14
+ uint32 id; // 0 m_ID
+ uint32 skillId; // 1 m_skillLine
+ uint32 spellId; // 2 m_spell
+ uint32 racemask; // 3 m_raceMask
+ uint32 classmask; // 4 m_classMask
+ //uint32 racemaskNot; // 5 m_excludeRace
+ //uint32 classmaskNot; // 6 m_excludeClass
+ uint32 req_skill_value; // 7 m_minSkillLineRank
+ uint32 forward_spellid; // 8 m_supercededBySpell
+ 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]
};
struct SoundEntriesEntry
{
- uint32 Id; // 0, sound id
- //uint32 Type; // 1, sound type (10 generally for creature, etc)
- //char* InternalName; // 2, internal name, for use in lookup command for example
- //char* FileName[10]; // 3-12, file names
- //uint32 Unk13[10]; // 13-22, linked with file names?
- //char* Path; // 23
- // 24-28, unknown
+ uint32 Id; // 0 m_ID
+ //uint32 Type; // 1 m_soundType
+ //char* InternalName; // 2 m_name
+ //char* FileName[10]; // 3-12 m_File[10]
+ //uint32 Unk13[10]; // 13-22 m_Freq[10]
+ //char* Path; // 23 m_DirectoryBase
+ // 24 m_volumeFloat
+ // 25 m_flags
+ // 26 m_minDistance
+ // 27 m_distanceCutoff
+ // 28 m_EAXDef
};
struct SpellEntry
{
- uint32 Id; // 0 normally counted from 0 field (but some tools start counting from 1, check this before tool use for data view!)
- uint32 Category; // 1
- //uint32 castUI // 2 not used
- uint32 Dispel; // 3
- uint32 Mechanic; // 4
- uint32 Attributes; // 5
- uint32 AttributesEx; // 6
- uint32 AttributesEx2; // 7
- uint32 AttributesEx3; // 8
- uint32 AttributesEx4; // 9
- uint32 AttributesEx5; // 10
- //uint32 AttributesEx6; // 11 not used
- uint32 Stances; // 12
- uint32 StancesNot; // 13
- uint32 Targets; // 14
- uint32 TargetCreatureType; // 15
- uint32 RequiresSpellFocus; // 16
- uint32 FacingCasterFlags; // 17
- uint32 CasterAuraState; // 18
- uint32 TargetAuraState; // 19
- uint32 CasterAuraStateNot; // 20
- uint32 TargetAuraStateNot; // 21
- uint32 CastingTimeIndex; // 22
- uint32 RecoveryTime; // 23
- uint32 CategoryRecoveryTime; // 24
- uint32 InterruptFlags; // 25
- uint32 AuraInterruptFlags; // 26
- uint32 ChannelInterruptFlags; // 27
- uint32 procFlags; // 28
- uint32 procChance; // 29
- uint32 procCharges; // 30
- uint32 maxLevel; // 31
- uint32 baseLevel; // 32
- uint32 spellLevel; // 33
- uint32 DurationIndex; // 34
- uint32 powerType; // 35
- uint32 manaCost; // 36
- uint32 manaCostPerlevel; // 37
- uint32 manaPerSecond; // 38
- uint32 manaPerSecondPerLevel; // 39
- uint32 rangeIndex; // 40
- float speed; // 41
- //uint32 modalNextSpell; // 42
- uint32 StackAmount; // 43
- uint32 Totem[2]; // 44-45
- int32 Reagent[8]; // 46-53
- uint32 ReagentCount[8]; // 54-61
- int32 EquippedItemClass; // 62 (value)
- int32 EquippedItemSubClassMask; // 63 (mask)
- int32 EquippedItemInventoryTypeMask; // 64 (mask)
- uint32 Effect[3]; // 65-67
- int32 EffectDieSides[3]; // 68-70
- uint32 EffectBaseDice[3]; // 71-73
- float EffectDicePerLevel[3]; // 74-76
- float EffectRealPointsPerLevel[3]; // 77-79
- int32 EffectBasePoints[3]; // 80-82 (don't must be used in spell/auras explicitly, must be used cached Spell::m_currentBasePoints)
- uint32 EffectMechanic[3]; // 83-85
- uint32 EffectImplicitTargetA[3]; // 86-88
- uint32 EffectImplicitTargetB[3]; // 89-91
- uint32 EffectRadiusIndex[3]; // 92-94 - spellradius.dbc
- uint32 EffectApplyAuraName[3]; // 95-97
- uint32 EffectAmplitude[3]; // 98-100
- float EffectMultipleValue[3]; // 101-103
- uint32 EffectChainTarget[3]; // 104-106
- uint32 EffectItemType[3]; // 107-109
- int32 EffectMiscValue[3]; // 110-112
- int32 EffectMiscValueB[3]; // 113-115
- uint32 EffectTriggerSpell[3]; // 116-118
- float EffectPointsPerComboPoint[3]; // 119-121
- uint32 SpellVisual; // 122
- // 123 not used
- uint32 SpellIconID; // 124
- uint32 activeIconID; // 125
- //uint32 spellPriority; // 126
- char* SpellName[16]; // 127-142
- //uint32 SpellNameFlag; // 143
- char* Rank[16]; // 144-159
- //uint32 RankFlags; // 160
- //char* Description[16]; // 161-176 not used
- //uint32 DescriptionFlags; // 177 not used
- //char* ToolTip[16]; // 178-193 not used
- //uint32 ToolTipFlags; // 194 not used
- uint32 ManaCostPercentage; // 195
- uint32 StartRecoveryCategory; // 196
- uint32 StartRecoveryTime; // 197
- uint32 MaxTargetLevel; // 198
- uint32 SpellFamilyName; // 199
- uint64 SpellFamilyFlags; // 200+201
- uint32 MaxAffectedTargets; // 202
- uint32 DmgClass; // 203 defenseType
- uint32 PreventionType; // 204
- //uint32 StanceBarOrder; // 205 not used
- float DmgMultiplier[3]; // 206-208
- //uint32 MinFactionId; // 209 not used, and 0 in 2.4.2
- //uint32 MinReputation; // 210 not used, and 0 in 2.4.2
- //uint32 RequiredAuraVision; // 211 not used
- uint32 TotemCategory[2]; // 212-213
- uint32 AreaId; // 214
- uint32 SchoolMask; // 215 school mask
+ uint32 Id; // 0 m_ID
+ uint32 Category; // 1 m_category
+ uint32 Dispel; // 2 m_dispelType
+ uint32 Mechanic; // 3 m_mechanic
+ uint32 Attributes; // 4 m_attribute
+ 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 not used
+ uint32 Stances; // 11 m_shapeshiftMask
+ uint32 StancesNot; // 12 m_shapeshiftExclude
+ uint32 Targets; // 13 m_targets
+ uint32 TargetCreatureType; // 14 m_targetCreatureType
+ uint32 RequiresSpellFocus; // 15 m_requiresSpellFocus
+ uint32 FacingCasterFlags; // 16 m_facingCasterFlags
+ uint32 CasterAuraState; // 17 m_casterAuraState
+ uint32 TargetAuraState; // 18 m_targetAuraState
+ uint32 CasterAuraStateNot; // 19 m_excludeCasterAuraState
+ uint32 TargetAuraStateNot; // 20 m_excludeTargetAuraState
+ uint32 casterAuraSpell; // 21 m_casterAuraSpell
+ uint32 targetAuraSpell; // 22 m_targetAuraSpell
+ uint32 excludeCasterAuraSpell; // 23 m_excludeCasterAuraSpell
+ uint32 excludeTargetAuraSpell; // 24 m_excludeTargetAuraSpell
+ uint32 CastingTimeIndex; // 25 m_castingTimeIndex
+ uint32 RecoveryTime; // 26 m_recoveryTime
+ uint32 CategoryRecoveryTime; // 27 m_categoryRecoveryTime
+ uint32 InterruptFlags; // 28 m_interruptFlags
+ uint32 AuraInterruptFlags; // 29 m_auraInterruptFlags
+ uint32 ChannelInterruptFlags; // 30 m_channelInterruptFlags
+ uint32 procFlags; // 31 m_procTypeMask
+ uint32 procChance; // 32 m_procChance
+ uint32 procCharges; // 33 m_procCharges
+ uint32 maxLevel; // 34 m_maxLevel
+ uint32 baseLevel; // 35 m_baseLevel
+ uint32 spellLevel; // 36 m_spellLevel
+ uint32 DurationIndex; // 37 m_durationIndex
+ uint32 powerType; // 38 m_powerType
+ uint32 manaCost; // 39 m_manaCost
+ uint32 manaCostPerlevel; // 40 m_manaCostPerLevel
+ uint32 manaPerSecond; // 41 m_manaPerSecond
+ uint32 manaPerSecondPerLevel; // 42 m_manaPerSecondPerLeve
+ uint32 rangeIndex; // 43 m_rangeIndex
+ float speed; // 44 m_speed
+ //uint32 modalNextSpell; // 45 m_modalNextSpell not used
+ uint32 StackAmount; // 46 m_cumulativeAura
+ uint32 Totem[2]; // 47-48 m_totem
+ int32 Reagent[8]; // 49-56 m_reagent
+ uint32 ReagentCount[8]; // 57-64 m_reagentCount
+ int32 EquippedItemClass; // 65 m_equippedItemClass (value)
+ int32 EquippedItemSubClassMask; // 66 m_equippedItemSubclass (mask)
+ int32 EquippedItemInventoryTypeMask; // 67 m_equippedItemInvTypes (mask)
+ uint32 Effect[3]; // 68-70 m_effect
+ int32 EffectDieSides[3]; // 71-73 m_effectDieSides
+ uint32 EffectBaseDice[3]; // 74-76 m_effectBaseDice
+ float EffectDicePerLevel[3]; // 77-79 m_effectDicePerLevel
+ float EffectRealPointsPerLevel[3]; // 80-82 m_effectRealPointsPerLevel
+ int32 EffectBasePoints[3]; // 83-85 m_effectBasePoints (don't must be used in spell/auras explicitly, must be used cached Spell::m_currentBasePoints)
+ uint32 EffectMechanic[3]; // 86-88 m_effectMechanic
+ uint32 EffectImplicitTargetA[3]; // 89-91 m_implicitTargetA
+ uint32 EffectImplicitTargetB[3]; // 92-94 m_implicitTargetB
+ uint32 EffectRadiusIndex[3]; // 95-97 m_effectRadiusIndex - spellradius.dbc
+ uint32 EffectApplyAuraName[3]; // 98-100 m_effectAura
+ uint32 EffectAmplitude[3]; // 101-103 m_effectAuraPeriod
+ float EffectMultipleValue[3]; // 104-106 m_effectAmplitude
+ uint32 EffectChainTarget[3]; // 107-109 m_effectChainTargets
+ uint32 EffectItemType[3]; // 110-112 m_effectItemType
+ int32 EffectMiscValue[3]; // 113-115 m_effectMiscValue
+ int32 EffectMiscValueB[3]; // 116-118 m_effectMiscValueB
+ uint32 EffectTriggerSpell[3]; // 119-121 m_effectTriggerSpell
+ float EffectPointsPerComboPoint[3]; // 122-124 m_effectPointsPerCombo
+ flag96 EffectSpellClassMask[3]; //
+ uint32 SpellVisual[2]; // 134-135 m_spellVisualID
+ uint32 SpellIconID; // 136 m_spellIconID
+ uint32 activeIconID; // 137 m_activeIconID
+ //uint32 spellPriority; // 138 not used
+ char* SpellName[16]; // 139-154 m_name_lang
+ //uint32 SpellNameFlag; // 155 not used
+ char* Rank[16]; // 156-171 m_nameSubtext_lang
+ //uint32 RankFlags; // 172 not used
+ //char* Description[16]; // 173-188 m_description_lang not used
+ //uint32 DescriptionFlags; // 189 not used
+ //char* ToolTip[16]; // 190-205 m_auraDescription_lang not used
+ //uint32 ToolTipFlags; // 206 not used
+ uint32 ManaCostPercentage; // 207 m_manaCostPct
+ uint32 StartRecoveryCategory; // 208 m_startRecoveryCategory
+ uint32 StartRecoveryTime; // 209 m_startRecoveryTime
+ uint32 MaxTargetLevel; // 210 m_maxTargetLevel
+ uint32 SpellFamilyName; // 211 m_spellClassSet
+ flag96 SpellFamilyFlags; // 212-214
+ uint32 MaxAffectedTargets; // 215 m_maxTargets
+ uint32 DmgClass; // 216 m_defenseType
+ uint32 PreventionType; // 217 m_preventionType
+ //uint32 StanceBarOrder; // 218 m_stanceBarOrder not used
+ float DmgMultiplier[3]; // 219-221 m_effectChainAmplitude
+ //uint32 MinFactionId; // 222 m_minFactionID not used
+ //uint32 MinReputation; // 223 m_minReputation not used
+ //uint32 RequiredAuraVision; // 224 m_requiredAuraVision not used
+ uint32 TotemCategory[2]; // 225-226 m_requiredTotemCategoryID
+ int32 AreaGroupId; // 227 m_requiredAreaGroupId
+ uint32 SchoolMask; // 228 m_schoolMask
+ uint32 runeCostID; // 229 m_runeCostID
+ //uint32 spellMissileID; // 230 m_spellMissileID not used
private:
// prevent creating custom entries (copy data from original in fact)
@@ -690,6 +1230,16 @@ struct SpellRangeEntry
uint32 type;
};
+struct SpellRuneCostEntry
+{
+ uint32 ID; // 0
+ uint32 RuneCost[3]; // 1-3 (0=blood, 1=frost, 2=unholy)
+ uint32 runePowerGain; // 4
+
+ bool NoRuneCost() const { return RuneCost[0] == 0 && RuneCost[1] == 0 && RuneCost[2] == 0; }
+ bool NoRunicPowerGain() const { return runePowerGain == 0; }
+};
+
struct SpellShapeshiftEntry
{
uint32 ID; // 0
@@ -722,26 +1272,31 @@ struct SpellDurationEntry
struct SpellItemEnchantmentEntry
{
- uint32 ID; // 0
- uint32 type[3]; // 1-3
- uint32 amount[3]; // 4-6
- //uint32 amount2[3] // 7-9 always same as similar `amount` value
- uint32 spellid[3]; // 10-12
- char* description[16]; // 13-29
- // 30 description flags
- uint32 aura_id; // 31
- uint32 slot; // 32
- uint32 GemID; // 33
- uint32 EnchantmentCondition; // 34
+ uint32 ID; // 0 m_ID
+ //uint32 charges; // 1 m_charges
+ uint32 type[3]; // 2-4 m_effect[3]
+ uint32 amount[3]; // 5-7 m_effectPointsMin[3]
+ //uint32 amount2[3] // 8-10 m_effectPointsMax[3]
+ uint32 spellid[3]; // 11-13 m_effectArg[3]
+ 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
};
struct SpellItemEnchantmentConditionEntry
{
- uint32 ID;
- uint8 Color[5];
- uint8 Comparator[5];
- uint8 CompareColor[5];
- uint32 Value[5];
+ uint32 ID; // 0 m_ID
+ uint8 Color[5]; // 1-5 m_lt_operandType[5]
+ //uint32 LT_Operand[5]; // 6-10 m_lt_operand[5]
+ uint8 Comparator[5]; // 11-15 m_operator[5]
+ uint8 CompareColor[5]; // 15-20 m_rt_operandType[5]
+ uint32 Value[5]; // 21-25 m_rt_operand[5]
+ //uint8 Logic[5] // 25-30 m_logic[5]
};
struct StableSlotPricesEntry
@@ -750,6 +1305,16 @@ struct StableSlotPricesEntry
uint32 Price;
};
+/*struct SummonPropertiesEntry
+{
+ uint32 Id; // 0
+ uint32 Group; // 1, 0 - can't be controlled?, 1 - something guardian?, 2 - pet?, 3 - something controllable?, 4 - taxi/mount?
+ uint32 Unk2; // 2, 14 rows > 0
+ uint32 Type; // 3, see enum
+ uint32 Slot; // 4, 0-6
+ uint32 Flags; // 5
+};*/
+
struct TalentEntry
{
uint32 TalentID; // 0
@@ -761,53 +1326,59 @@ struct TalentEntry
uint32 DependsOn; // 13 index in Talent.dbc (TalentEntry)
// 14-15 not used
uint32 DependsOnRank; // 16
- // 17-19 not used
- uint32 DependsOnSpell; // 20 req.spell
+ // 17-18 not used
+ //uint32 unk1; // 19, 0 or 1
+ //uint32 unk2; // 20, all 0
+ //uint32 unkFlags1; // 21, related to hunter pet talents
+ //uint32 unkFlags2; // 22, related to hunter pet talents
};
struct TalentTabEntry
{
- uint32 TalentTabID; // 0
- //char* name[16]; // 1-16, unused
+ uint32 TalentTabID; // 0
+ //char* name[16]; // 1-16, unused
//uint32 nameFlags; // 17, unused
//unit32 spellicon; // 18
// 19 not used
- uint32 ClassMask; // 20
- uint32 tabpage; // 21
- //char* internalname; // 22
+ uint32 ClassMask; // 20
+ uint32 petTalentMask; // 21
+ uint32 tabpage; // 22
+ //char* internalname; // 23
};
struct TaxiNodesEntry
{
- uint32 ID; // 0
- uint32 map_id; // 1
- float x; // 2
- float y; // 3
- float z; // 4
- //char* name[16]; // 5-21
- // 22 string flags, unused
- uint32 horde_mount_type; // 23
- uint32 alliance_mount_type; // 24
+ uint32 ID; // 0 m_ID
+ uint32 map_id; // 1 m_ContinentID
+ 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]
};
struct TaxiPathEntry
{
- uint32 ID;
- uint32 from;
- uint32 to;
- uint32 price;
+ uint32 ID; // 0 m_ID
+ uint32 from; // 1 m_FromTaxiNode
+ uint32 to; // 2 m_ToTaxiNode
+ uint32 price; // 3 m_Cost
};
struct TaxiPathNodeEntry
{
- uint32 path;
- uint32 index;
- uint32 mapid;
- float x;
- float y;
- float z;
- uint32 actionFlag;
- uint32 delay;
+ // 0 m_ID
+ uint32 path; // 1 m_PathID
+ uint32 index; // 2 m_NodeIndex
+ uint32 mapid; // 3 m_ContinentID
+ float x; // 4 m_LocX
+ float y; // 5 m_LocY
+ float z; // 6 m_LocZ
+ uint32 actionFlag; // 7 m_flags
+ uint32 delay; // 8 m_delay
+ // 9 m_arrivalEventID
+ // 10 m_departureEventID
};
struct TotemCategoryEntry
@@ -819,16 +1390,100 @@ struct TotemCategoryEntry
uint32 categoryMask; // 19 (compatibility mask for same type: different for totems, compatible from high to low for rods)
};
+struct VehicleEntry
+{
+ uint32 m_ID; // 0
+ uint32 m_flags; // 1
+ float m_turnSpeed; // 2
+ float m_pitchSpeed; // 3
+ float m_pitchMin; // 4
+ float m_pitchMax; // 5
+ uint32 m_seatID[8]; // 6-13
+ float m_mouseLookOffsetPitch; // 14
+ float m_cameraFadeDistScalarMin; // 15
+ float m_cameraFadeDistScalarMax; // 16
+ float m_cameraPitchOffset; // 17
+ int m_powerType[3]; // 18-20
+ int m_powerToken[3]; // 21-23
+ float m_facingLimitRight; // 24
+ float m_facingLimitLeft; // 25
+ float m_msslTrgtTurnLingering; // 26
+ float m_msslTrgtPitchLingering; // 27
+ float m_msslTrgtMouseLingering; // 28
+ float m_msslTrgtEndOpacity; // 29
+ float m_msslTrgtArcSpeed; // 30
+ float m_msslTrgtArcRepeat; // 31
+ float m_msslTrgtArcWidth; // 32
+ float m_msslTrgtImpactRadius[2]; // 33-34
+ char* m_msslTrgtArcTexture; // 35
+ char* m_msslTrgtImpactTexture; // 36
+ char* m_msslTrgtImpactModel[2]; // 37-38
+ float m_cameraYawOffset; // 39
+ uint32 m_uiLocomotionType; // 40
+ float m_msslTrgtImpactTexRadius; // 41
+ uint32 m_uiSeatIndicatorType; // 42
+};
+
+struct VehicleSeatEntry
+{
+ uint32 m_ID; // 0
+ uint32 m_flags; // 1
+ int32 m_attachmentID; // 2
+ float m_attachmentOffsetX; // 3
+ float m_attachmentOffsetY; // 4
+ float m_attachmentOffsetZ; // 5
+ float m_enterPreDelay; // 6
+ float m_enterSpeed; // 7
+ float m_enterGravity; // 8
+ float m_enterMinDuration; // 9
+ float m_enterMaxDuration; // 10
+ float m_enterMinArcHeight; // 11
+ float m_enterMaxArcHeight; // 12
+ int32 m_enterAnimStart; // 13
+ int32 m_enterAnimLoop; // 14
+ int32 m_rideAnimStart; // 15
+ int32 m_rideAnimLoop; // 16
+ int32 m_rideUpperAnimStart; // 17
+ int32 m_rideUpperAnimLoop; // 18
+ float m_exitPreDelay; // 19
+ float m_exitSpeed; // 20
+ float m_exitGravity; // 21
+ float m_exitMinDuration; // 22
+ float m_exitMaxDuration; // 23
+ float m_exitMinArcHeight; // 24
+ float m_exitMaxArcHeight; // 25
+ int32 m_exitAnimStart; // 26
+ int32 m_exitAnimLoop; // 27
+ int32 m_exitAnimEnd; // 28
+ float m_passengerYaw; // 29
+ float m_passengerPitch; // 30
+ float m_passengerRoll; // 31
+ int32 m_passengerAttachmentID; // 32
+ int32 m_vehicleEnterAnim; // 33
+ int32 m_vehicleExitAnim; // 34
+ int32 m_vehicleRideAnimLoop; // 35
+ int32 m_vehicleEnterAnimBone; // 36
+ int32 m_vehicleExitAnimBone; // 37
+ int32 m_vehicleRideAnimLoopBone; // 38
+ float m_vehicleEnterAnimDelay; // 39
+ float m_vehicleExitAnimDelay; // 40
+ uint32 m_vehicleAbilityDisplay; // 41
+ uint32 m_enterUISoundID; // 42
+ uint32 m_exitUISoundID; // 43
+ int32 m_uiSkin; // 44
+ uint32 m_flagsB; // 45
+};
+
struct WorldMapAreaEntry
{
- //uint32 ID; // 0
- uint32 map_id; // 1
- uint32 area_id; // 2 index (continent 0 areas ignored)
- //char* internal_name // 3
- float y1; // 4
- float y2; // 5
- float x1; // 6
- float x2; // 7
+ //uint32 ID; // 0
+ uint32 map_id; // 1
+ uint32 area_id; // 2 index (continent 0 areas ignored)
+ //char* internal_name // 3
+ float y1; // 4
+ float y2; // 5
+ float x1; // 6
+ float x2; // 7
int32 virtual_map_id; // 8 -1 (map_id have correct map) other: virtual map where zone show (map_id - where zone in fact internally)
};
@@ -843,6 +1498,12 @@ struct WorldSafeLocsEntry
// 21 name flags, unused
};
+struct WorldMapOverlayEntry
+{
+ uint32 ID; // 0
+ uint32 areatableID; // 2
+};
+
// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform
#if defined( __GNUC__ )
#pragma pack()
@@ -888,6 +1549,6 @@ struct TaxiPathNode
typedef std::vector<TaxiPathNode> TaxiPathNodeList;
typedef std::vector<TaxiPathNodeList> TaxiPathNodesByPath;
-#define TaxiMaskSize 16
+#define TaxiMaskSize 12
typedef uint32 TaxiMask[TaxiMaskSize];
#endif
diff --git a/src/shared/Database/DBCfmt.cpp b/src/shared/Database/DBCfmt.cpp
index 57a81921d62..643e1828448 100644
--- a/src/shared/Database/DBCfmt.cpp
+++ b/src/shared/Database/DBCfmt.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -10,36 +10,41 @@
*
* 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
+ * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-const char AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxixxxxxx";
+const char Achievementfmt[]="niixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxxxxxxxxxi";
+const char AchievementCriteriafmt[]="niiiiiiiixxxxxxxxxxxxxxxxxiixix";
+const char AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxixxxxxxx";
+const char AreaGroupEntryfmt[]="niiiiiii";
const char AreaTriggerEntryfmt[]="niffffffff";
const char BankBagSlotPricesEntryfmt[]="ni";
-const char BattlemasterListEntryfmt[]="niiixxxxxiiiixxssssssssssssssssxx";
-const char CharStartOutfitEntryfmt[]="diiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxx";
-// 3*12 new item fields in 3.0.x
-//const char CharStartOutfitEntryfmt[]="diiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
+const char BarberShopStyleEntryfmt[]="nixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiii";
+const char BattlemasterListEntryfmt[]="niiiiiiiiiiiixxxssssssssssssssssxx";
+const char CharStartOutfitEntryfmt[]="diiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
const char CharTitlesEntryfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi";
const char ChatChannelsEntryfmt[]="iixssssssssssssssssxxxxxxxxxxxxxxxxxx";
// ChatChannelsEntryfmt, index not used (more compact store)
-//const char ChrClassesEntryfmt[]="nxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxix";
-const char ChrClassesEntryfmt[]="nxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxix";
+const char ChrClassesEntryfmt[]="nxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii";
const char ChrRacesEntryfmt[]="nxixiixxixxxxissssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi";
-const char CreatureDisplayInfofmt[]="nxxxfxxxxxxxxx";
-const char CreatureFamilyfmt[]="nfifiiiissssssssssssssssxx";
+const char CreatureDisplayInfofmt[]="nxxxfxxxxxxxxxxx";
+const char CreatureFamilyfmt[]="nfifiiiiixssssssssssssssssxx";
const char CreatureSpellDatafmt[]="nxxxxxxxx";
+const char CreatureTypefmt[]="nxxxxxxxxxxxxxxxxxx";
const char DurabilityCostsfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiii";
const char DurabilityQualityfmt[]="nf";
const char EmoteEntryfmt[]="nxixxxxxxxxxxxxxxxx";
const char FactionEntryfmt[]="niiiiiiiiiiiiiiiiiissssssssssssssssxxxxxxxxxxxxxxxxxx";
const char FactionTemplateEntryfmt[]="niiiiiiiiiiiii";
const char GemPropertiesEntryfmt[]="nixxi";
+const char GlyphPropertiesfmt[]="niii";
+const char GlyphSlotfmt[]="nii";
+const char GtBarberShopCostBasefmt[]="f";
const char GtCombatRatingsfmt[]="f";
const char GtChanceToMeleeCritBasefmt[]="f";
const char GtChanceToMeleeCritfmt[]="f";
@@ -49,36 +54,44 @@ const char GtOCTRegenHPfmt[]="f";
//const char GtOCTRegenMPfmt[]="f";
const char GtRegenHPPerSptfmt[]="f";
const char GtRegenMPPerSptfmt[]="f";
-const char Itemfmt[]="niii";
+const char Itemfmt[]="nixiiiii";
//const char ItemDisplayTemplateEntryfmt[]="nxxxxxxxxxxixxxxxxxxxxx";
//const char ItemCondExtCostsEntryfmt[]="xiii";
-const char ItemExtendedCostEntryfmt[]="niiiiiiiiiiiii";
-const char ItemRandomPropertiesfmt[]="nxiiixxxxxxxxxxxxxxxxxxx";
-const char ItemRandomSuffixfmt[]="nxxxxxxxxxxxxxxxxxxiiiiii";
+const char ItemExtendedCostEntryfmt[]="niiiiiiiiiiiiix";
+const char ItemRandomPropertiesfmt[]="nxiiiiixxxxxxxxxxxxxxxxx";
+const char ItemRandomSuffixfmt[]="nxxxxxxxxxxxxxxxxxxiiiiiiiiii";
const char ItemSetEntryfmt[]="dssssssssssssssssxxxxxxxxxxxxxxxxxxiiiiiiiiiiiiiiiiii";
-const char LockEntryfmt[]="niiiiixxxiiiiixxxiixxxxxxxxxxxxxx";
+const char LockEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx";
const char MailTemplateEntryfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
-const char MapEntryfmt[]="nxixssssssssssssssssxxxxxxxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiffiixxi";
+const char MapEntryfmt[]="nxixssssssssssssssssxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiffiixxix";
const char QuestSortEntryfmt[]="nxxxxxxxxxxxxxxxxx";
const char RandomPropertiesPointsfmt[]="niiiiiiiiiiiiiii";
-const char SkillLinefmt[]="nixssssssssssssssssxxxxxxxxxxxxxxxxxxi";
-const char SkillLineAbilityfmt[]="niiiixxiiiiixxi";
+const char ScalingStatDistributionfmt[]="niiiiiiiiiiiiiiiiiiiii";
+const char ScalingStatValuesfmt[]="iniiiiiiiiiiiiiiiii";
+const char SkillLinefmt[]="nixssssssssssssssssxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxx";
+const char SkillLineAbilityfmt[]="niiiixxiiiiixx";
const char SoundEntriesfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
const char SpellCastTimefmt[]="nixx";
const char SpellDurationfmt[]="niii";
-const char SpellEntryfmt[]="nixiiiiiiiixiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffffffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffixiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiixfffxxxiiii";
+const char SpellEntryfmt[]="niiiiiiiiixiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffffffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiix";
const char SpellFocusObjectfmt[]="nxxxxxxxxxxxxxxxxx";
-const char SpellItemEnchantmentfmt[]="niiiiiixxxiiissssssssssssssssxiiii";
+const char SpellItemEnchantmentfmt[]="nxiiiiiixxxiiissssssssssssssssxiiiixx";
const char SpellItemEnchantmentConditionfmt[]="nbbbbbxxxxxbbbbbbbbbbiiiiiXXXXX";
const char SpellRadiusfmt[]="nfxf";
-const char SpellRangefmt[]="nffixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
+const char SpellRangefmt[]="nfxfxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
+const char SpellRuneCostfmt[]="niiii";
const char SpellShapeshiftfmt[]="nxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxx";
const char StableSlotPricesfmt[] = "ni";
-const char TalentEntryfmt[]="niiiiiiiixxxxixxixxxi";
-const char TalentTabEntryfmt[]="nxxxxxxxxxxxxxxxxxxxiix";
+//const char SummonPropertiesfmt[] = "niiiii";
+const char TalentEntryfmt[]="niiiiiiiixxxxixxixxxxxx";
+const char TalentTabEntryfmt[]="nxxxxxxxxxxxxxxxxxxxiiix";
const char TaxiNodesEntryfmt[]="nifffxxxxxxxxxxxxxxxxxii";
const char TaxiPathEntryfmt[]="niii";
const char TaxiPathNodeEntryfmt[]="diiifffiixx";
const char TotemCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxii";
-const char WorldMapAreaEntryfmt[]="xinxffffi";
+const char VehicleEntryfmt[]="niffffiiiiiiiiffffiiiiiifffffffffffssssfifi";
+const char VehicleSeatEntryfmt[]="niiffffffffffiiiiiifffffffiiifffiiiiiiiffiiiii";
+const char WorldMapAreaEntryfmt[]="xinxffffix";
const char WorldSafeLocsEntryfmt[]="nifffxxxxxxxxxxxxxxxxx";
+const char WorldMapOverlayEntryfmt[]="nxixxxxxxxxxxxxxx";
+
diff --git a/src/shared/Database/Database.cpp b/src/shared/Database/Database.cpp
index 4623deacbed..5d7f5bf473e 100644
--- a/src/shared/Database/Database.cpp
+++ b/src/shared/Database/Database.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Database/Database.h b/src/shared/Database/Database.h
index 7e64fbebb55..beff0fb740a 100644
--- a/src/shared/Database/Database.h
+++ b/src/shared/Database/Database.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -33,7 +33,7 @@ class SqlQueryHolder;
typedef UNORDERED_MAP<ZThread::ThreadImpl*, SqlTransaction*> TransactionQueues;
typedef UNORDERED_MAP<ZThread::ThreadImpl*, SqlResultQueue*> QueryQueues;
-#define MAX_QUERY_LEN 1024
+#define MAX_QUERY_LEN 32*1024
class TRINITY_DLL_SPEC Database
{
diff --git a/src/shared/Database/DatabaseEnv.h b/src/shared/Database/DatabaseEnv.h
index fe565cde7a6..df1f51adbe7 100644
--- a/src/shared/Database/DatabaseEnv.h
+++ b/src/shared/Database/DatabaseEnv.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Database/DatabaseImpl.h b/src/shared/Database/DatabaseImpl.h
index 244f52d0106..c9a02a0a4a1 100644
--- a/src/shared/Database/DatabaseImpl.h
+++ b/src/shared/Database/DatabaseImpl.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Database/DatabaseMysql.cpp b/src/shared/Database/DatabaseMysql.cpp
index 0fae83caadf..7e67861d883 100644
--- a/src/shared/Database/DatabaseMysql.cpp
+++ b/src/shared/Database/DatabaseMysql.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Database/DatabaseMysql.h b/src/shared/Database/DatabaseMysql.h
index ee800fdf22e..6dbaf4a59ab 100644
--- a/src/shared/Database/DatabaseMysql.h
+++ b/src/shared/Database/DatabaseMysql.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Database/DatabasePostgre.cpp b/src/shared/Database/DatabasePostgre.cpp
index 6a172bb12a0..8f8cf95b429 100644
--- a/src/shared/Database/DatabasePostgre.cpp
+++ b/src/shared/Database/DatabasePostgre.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Database/DatabasePostgre.h b/src/shared/Database/DatabasePostgre.h
index 7e541f84c73..9a2aeb84a07 100644
--- a/src/shared/Database/DatabasePostgre.h
+++ b/src/shared/Database/DatabasePostgre.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Database/DatabaseSqlite.cpp b/src/shared/Database/DatabaseSqlite.cpp
index 9de786bf739..a3fffd8aa4c 100644
--- a/src/shared/Database/DatabaseSqlite.cpp
+++ b/src/shared/Database/DatabaseSqlite.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Database/DatabaseSqlite.h b/src/shared/Database/DatabaseSqlite.h
index 325c3168acb..a9593989143 100644
--- a/src/shared/Database/DatabaseSqlite.h
+++ b/src/shared/Database/DatabaseSqlite.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Database/Field.cpp b/src/shared/Database/Field.cpp
index 20a88395b7e..18831e23687 100644
--- a/src/shared/Database/Field.cpp
+++ b/src/shared/Database/Field.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Database/Field.h b/src/shared/Database/Field.h
index 430e262c39e..a4514c963cd 100644
--- a/src/shared/Database/Field.h
+++ b/src/shared/Database/Field.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Database/Makefile.am b/src/shared/Database/Makefile.am
index 20cb2c87875..e5dce08653b 100644
--- a/src/shared/Database/Makefile.am
+++ b/src/shared/Database/Makefile.am
@@ -1,6 +1,6 @@
-# Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+# Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
#
-# Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+# Copyright (C) 2008-2009 Trinity <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
@@ -9,19 +9,19 @@
#
# 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
+# 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, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
## Process this file with automake to produce Makefile.in
## Sub-directories to parse
## CPP flags for includes, defines, etc.
-AM_CPPFLAGS = $(MYSQL_INCLUDES) $(POSTGRE_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(srcdir)/../../../dep/include -I$(srcdir)/../../framework -I$(srcdir)/../../shared -I$(srcdir)/../../../dep/include/g3dlite
+AM_CPPFLAGS = $(TRINI_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(srcdir)/../../../dep/include -I$(srcdir)/../../framework -I$(srcdir)/../../shared -I$(srcdir)/../../../dep/include/g3dlite
## Build MaNGOS shared library and its parts as convenience library.
# All libraries will be convenience libraries. Might be changed to shared
@@ -29,36 +29,38 @@ AM_CPPFLAGS = $(MYSQL_INCLUDES) $(POSTGRE_INCLUDES) -I$(top_builddir)/src/shared
noinst_LIBRARIES = libmangosdatabase.a
libmangosdatabase_a_SOURCES = \
- DBCStores.cpp \
- DBCStores.h \
- DBCStructure.h \
- DBCfmt.cpp \
- Database.cpp \
- Database.h \
- DatabaseEnv.h \
- DatabaseImpl.h \
- DatabaseMysql.cpp \
- DatabasePostgre.cpp \
- DatabaseMysql.h \
- DatabasePostgre.h \
- DatabaseSqlite.cpp \
- DatabaseSqlite.h \
- Field.cpp \
- Field.h \
- MySQLDelayThread.h \
- PGSQLDelayThread.h \
- QueryResult.h \
- QueryResultMysql.cpp \
- QueryResultMysql.h \
- QueryResultPostgre.cpp \
- QueryResultPostgre.h \
- QueryResultSqlite.cpp \
- QueryResultSqlite.h \
- SQLStorage.cpp \
- SQLStorage.h \
- SqlDelayThread.cpp \
- SqlDelayThread.h \
- SqlOperations.cpp \
- SqlOperations.h \
- dbcfile.cpp \
- dbcfile.h
+ DBCStores.cpp \
+ DBCStores.h \
+ DBCStructure.h \
+ DBCfmt.cpp \
+ Database.cpp \
+ Database.h \
+ DatabaseEnv.h \
+ DatabaseImpl.h \
+ DatabaseMysql.cpp \
+ DatabasePostgre.cpp \
+ DatabaseMysql.h \
+ DatabasePostgre.h \
+ DatabaseSqlite.cpp \
+ DatabaseSqlite.h \
+ DBCEnums.h \
+ Field.cpp \
+ Field.h \
+ MySQLDelayThread.h \
+ PGSQLDelayThread.h \
+ QueryResult.h \
+ QueryResultMysql.cpp \
+ QueryResultMysql.h \
+ QueryResultPostgre.cpp \
+ QueryResultPostgre.h \
+ QueryResultSqlite.cpp \
+ QueryResultSqlite.h \
+ SQLStorage.cpp \
+ SQLStorage.h \
+ SQLStorageImpl.h \
+ SqlDelayThread.cpp \
+ SqlDelayThread.h \
+ SqlOperations.cpp \
+ SqlOperations.h \
+ dbcfile.cpp \
+ dbcfile.h
diff --git a/src/shared/Database/MySQLDelayThread.h b/src/shared/Database/MySQLDelayThread.h
index b01d88b6f72..5f3e66de722 100644
--- a/src/shared/Database/MySQLDelayThread.h
+++ b/src/shared/Database/MySQLDelayThread.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Database/PGSQLDelayThread.h b/src/shared/Database/PGSQLDelayThread.h
index 0525fb9f6d6..bd6a2bf962d 100644
--- a/src/shared/Database/PGSQLDelayThread.h
+++ b/src/shared/Database/PGSQLDelayThread.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Database/QueryResult.h b/src/shared/Database/QueryResult.h
index ab87fda59be..0fab7a3633b 100644
--- a/src/shared/Database/QueryResult.h
+++ b/src/shared/Database/QueryResult.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Database/QueryResultMysql.cpp b/src/shared/Database/QueryResultMysql.cpp
index 63808060b9f..8ae59b350d8 100644
--- a/src/shared/Database/QueryResultMysql.cpp
+++ b/src/shared/Database/QueryResultMysql.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Database/QueryResultMysql.h b/src/shared/Database/QueryResultMysql.h
index 79f5439ed06..39d2985ad77 100644
--- a/src/shared/Database/QueryResultMysql.h
+++ b/src/shared/Database/QueryResultMysql.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Database/QueryResultPostgre.cpp b/src/shared/Database/QueryResultPostgre.cpp
index 8ebe03ede64..e10905f0feb 100644
--- a/src/shared/Database/QueryResultPostgre.cpp
+++ b/src/shared/Database/QueryResultPostgre.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Database/QueryResultPostgre.h b/src/shared/Database/QueryResultPostgre.h
index ac7f31223ba..aa183ab4b96 100644
--- a/src/shared/Database/QueryResultPostgre.h
+++ b/src/shared/Database/QueryResultPostgre.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Database/QueryResultSqlite.cpp b/src/shared/Database/QueryResultSqlite.cpp
index 2bf64ed49ab..9a32e36bc84 100644
--- a/src/shared/Database/QueryResultSqlite.cpp
+++ b/src/shared/Database/QueryResultSqlite.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Database/QueryResultSqlite.h b/src/shared/Database/QueryResultSqlite.h
index 1416ac426cc..d3462977e49 100644
--- a/src/shared/Database/QueryResultSqlite.h
+++ b/src/shared/Database/QueryResultSqlite.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Database/SQLStorage.cpp b/src/shared/Database/SQLStorage.cpp
index cd1c7908e46..2f4f4534b3a 100644
--- a/src/shared/Database/SQLStorage.cpp
+++ b/src/shared/Database/SQLStorage.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -27,20 +27,20 @@ extern DatabasePostgre WorldDatabase;
extern DatabaseMysql WorldDatabase;
#endif
-const char CreatureInfosrcfmt[]="iiiiiisssiiiiiiiiiiffiffiiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiilliiis";
-const char CreatureInfodstfmt[]="iiiiiisssiiiiiiiiiiffiffiiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiilliiii";
+const char CreatureInfosrcfmt[]="iiiiiisssiiiiiiiiiiffiffiiiiiiiiiiiffiiiiiiiiiiiiiiiiiiiiiiisiilliiis";
+const char CreatureInfodstfmt[]="iiiiiisssiiiiiiiiiiffiffiiiiiiiiiiiffiiiiiiiiiiiiiiiiiiiiiiisiilliiii";
const char CreatureDataAddonInfofmt[]="iiiiiiiis";
const char CreatureModelfmt[]="iffbi";
const char CreatureInfoAddonInfofmt[]="iiiiiiiis";
-const char EquipmentInfofmt[]="iiiiiiiiii";
+const char EquipmentInfofmt[]="iiii";
const char GameObjectInfosrcfmt[]="iiissiifiiiiiiiiiiiiiiiiiiiiiiiis";
const char GameObjectInfodstfmt[]="iiissiifiiiiiiiiiiiiiiiiiiiiiiiii";
-const char ItemPrototypesrcfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiffiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifsiiiii";
-const char ItemPrototypedstfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiffiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiiiiii";
+const char ItemPrototypesrcfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiffiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiisiiii";
+const char ItemPrototypedstfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiffiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiiiiiii";
const char PageTextfmt[]="isi";
const char SpellThreatfmt[]="ii";
-const char InstanceTemplatesrcfmt[]="iiiiiiffffs";
-const char InstanceTemplatedstfmt[]="iiiiiiffffi";
+const char InstanceTemplatesrcfmt[]="iiiiiiiffffs";
+const char InstanceTemplatedstfmt[]="iiiiiiiffffi";
SQLStorage sCreatureStorage(CreatureInfosrcfmt, CreatureInfodstfmt, "entry","creature_template");
SQLStorage sCreatureDataAddonStorage(CreatureDataAddonInfofmt,"guid","creature_addon");
diff --git a/src/shared/Database/SQLStorage.h b/src/shared/Database/SQLStorage.h
index 5a429d185cb..f2250410c26 100644
--- a/src/shared/Database/SQLStorage.h
+++ b/src/shared/Database/SQLStorage.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Database/SQLStorageImpl.h b/src/shared/Database/SQLStorageImpl.h
index 4f10c6eee05..b820d68619b 100644
--- a/src/shared/Database/SQLStorageImpl.h
+++ b/src/shared/Database/SQLStorageImpl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
+ * 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
diff --git a/src/shared/Database/SqlDelayThread.cpp b/src/shared/Database/SqlDelayThread.cpp
index a265b48e622..a35090adb7e 100644
--- a/src/shared/Database/SqlDelayThread.cpp
+++ b/src/shared/Database/SqlDelayThread.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Database/SqlDelayThread.h b/src/shared/Database/SqlDelayThread.h
index 093c1c843d0..1fc35741fc5 100644
--- a/src/shared/Database/SqlDelayThread.h
+++ b/src/shared/Database/SqlDelayThread.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -42,7 +42,7 @@ class SqlDelayThread : public ZThread::Runnable
SqlDelayThread(Database* db);
///< Put sql statement to delay queue
- inline bool Delay(SqlOperation* sql) { m_sqlQueue.add(sql); return true; }
+ bool Delay(SqlOperation* sql) { m_sqlQueue.add(sql); return true; }
virtual void Stop(); ///< Stop event
virtual void run(); ///< Main Thread loop
diff --git a/src/shared/Database/SqlOperations.cpp b/src/shared/Database/SqlOperations.cpp
index 1a81c4c96a1..233eed1e4cb 100644
--- a/src/shared/Database/SqlOperations.cpp
+++ b/src/shared/Database/SqlOperations.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Database/SqlOperations.h b/src/shared/Database/SqlOperations.h
index 0ebff9868d9..b7c84b5d6cf 100644
--- a/src/shared/Database/SqlOperations.h
+++ b/src/shared/Database/SqlOperations.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Database/dbcfile.cpp b/src/shared/Database/dbcfile.cpp
index 9f570e72496..f0b7e6e3c15 100644
--- a/src/shared/Database/dbcfile.cpp
+++ b/src/shared/Database/dbcfile.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Database/dbcfile.h b/src/shared/Database/dbcfile.h
index e0cef4dee5f..470322326aa 100644
--- a/src/shared/Database/dbcfile.h
+++ b/src/shared/Database/dbcfile.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Errors.h b/src/shared/Errors.h
index 0e8feb8424a..a521ae7f3f0 100644
--- a/src/shared/Errors.h
+++ b/src/shared/Errors.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Log.cpp b/src/shared/Log.cpp
index 9e910a4fcbf..2ed66ae3189 100644
--- a/src/shared/Log.cpp
+++ b/src/shared/Log.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Log.h b/src/shared/Log.h
index c4190264f3a..076d660be61 100644
--- a/src/shared/Log.h
+++ b/src/shared/Log.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Makefile.am b/src/shared/Makefile.am
index 3a86f148521..a5465f86c11 100644
--- a/src/shared/Makefile.am
+++ b/src/shared/Makefile.am
@@ -1,6 +1,6 @@
-# Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+# Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
#
-# Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+# Copyright (C) 2008-2009 Trinity <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
@@ -18,96 +18,40 @@
## Process this file with automake to produce Makefile.in
-## TODO move vmaps in src dir instead of src/shared
-
## Sub-directories to parse
-SUBDIRS = vmap
+SUBDIRS = Auth Config Database vmap
+
+## CPP flags for includes, defines, etc.
+AM_CPPFLAGS = $(TRINI_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(srcdir)/../../dep/include -I$(srcdir)/../framework -I$(srcdir)/../shared -I$(srcdir)/../../dep/include/g3dlite -DSYSCONFDIR=\"$(sysconfdir)/\"
+## AM_CPPFLAGS += -I$(srcdir)/../game -I$(srcdir)/../realmd
## Build MaNGOS shared library and its parts as convenience library.
# All libraries will be convenience libraries. Might be changed to shared
# later.
-noinst_LIBRARIES = libshared.a
-
-libshared_a_CPPFLAGS = \
-$(MYSQL_INCLUDES) \
-$(POSTGRE_INCLUDES) \
-$(TRINI_INCLUDES) \
--I$(top_srcdir)/dep/include \
--I$(top_srcdir)/src/framework
+noinst_LIBRARIES = libmangosshared.a
# libmangosshared library will later be reused by ...
-libshared_a_SOURCES = \
-$(srcdir)/Base.cpp \
-$(srcdir)/Base.h \
-$(srcdir)/ByteBuffer.h \
-$(srcdir)/Common.cpp \
-$(srcdir)/Common.h \
-$(srcdir)/Errors.h \
-$(srcdir)/Log.cpp \
-$(srcdir)/Log.h \
-$(srcdir)/Mthread.cpp \
-$(srcdir)/Mthread.h \
-$(srcdir)/ProgressBar.cpp \
-$(srcdir)/ProgressBar.h \
-$(srcdir)/Timer.h \
-$(srcdir)/Util.cpp \
-$(srcdir)/Util.h \
-$(srcdir)/WorldPacket.h \
-$(srcdir)/SystemConfig.h \
-$(srcdir)../game/IRCConf.h \
-$(srcdir)/Auth/AuthCrypt.cpp \
-$(srcdir)/Auth/AuthCrypt.h \
-$(srcdir)/Auth/BigNumber.cpp \
-$(srcdir)/Auth/BigNumber.h \
-$(srcdir)/Auth/Hmac.cpp \
-$(srcdir)/Auth/Hmac.h \
-$(srcdir)/Auth/Sha1.cpp \
-$(srcdir)/Auth/Sha1.h \
-$(srcdir)/Auth/md5.c \
-$(srcdir)/Auth/md5.h \
-$(srcdir)/Config/dotconfpp/dotconfpp.cpp \
-$(srcdir)/Config/dotconfpp/dotconfpp.h \
-$(srcdir)/Config/dotconfpp/mempool.cpp \
-$(srcdir)/Config/dotconfpp/mempool.h \
-$(srcdir)/Config/Config.cpp \
-$(srcdir)/Config/Config.h \
-$(srcdir)/Config/ConfigEnv.h \
-$(srcdir)/Database/DBCStores.cpp \
-$(srcdir)/Database/DBCStores.h \
-$(srcdir)/Database/DBCStructure.h \
-$(srcdir)/Database/DBCfmt.cpp \
-$(srcdir)/Database/Database.cpp \
-$(srcdir)/Database/Database.h \
-$(srcdir)/Database/DatabaseEnv.h \
-$(srcdir)/Database/DatabaseImpl.h \
-$(srcdir)/Database/DatabaseMysql.cpp \
-$(srcdir)/Database/DatabasePostgre.cpp \
-$(srcdir)/Database/DatabaseMysql.h \
-$(srcdir)/Database/DatabasePostgre.h \
-$(srcdir)/Database/DatabaseSqlite.cpp \
-$(srcdir)/Database/DatabaseSqlite.h \
-$(srcdir)/Database/Field.cpp \
-$(srcdir)/Database/Field.h \
-$(srcdir)/Database/MySQLDelayThread.h \
-$(srcdir)/Database/PGSQLDelayThread.h \
-$(srcdir)/Database/QueryResult.h \
-$(srcdir)/Database/QueryResultMysql.cpp \
-$(srcdir)/Database/QueryResultMysql.h \
-$(srcdir)/Database/QueryResultPostgre.cpp \
-$(srcdir)/Database/QueryResultPostgre.h \
-$(srcdir)/Database/QueryResultSqlite.cpp \
-$(srcdir)/Database/QueryResultSqlite.h \
-$(srcdir)/Database/SQLStorage.cpp \
-$(srcdir)/Database/SQLStorage.h \
-$(srcdir)/Database/SqlDelayThread.cpp \
-$(srcdir)/Database/SqlDelayThread.h \
-$(srcdir)/Database/SqlOperations.cpp \
-$(srcdir)/Database/SqlOperations.h \
-$(srcdir)/Database/dbcfile.cpp \
-$(srcdir)/Database/dbcfile.h \
-$(srcdir)/revision.h
-
+libmangosshared_a_SOURCES = \
+ Base.cpp \
+ Base.h \
+ ByteBuffer.h \
+ Common.cpp \
+ Common.h \
+ Errors.h \
+ Log.cpp \
+ Log.h \
+ MemoryLeaks.cpp \
+ MemoryLeaks.h \
+ ProgressBar.cpp \
+ ProgressBar.h \
+ Timer.h \
+ Util.cpp \
+ Util.h \
+ WorldPacket.h \
+ revision_nr.h \
+ revision.h
+# Get revision (git or svn)
# Get HG revision
REVISION_FILE = revision.h
diff --git a/src/shared/MemoryLeaks.cpp b/src/shared/MemoryLeaks.cpp
new file mode 100644
index 00000000000..ef7e36c3b57
--- /dev/null
+++ b/src/shared/MemoryLeaks.cpp
@@ -0,0 +1,32 @@
+/*
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "MemoryLeaks.h"
+#include "Policies/SingletonImp.h"
+
+INSTANTIATE_SINGLETON_1( MemoryManager ) ;
+
+MemoryManager::MemoryManager( )
+{
+ #if COMPILER == MICROSOFT
+ // standard leak check initialization
+ //_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+ // uncomment to disable Visual Leak Detector from code
+ //VLDDisable();
+ #endif
+}
diff --git a/src/shared/MemoryLeaks.h b/src/shared/MemoryLeaks.h
new file mode 100644
index 00000000000..fcea1f557b1
--- /dev/null
+++ b/src/shared/MemoryLeaks.h
@@ -0,0 +1,48 @@
+/*
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef TRINITYSERVER_MEMORY_H
+#define TRINITYSERVER_MEMORY_H
+
+#include "Platform/CompilerDefs.h"
+
+#if COMPILER == COMPILER_MICROSOFT
+
+#ifndef _WIN64
+// Visual Leak Detector support enabled
+//#include <vld/vld.h>
+// standard Visual Studio leak check disabled,
+//# define _CRTDBG_MAP_ALLOC
+//# include <stdlib.h>
+//# include <crtdbg.h>
+#else
+# define _CRTDBG_MAP_ALLOC
+# include <stdlib.h>
+# include <crtdbg.h>
+#endif
+
+#endif
+
+
+#include "Policies/Singleton.h"
+
+struct MemoryManager : public Trinity::Singleton < MemoryManager >
+{
+ MemoryManager();
+};
+#endif
diff --git a/src/shared/PacketLog.cpp b/src/shared/PacketLog.cpp
index 0ae6f198640..2fcd6c58b9b 100644
--- a/src/shared/PacketLog.cpp
+++ b/src/shared/PacketLog.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/PacketLog.h b/src/shared/PacketLog.h
index 3280d801261..b4313c48624 100644
--- a/src/shared/PacketLog.h
+++ b/src/shared/PacketLog.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/ProgressBar.cpp b/src/shared/ProgressBar.cpp
index 3cb09290485..0108dfec974 100644
--- a/src/shared/ProgressBar.cpp
+++ b/src/shared/ProgressBar.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/ProgressBar.h b/src/shared/ProgressBar.h
index 77f1e4c43ec..8c551ed65dc 100644
--- a/src/shared/ProgressBar.h
+++ b/src/shared/ProgressBar.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/ServiceWin32.cpp b/src/shared/ServiceWin32.cpp
index 2a152513977..878656b1d91 100644
--- a/src/shared/ServiceWin32.cpp
+++ b/src/shared/ServiceWin32.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/ServiceWin32.h b/src/shared/ServiceWin32.h
index fdc9d7d4e9e..762502ccaa7 100644
--- a/src/shared/ServiceWin32.h
+++ b/src/shared/ServiceWin32.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/SystemConfig.h b/src/shared/SystemConfig.h
index 9e7fe3e3045..7d0143085b4 100644
--- a/src/shared/SystemConfig.h
+++ b/src/shared/SystemConfig.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -28,7 +28,7 @@
#include "revision.h"
-#define _PACKAGENAME "TrinityCore "
+#define _PACKAGENAME "TC&MaNGOS "
#define _CODENAME "YUME"
#if TRINITY_ENDIAN == TRINITY_BIGENDIAN
diff --git a/src/shared/SystemConfig.h.in b/src/shared/SystemConfig.h.in
new file mode 100644
index 00000000000..6eff490b144
--- /dev/null
+++ b/src/shared/SystemConfig.h.in
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2009 Trinity <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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef TRINITY_SYSTEMCONFIG_H
+#define TRINITY_SYSTEMCONFIG_H
+
+#ifndef _PACKAGENAME
+#define _PACKAGENAME "TC&Mangos "
+#endif
+
+#include "Platform/Define.h"
+#include "revision.h" //-----here u are ------ _REVISION is the magic key
+
+#ifndef _VERSION
+#if PLATFORM == PLATFORM_WINDOWS
+# define _VERSION(REVD,REVT,REVN,REVH) "0.13.0-DEV" " (" REVD " " REVT " Revision " REVN " - " REVH ")"
+#else
+# define _VERSION(REVD,REVT,REVN,REVH) "@VERSION@" " (" REVD " " REVT " Revision " REVN " - " REVH ")"
+#endif
+#endif
+
+// Format is YYYYMMDDRR where RR is the change in the conf file
+// for that day.
+#ifndef _MANGOSDCONFVERSION
+# define _MANGOSDCONFVERSION 2008022901
+#endif
+#ifndef _REALMDCONFVERSION
+# define _REALMDCONFVERSION 2007062001
+#endif
+
+#if MANGOS_ENDIAN == MANGOS_BIGENDIAN
+# define _ENDIAN_STRING "big-endian"
+#else
+# define _ENDIAN_STRING "little-endian"
+#endif
+
+// The path to config files
+#ifndef SYSCONFDIR
+# define SYSCONFDIR ""
+#endif
+
+#if PLATFORM == PLATFORM_WINDOWS
+# ifdef _WIN64
+# define _ENDIAN_PLATFORM "Win64 (" _ENDIAN_STRING ")"
+# else
+# define _ENDIAN_PLATFORM "Win32 (" _ENDIAN_STRING ")"
+# endif
+# define _MANGOSD_CONFIG SYSCONFDIR"mangosd.conf"
+# define _REALMD_CONFIG SYSCONFDIR"realmd.conf"
+#else
+# define _ENDIAN_PLATFORM "Unix (" _ENDIAN_STRING ")"
+# define _MANGOSD_CONFIG SYSCONFDIR"mangosd.conf"
+# define _REALMD_CONFIG SYSCONFDIR"realmd.conf"
+#endif
+
+
+#define DEFAULT_PLAYER_LIMIT 100
+#define DEFAULT_WORLDSERVER_PORT 8085 //8129
+#define DEFAULT_REALMSERVER_PORT 3724
+#define DEFAULT_SOCKET_SELECT_TIME 10000
+#endif
diff --git a/src/shared/Timer.h b/src/shared/Timer.h
index 848a8cfac4f..30f5966afce 100644
--- a/src/shared/Timer.h
+++ b/src/shared/Timer.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/Util.cpp b/src/shared/Util.cpp
index 72b35319298..0d3010c5f04 100644
--- a/src/shared/Util.cpp
+++ b/src/shared/Util.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -36,27 +36,27 @@ static MTRandTSS mtRand;
int32 irand (int32 min, int32 max)
{
- return int32 (mtRand.get ().randInt (max - min)) + min;
+ return int32 (mtRand.get ().randInt (max - min)) + min;
}
uint32 urand (uint32 min, uint32 max)
{
- return mtRand.get ().randInt (max - min) + min;
+ return mtRand.get ().randInt (max - min) + min;
}
int32 rand32 ()
{
- return mtRand.get ().randInt ();
+ return mtRand.get ().randInt ();
}
double rand_norm(void)
{
- return mtRand.get ().randExc ();
+ return mtRand.get ().randExc ();
}
double rand_chance (void)
{
- return mtRand.get ().randExc (100.0);
+ return mtRand.get ().randExc (100.0);
}
Tokens StrSplit(const std::string &src, const std::string &sep)
diff --git a/src/shared/Util.h b/src/shared/Util.h
index 4b91a8ede4c..adfbdad620a 100644
--- a/src/shared/Util.h
+++ b/src/shared/Util.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -287,20 +287,20 @@ bool consoleToUtf8(const std::string& conStr,std::string& utf8str);
bool Utf8FitTo(const std::string& str, std::wstring search);
#if PLATFORM == PLATFORM_WINDOWS
-#define UTF8PRINTF(OUT,FRM,RESERR) \
-{ \
- char temp_buf[6000]; \
- va_list ap; \
- va_start(ap, FRM); \
- size_t temp_len = vsnprintf(temp_buf,6000,FRM,ap); \
- va_end(ap); \
- \
- wchar_t wtemp_buf[6000]; \
- size_t wtemp_len = 6000-1; \
+#define UTF8PRINTF(OUT,FRM,RESERR) \
+{ \
+ char temp_buf[32*1024]; \
+ va_list ap; \
+ va_start(ap, FRM); \
+ size_t temp_len = vsnprintf(temp_buf,32*1024,FRM,ap); \
+ va_end(ap); \
+ \
+ wchar_t wtemp_buf[32*1024]; \
+ size_t wtemp_len = 32*1024-1; \
if(!Utf8toWStr(temp_buf,temp_len,wtemp_buf,wtemp_len)) \
- return RESERR; \
+ return RESERR; \
CharToOemBuffW(&wtemp_buf[0],&temp_buf[0],wtemp_len+1);\
- fprintf(OUT,temp_buf); \
+ fprintf(OUT,temp_buf); \
}
#else
#define UTF8PRINTF(OUT,FRM,RESERR) \
@@ -316,3 +316,232 @@ bool IsIPAddress(char const* ipaddress);
uint32 CreatePIDFile(const std::string& filename);
#endif
+
+//handler for operations on large flags
+#ifndef _FLAG96
+#define _FLAG96
+
+class flag96
+{
+private:
+ uint32 part[3];
+public:
+ flag96(uint32 p1=0,uint32 p2=0,uint32 p3=0)
+ {
+ part[0]=p1;
+ part[1]=p2;
+ part[2]=p3;
+ }
+
+ inline bool IsEqual(uint32 p1=0, uint32 p2=0, uint32 p3=0) const
+ {
+ return (
+ part[0]==p1 &&
+ part[1]==p2 &&
+ part[2]==p3);
+ };
+
+ inline bool HasFlag(uint32 p1=0, uint32 p2=0, uint32 p3=0) const
+ {
+ return (
+ part[0]&p1 ||
+ part[1]&p2 ||
+ part[2]&p3);
+ };
+
+ inline void Set(uint32 p1=0, uint32 p2=0, uint32 p3=0)
+ {
+ part[0]=p1;
+ part[1]=p2;
+ part[2]=p3;
+ };
+
+ template<class type>
+ inline bool operator < (type & right)
+ {
+ for (uint8 i=3;i>0;i--)
+ {
+ if (part[i-1]<right.part[i-1])
+ return 1;
+ else if (part[i-1]>right.part[i-1])
+ return 0;
+ }
+ return 0;
+ };
+
+ template<class type>
+ inline bool operator < (type & right) const
+ {
+ for (uint8 i=3;i>0;i--)
+ {
+ if (part[i-1]<right.part[i-1])
+ return 1;
+ else if (part[i-1]>right.part[i-1])
+ return 0;
+ }
+ return 0;
+ };
+
+ template<class type>
+ inline bool operator != (type & right)
+ {
+ if (part[0]!=right.part[0]
+ || part[1]!=right.part[1]
+ || part[2]!=right.part[2])
+ return true;
+ return false;
+ }
+
+ template<class type>
+ inline bool operator != (type & right) const
+ {
+ if (part[0]!=right.part[0]
+ || part[1]!=right.part[1]
+ || part[2]!=right.part[2])
+ return true;
+ return false;
+ };
+
+ template<class type>
+ inline bool operator == (type & right)
+ {
+ if (part[0]!=right.part[0]
+ || part[1]!=right.part[1]
+ || part[2]!=right.part[2])
+ return false;
+ return true;
+ };
+
+ template<class type>
+ inline bool operator == (type & right) const
+ {
+ if (part[0]!=right.part[0]
+ || part[1]!=right.part[1]
+ || part[2]!=right.part[2])
+ return false;
+ return true;
+ };
+
+ template<class type>
+ inline void operator = (type & right)
+ {
+ part[0]=right.part[0];
+ part[1]=right.part[1];
+ part[2]=right.part[2];
+ };
+
+ template<class type>
+ inline flag96 operator & (type & right)
+ {
+ flag96 ret(part[0] & right.part[0],part[1] & right.part[1],part[2] & right.part[2]);
+ return
+ ret;
+ };
+ template<class type>
+ inline flag96 operator & (type & right) const
+ {
+ flag96 ret(part[0] & right.part[0],part[1] & right.part[1],part[2] & right.part[2]);
+ return
+ ret;
+ };
+
+ template<class type>
+ inline void operator &= (type & right)
+ {
+ *this=*this & right;
+ };
+
+ template<class type>
+ inline flag96 operator | (type & right)
+ {
+ flag96 ret(part[0] | right.part[0],part[1] | right.part[1],part[2] | right.part[2]);
+ return
+ ret;
+ };
+
+ template<class type>
+ inline flag96 operator | (type & right) const
+ {
+ flag96 ret(part[0] | right.part[0],part[1] | right.part[1],part[2] | right.part[2]);
+ return
+ ret;
+ };
+
+ template<class type>
+ inline void operator |= (type & right)
+ {
+ *this=*this | right;
+ };
+
+ inline void operator ~ ()
+ {
+ part[2]=~part[2];
+ part[1]=~part[1];
+ part[0]=~part[0];
+ };
+
+ template<class type>
+ inline flag96 operator ^ (type & right)
+ {
+ flag96 ret(part[0] ^ right.part[0],part[1] ^ right.part[1],part[2] ^ right.part[2]);
+ return
+ ret;
+ };
+
+ template<class type>
+ inline flag96 operator ^ (type & right) const
+ {
+ flag96 ret(part[0] ^ right.part[0],part[1] ^ right.part[1],part[2] ^ right.part[2]);
+ return
+ ret;
+ };
+
+ template<class type>
+ inline void operator ^= (type & right)
+ {
+ *this=*this^right;
+ };
+
+ inline operator bool() const
+ {
+ return(
+ part[0] != 0 ||
+ part[1] != 0 ||
+ part[2] != 0);
+ };
+
+ inline operator bool()
+ {
+ return(
+ part[0] != 0 ||
+ part[1] != 0 ||
+ part[2] != 0);
+ };
+
+ inline bool operator ! () const
+ {
+ return(
+ part[0] == 0 &&
+ part[1] == 0 &&
+ part[2] == 0);
+ };
+
+ inline bool operator ! ()
+ {
+ return(
+ part[0] == 0 &&
+ part[1] == 0 &&
+ part[2] == 0);
+ };
+
+ inline uint32 & operator[](uint8 el)
+ {
+ return (part[el]);
+ };
+
+ inline const uint32 & operator[](uint8 el) const
+ {
+ return (part[el]);
+ };
+};
+#endif
diff --git a/src/shared/WorldPacket.h b/src/shared/WorldPacket.h
index ee17047a9ef..4d30533d2f1 100644
--- a/src/shared/WorldPacket.h
+++ b/src/shared/WorldPacket.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h
new file mode 100644
index 00000000000..048435dc33b
--- /dev/null
+++ b/src/shared/revision_nr.h
@@ -0,0 +1,4 @@
+#ifndef __REVISION_NR_H__
+#define __REVISION_NR_H__
+ #define REVISION_NR "7265"
+#endif // __REVISION_NR_H__
diff --git a/src/shared/vmap/BaseModel.cpp b/src/shared/vmap/BaseModel.cpp
index 1b7ad34d413..bce9c718acd 100644
--- a/src/shared/vmap/BaseModel.cpp
+++ b/src/shared/vmap/BaseModel.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/vmap/BaseModel.h b/src/shared/vmap/BaseModel.h
index 1601f367de7..42e277634ba 100644
--- a/src/shared/vmap/BaseModel.h
+++ b/src/shared/vmap/BaseModel.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/vmap/CoordModelMapping.cpp b/src/shared/vmap/CoordModelMapping.cpp
index 7c7c801d690..9c7cbe58a6b 100644
--- a/src/shared/vmap/CoordModelMapping.cpp
+++ b/src/shared/vmap/CoordModelMapping.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/vmap/CoordModelMapping.h b/src/shared/vmap/CoordModelMapping.h
index 34f1917f5b3..10392ca7eaf 100644
--- a/src/shared/vmap/CoordModelMapping.h
+++ b/src/shared/vmap/CoordModelMapping.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/vmap/DebugCmdLogger.cpp b/src/shared/vmap/DebugCmdLogger.cpp
index 5e26b7ade8f..26846fa5783 100644
--- a/src/shared/vmap/DebugCmdLogger.cpp
+++ b/src/shared/vmap/DebugCmdLogger.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/vmap/DebugCmdLogger.h b/src/shared/vmap/DebugCmdLogger.h
index aa0df4d1e5c..f0e35d377bf 100644
--- a/src/shared/vmap/DebugCmdLogger.h
+++ b/src/shared/vmap/DebugCmdLogger.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/vmap/IVMapManager.h b/src/shared/vmap/IVMapManager.h
index 60159ed8bea..49f639b845e 100644
--- a/src/shared/vmap/IVMapManager.h
+++ b/src/shared/vmap/IVMapManager.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/vmap/Makefile.am b/src/shared/vmap/Makefile.am
index 80b297f8def..3829117f2a9 100644
--- a/src/shared/vmap/Makefile.am
+++ b/src/shared/vmap/Makefile.am
@@ -1,6 +1,6 @@
-# Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+# Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
#
-# Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+# Copyright (C) 2008-2009 Trinity <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
@@ -9,50 +9,50 @@
#
# 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
+# 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, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
## Process this file with automake to produce Makefile.in
-noinst_LIBRARIES = libvmaps.a
+## Sub-directories to parse
-## Preprocessor flags
-libvmaps_a_CPPFLAGS = \
-$(TRINI_INCLUDES) \
--I$(top_srcdir)/dep/include \
--I$(top_srcdir)/dep/include/g3dlite
-
-libvmaps_a_SOURCES = \
-$(srcdir)/AABSPTree.h \
-$(srcdir)/BaseModel.cpp \
-$(srcdir)/BaseModel.h \
-$(srcdir)/CoordModelMapping.cpp \
-$(srcdir)/CoordModelMapping.h \
-$(srcdir)/DebugCmdLogger.cpp \
-$(srcdir)/DebugCmdLogger.h \
-$(srcdir)/IVMapManager.h \
-$(srcdir)/ManagedModelContainer.cpp \
-$(srcdir)/ManagedModelContainer.h \
-$(srcdir)/ModelContainer.cpp \
-$(srcdir)/ModelContainer.h \
-$(srcdir)/NodeValueAccess.h \
-$(srcdir)/ShortBox.h \
-$(srcdir)/ShortVector.h \
-$(srcdir)/SubModel.cpp \
-$(srcdir)/SubModel.h \
-$(srcdir)/TileAssembler.cpp \
-$(srcdir)/TileAssembler.h \
-$(srcdir)/TreeNode.cpp \
-$(srcdir)/TreeNode.h \
-$(srcdir)/VMapDefinitions.h \
-$(srcdir)/VMapFactory.cpp \
-$(srcdir)/VMapFactory.h \
-$(srcdir)/VMapManager.cpp \
-$(srcdir)/VMapManager.h \
-$(srcdir)/VMapTools.h
+## CPP flags for includes, defines, etc.
+AM_CPPFLAGS = $(TRINI_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(srcdir)/../../../dep/include -I$(srcdir)/../../framework -I$(srcdir)/../../shared -I$(srcdir)/../../../dep/include/g3dlite
+## Build MaNGOS shared library and its parts as convenience library.
+# All libraries will be convenience libraries. Might be changed to shared
+# later.
+noinst_LIBRARIES = libmangosvmaps.a
+libmangosvmaps_a_SOURCES = \
+ AABSPTree.h \
+ BaseModel.cpp \
+ BaseModel.h \
+ CoordModelMapping.cpp \
+ CoordModelMapping.h \
+ DebugCmdLogger.cpp \
+ DebugCmdLogger.h \
+ IVMapManager.h \
+ ManagedModelContainer.cpp \
+ ManagedModelContainer.h \
+ ModelContainer.cpp \
+ ModelContainer.h \
+ NodeValueAccess.h \
+ ShortBox.h \
+ ShortVector.h \
+ SubModel.cpp \
+ SubModel.h \
+ TileAssembler.cpp \
+ TileAssembler.h \
+ TreeNode.cpp \
+ TreeNode.h \
+ VMapDefinitions.h \
+ VMapFactory.cpp \
+ VMapFactory.h \
+ VMapManager.cpp \
+ VMapManager.h \
+ VMapTools.h
diff --git a/src/shared/vmap/ManagedModelContainer.cpp b/src/shared/vmap/ManagedModelContainer.cpp
index 08c58a60c8f..34800b3b5f7 100644
--- a/src/shared/vmap/ManagedModelContainer.cpp
+++ b/src/shared/vmap/ManagedModelContainer.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/vmap/ManagedModelContainer.h b/src/shared/vmap/ManagedModelContainer.h
index b193ef9d57f..5aa6bfdf1c3 100644
--- a/src/shared/vmap/ManagedModelContainer.h
+++ b/src/shared/vmap/ManagedModelContainer.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/vmap/ModelContainer.cpp b/src/shared/vmap/ModelContainer.cpp
index 4d2dc2aac78..a4bc5b8aa17 100644
--- a/src/shared/vmap/ModelContainer.cpp
+++ b/src/shared/vmap/ModelContainer.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/vmap/ModelContainer.h b/src/shared/vmap/ModelContainer.h
index 98b4c9ddcf3..f66b11658d6 100644
--- a/src/shared/vmap/ModelContainer.h
+++ b/src/shared/vmap/ModelContainer.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/vmap/NodeValueAccess.h b/src/shared/vmap/NodeValueAccess.h
index b8ec54e90be..70bd0eeefae 100644
--- a/src/shared/vmap/NodeValueAccess.h
+++ b/src/shared/vmap/NodeValueAccess.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/vmap/ShortBox.h b/src/shared/vmap/ShortBox.h
index 9c5472f4c3a..059e59f47e6 100644
--- a/src/shared/vmap/ShortBox.h
+++ b/src/shared/vmap/ShortBox.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/vmap/ShortVector.h b/src/shared/vmap/ShortVector.h
index 8c4aec8a0b4..d02e6b4081e 100644
--- a/src/shared/vmap/ShortVector.h
+++ b/src/shared/vmap/ShortVector.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/vmap/SubModel.cpp b/src/shared/vmap/SubModel.cpp
index 3d1c0e29ff6..ed586ce6b52 100644
--- a/src/shared/vmap/SubModel.cpp
+++ b/src/shared/vmap/SubModel.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/vmap/SubModel.h b/src/shared/vmap/SubModel.h
index bc8239b1568..5a0b0d38be7 100644
--- a/src/shared/vmap/SubModel.h
+++ b/src/shared/vmap/SubModel.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/vmap/TileAssembler.cpp b/src/shared/vmap/TileAssembler.cpp
index fd83a318f65..e57836a6f9e 100644
--- a/src/shared/vmap/TileAssembler.cpp
+++ b/src/shared/vmap/TileAssembler.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
@@ -75,12 +75,12 @@ namespace VMAP
addWorldAreaMapId(0); //Azeroth
addWorldAreaMapId(1); //Kalimdor
addWorldAreaMapId(530); //Expansion01
+ addWorldAreaMapId(571); //Expansion02
}
//=================================================================
std::string getModNameFromModPosName(const std::string& pModPosName)
{
-
size_t spos = pModPosName.find_first_of('#');
std::string modelFileName = pModPosName.substr(0,spos);
return(modelFileName);
@@ -142,7 +142,6 @@ namespace VMAP
//=================================================================
bool TileAssembler::convertWorld()
{
-
#ifdef _ASSEMBLER_DEBUG
# ifdef _DEBUG
::g_df = fopen("../TileAssembler_debug.txt", "wb");
diff --git a/src/shared/vmap/TileAssembler.h b/src/shared/vmap/TileAssembler.h
index 3f0f9468172..cdfd6e1311d 100644
--- a/src/shared/vmap/TileAssembler.h
+++ b/src/shared/vmap/TileAssembler.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/vmap/TreeNode.cpp b/src/shared/vmap/TreeNode.cpp
index af7fe224fe5..1c0cff7d4b3 100644
--- a/src/shared/vmap/TreeNode.cpp
+++ b/src/shared/vmap/TreeNode.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/vmap/TreeNode.h b/src/shared/vmap/TreeNode.h
index 8f3fbd7a71a..d30b470b4b3 100644
--- a/src/shared/vmap/TreeNode.h
+++ b/src/shared/vmap/TreeNode.h
@@ -1,7 +1,7 @@
/*
-* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
-* Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+* Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/vmap/VMapDefinitions.h b/src/shared/vmap/VMapDefinitions.h
index c3498ea9260..35c672bd82e 100644
--- a/src/shared/vmap/VMapDefinitions.h
+++ b/src/shared/vmap/VMapDefinitions.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/vmap/VMapFactory.cpp b/src/shared/vmap/VMapFactory.cpp
index 4c349cdaa62..f0a78ba4f1c 100644
--- a/src/shared/vmap/VMapFactory.cpp
+++ b/src/shared/vmap/VMapFactory.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/vmap/VMapFactory.h b/src/shared/vmap/VMapFactory.h
index a8784a37219..738a8a7f4e0 100644
--- a/src/shared/vmap/VMapFactory.h
+++ b/src/shared/vmap/VMapFactory.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/vmap/VMapManager.cpp b/src/shared/vmap/VMapManager.cpp
index cf2bc080865..9cf35b2655d 100644
--- a/src/shared/vmap/VMapManager.cpp
+++ b/src/shared/vmap/VMapManager.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/vmap/VMapManager.h b/src/shared/vmap/VMapManager.h
index 5b4064915e4..02e0ec3e179 100644
--- a/src/shared/vmap/VMapManager.h
+++ b/src/shared/vmap/VMapManager.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/shared/vmap/VMapTools.h b/src/shared/vmap/VMapTools.h
index 49a28d5272d..5253392f867 100644
--- a/src/shared/vmap/VMapTools.h
+++ b/src/shared/vmap/VMapTools.h
@@ -1,7 +1,7 @@
/*
-* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
-* Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+* Copyright (C) 2008-2009 Trinity <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
diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am
index 333cba05861..81040a49592 100644
--- a/src/tools/Makefile.am
+++ b/src/tools/Makefile.am
@@ -1,2 +1,23 @@
+# 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+## Process this file with automake to produce Makefile.in
+
## Sub-directories to parse
SUBDIRS = genrevision
+
+## Additional files to include when running 'make dist'
+# Nothing yet.
diff --git a/src/tools/genrevision/Makefile.am b/src/tools/genrevision/Makefile.am
index faf5451f652..3f60ac14ab2 100644
--- a/src/tools/genrevision/Makefile.am
+++ b/src/tools/genrevision/Makefile.am
@@ -1,17 +1,35 @@
+# 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+## Process this file with automake to produce Makefile.in
+
## CPP flags for includes, defines, etc.
AM_CPPFLAGS = -I$(srcdir)
## Build world list daemon as standalone program
bin_PROGRAMS = genrevision
genrevision_SOURCES = \
- genrevision.cpp
+ genrevision.cpp
## Link world daemon against the shared library
-genrevision_LDADD =
+genrevision_LDADD =
genrevision_LDFLAGS = -L$(libdir)
## Additional files to include when running 'make dist'
# Include world daemon configuration
-#EXTRA_DIST =
+#EXTRA_DIST =
## Additional files to install
diff --git a/src/tools/genrevision/genrevision.cpp b/src/tools/genrevision/genrevision.cpp
index 99c407c33d9..83cf4da7c62 100644
--- a/src/tools/genrevision/genrevision.cpp
+++ b/src/tools/genrevision/genrevision.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
+ * 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
diff --git a/src/trinitycore/CliRunnable.cpp b/src/trinitycore/CliRunnable.cpp
index 267a8d41a27..a0609309298 100644
--- a/src/trinitycore/CliRunnable.cpp
+++ b/src/trinitycore/CliRunnable.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/trinitycore/Main.cpp b/src/trinitycore/Main.cpp
index d24ae02d426..df9d9185deb 100644
--- a/src/trinitycore/Main.cpp
+++ b/src/trinitycore/Main.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/trinitycore/Makefile.am b/src/trinitycore/Makefile.am
deleted file mode 100644
index ad1b78d9033..00000000000
--- a/src/trinitycore/Makefile.am
+++ /dev/null
@@ -1,85 +0,0 @@
-# Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
-#
-# Copyright (C) 2008 Trinity <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, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-## Process this file with automake to produce Makefile.in
-
-## Build world list daemon as standalone program
-bin_PROGRAMS = trinity-core
-
-## Preprocessor flags
-trinity_core_CPPFLAGS = \
-$(MYSQL_INCLUDES) \
-$(POSTGRE_INCLUDES) \
-$(TRINI_INCLUDES) \
--I$(top_srcdir)/dep/include \
--I$(top_srcdir)/src/shared \
--I$(top_srcdir)/src/framework \
--I$(top_srcdir)/src/game \
--D_TRINITY_CORE_CONFIG='"$(sysconfdir)/trinitycore.conf"'
-
-## Sources
-trinity_core_SOURCES = \
-$(srcdir)/CliRunnable.cpp \
-$(srcdir)/CliRunnable.h \
-$(srcdir)/Main.cpp \
-$(srcdir)/Master.cpp \
-$(srcdir)/Master.h \
-$(srcdir)/RASocket.cpp \
-$(srcdir)/RASocket.h \
-$(srcdir)/WorldRunnable.cpp \
-$(srcdir)/WorldRunnable.h
-
-## Convenience libs to add
-trinity_core_LDADD = \
-$(top_builddir)/src/game/libgame.a \
-$(top_builddir)/src/shared/libshared.a \
-$(top_builddir)/src/shared/vmap/libvmaps.a \
-$(top_builddir)/src/framework/libmangosframework.a \
-$(top_builddir)/dep/src/sockets/libmangossockets.a \
-$(top_builddir)/dep/src/zthread/libZThread.la \
-$(top_builddir)/dep/src/g3dlite/libg3dlite.a
-
-if USE_TSCRIPTS
-trinity_core_LDADD += $(top_builddir)/src/bindings/scripts/libtrinityscript.la
-else
-trinity_core_LDADD += $(top_builddir)/src/bindings/interface/libtrinityscript.la
-endif
-
-## Linker flags
-trinity_core_LDFLAGS = $(MYSQL_LIBS) $(POSTGRE_LIBS) $(ZLIB) $(COMPATLIB) $(SSLLIB) $(TRINI_LIBS) -export-dynamic
-
-## Additional files to install
-sysconf_DATA = \
- trinitycore.conf.dist
-
-EXTRA_DIST = \
- trinitycore.conf.dist
-
-## Prevend overwrite of the config file, if its already installed
-install-data-hook:
- @list='$(sysconf_DATA)'; for p in $$list; do \
- dest=`echo $$p | sed -e s/.dist//`; \
- if test -f $(DESTDIR)$(sysconfdir)/$$dest; then \
- echo "$@ will not overwrite existing $(DESTDIR)$(sysconfdir)/$$dest"; \
- else \
- echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(sysconfdir)/$$dest"; \
- $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(sysconfdir)/$$dest; \
- fi; \
- done
-
-
diff --git a/src/trinitycore/Master.cpp b/src/trinitycore/Master.cpp
index 66c1c17664e..8eeda54ab83 100644
--- a/src/trinitycore/Master.cpp
+++ b/src/trinitycore/Master.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/trinitycore/RASocket.cpp b/src/trinitycore/RASocket.cpp
index cfc50d95f89..a48928d5a23 100644
--- a/src/trinitycore/RASocket.cpp
+++ b/src/trinitycore/RASocket.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/trinitycore/WorldRunnable.cpp b/src/trinitycore/WorldRunnable.cpp
index e4f1a79a6e8..ec4c25a6cf6 100644
--- a/src/trinitycore/WorldRunnable.cpp
+++ b/src/trinitycore/WorldRunnable.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/trinityrealm/AuthSocket.cpp b/src/trinityrealm/AuthSocket.cpp
index 6f8363a9724..c5c81593737 100644
--- a/src/trinityrealm/AuthSocket.cpp
+++ b/src/trinityrealm/AuthSocket.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/trinityrealm/Main.cpp b/src/trinityrealm/Main.cpp
index 274aabf0717..95829ee96ca 100644
--- a/src/trinityrealm/Main.cpp
+++ b/src/trinityrealm/Main.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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
diff --git a/src/trinityrealm/Makefile.am b/src/trinityrealm/Makefile.am
deleted file mode 100644
index 9baeed6c2b1..00000000000
--- a/src/trinityrealm/Makefile.am
+++ /dev/null
@@ -1,72 +0,0 @@
-# Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
-#
-# Copyright (C) 2008 Trinity <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, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-## Process this file with automake to produce Makefile.in
-
-## Build realm list daemon as standalone program
-bin_PROGRAMS = trinity-realm
-
-## Preprocessor flags
-trinity_realm_CPPFLAGS = \
-$(MYSQL_INCLUDES) \
-$(POSTGRE_INCLUDES) \
-$(TRINI_INCLUDES) \
--I$(top_srcdir)/dep/include \
--I$(top_srcdir)/src/framework \
--I$(top_srcdir)/src/shared \
--D_TRINITY_REALM_CONFIG='"$(sysconfdir)/trinityrealm.conf"'
-
-## Sources
-trinity_realm_SOURCES = \
-$(srcdir)/AuthCodes.h \
-$(srcdir)/AuthSocket.cpp \
-$(srcdir)/AuthSocket.h \
-$(srcdir)/Main.cpp \
-$(srcdir)/RealmList.cpp \
-$(srcdir)/RealmList.h
-
-## Convenience libs to add
-trinity_realm_LDADD = \
-$(top_builddir)/src/shared/libshared.a \
-$(top_builddir)/src/framework/libmangosframework.a \
-$(top_builddir)/dep/src/sockets/libmangossockets.a \
-$(top_builddir)/dep/src/zthread/libZThread.la
-
-## Linker flags
-trinity_realm_LDFLAGS = $(MYSQL_LIBS) $(POSTGRE_LIBS) $(ZLIB) $(COMPATLIB) $(SSLLIB) $(TRINI_LIBS)
-
-## Additional files to install
-sysconf_DATA = \
- trinityrealm.conf.dist
-
-## Prevend overwrite of the config file, if its already installed
-install-data-hook:
- @list='$(sysconf_DATA)'; for p in $$list; do \
- dest=`echo $$p | sed -e s/.dist//`; \
- if test -f $(DESTDIR)$(sysconfdir)/$$dest; then \
- echo "$@ will not overwrite existing $(DESTDIR)$(sysconfdir)/$$dest"; \
- else \
- echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(sysconfdir)/$$dest"; \
- $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(sysconfdir)/$$dest; \
- fi; \
- done
-
-## Additional files to include when running 'make dist'
-EXTRA_DIST = trinityrealm.conf.dist
-
-
diff --git a/src/trinityrealm/RealmList.cpp b/src/trinityrealm/RealmList.cpp
index 558d6c12610..6a3d6b47e0f 100644
--- a/src/trinityrealm/RealmList.cpp
+++ b/src/trinityrealm/RealmList.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <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