aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/CMakeLists.txt113
-rw-r--r--src/common/Collision/BoundingIntervalHierarchy.h2
-rw-r--r--src/common/Collision/DynamicTree.h2
-rw-r--r--src/common/Collision/Management/IVMapManager.h2
-rw-r--r--src/common/Collision/Management/MMapFactory.h2
-rw-r--r--src/common/Collision/Management/MMapManager.h2
-rw-r--r--src/common/Collision/Management/VMapFactory.h2
-rw-r--r--src/common/Collision/Management/VMapManager2.h4
-rw-r--r--src/common/Collision/Maps/MapTree.h6
-rw-r--r--src/common/Collision/Maps/TileAssembler.h10
-rw-r--r--src/common/Collision/Models/GameObjectModel.h6
-rw-r--r--src/common/Collision/Models/ModelInstance.h4
-rw-r--r--src/common/Collision/Models/WorldModel.h8
-rw-r--r--src/common/Collision/RegularGrid.h2
-rw-r--r--src/common/Common.h4
-rw-r--r--src/common/Configuration/BuiltInConfig.cpp52
-rw-r--r--src/common/Configuration/BuiltInConfig.h43
-rw-r--r--src/common/Configuration/Config.cpp14
-rw-r--r--src/common/Configuration/Config.h18
-rw-r--r--src/common/Cryptography/ARC4.h2
-rw-r--r--src/common/Cryptography/Authentication/AuthCrypt.h2
-rw-r--r--src/common/Cryptography/BigNumber.h2
-rw-r--r--src/common/Cryptography/HMACSHA1.h2
-rw-r--r--src/common/Cryptography/OpenSSLCrypto.h8
-rw-r--r--src/common/Cryptography/SHA1.h2
-rw-r--r--src/common/Debugging/Errors.cpp7
-rw-r--r--src/common/Debugging/Errors.h14
-rw-r--r--src/common/Define.h39
-rw-r--r--src/common/GitRevision.cpp21
-rw-r--r--src/common/GitRevision.h27
-rw-r--r--src/common/Logging/Appender.h6
-rw-r--r--src/common/Logging/AppenderConsole.h2
-rw-r--r--src/common/Logging/AppenderFile.h2
-rw-r--r--src/common/Logging/Log.cpp25
-rw-r--r--src/common/Logging/Log.h9
-rw-r--r--src/common/Logging/LogOperation.h3
-rw-r--r--src/common/Logging/Logger.h2
-rw-r--r--src/common/Platform/ServiceWin32.cpp (renamed from src/server/shared/Service/ServiceWin32.cpp)1
-rw-r--r--src/common/Platform/ServiceWin32.h (renamed from src/server/shared/Service/ServiceWin32.h)1
-rw-r--r--src/common/Threading/LockedQueue.h8
-rw-r--r--src/common/Threading/MPSCQueue.h83
-rw-r--r--src/common/Utilities/Containers.h1
-rw-r--r--src/common/Utilities/EventMap.h2
-rw-r--r--src/common/Utilities/EventProcessor.h4
-rw-r--r--src/common/Utilities/Random.cpp8
-rw-r--r--src/common/Utilities/Random.h20
-rw-r--r--src/common/Utilities/StringFormat.h2
-rw-r--r--src/common/Utilities/TaskScheduler.h6
-rw-r--r--src/common/Utilities/Util.cpp30
-rw-r--r--src/common/Utilities/Util.h46
-rw-r--r--src/genrev/CMakeLists.txt5
-rw-r--r--src/server/CMakeLists.txt15
-rw-r--r--src/server/authserver/CMakeLists.txt95
-rw-r--r--src/server/authserver/Main.cpp29
-rw-r--r--src/server/authserver/Realms/RealmList.cpp90
-rw-r--r--src/server/authserver/Realms/RealmList.h58
-rw-r--r--src/server/authserver/Server/AuthSession.cpp46
-rw-r--r--src/server/authserver/Server/AuthSocketMgr.h15
-rw-r--r--src/server/authserver/authserver.conf.dist47
-rw-r--r--src/server/database/CMakeLists.txt91
-rw-r--r--src/server/database/Database/AdhocStatement.h2
-rw-r--r--src/server/database/Database/DatabaseEnv.cpp22
-rw-r--r--src/server/database/Database/DatabaseEnv.h10
-rw-r--r--src/server/database/Database/DatabaseLoader.cpp79
-rw-r--r--src/server/database/Database/DatabaseLoader.h17
-rw-r--r--src/server/database/Database/DatabaseWorker.h2
-rw-r--r--src/server/database/Database/DatabaseWorkerPool.cpp322
-rw-r--r--src/server/database/Database/DatabaseWorkerPool.h313
-rw-r--r--src/server/database/Database/Field.h2
-rw-r--r--src/server/database/Database/Implementation/CharacterDatabase.cpp15
-rw-r--r--src/server/database/Database/Implementation/CharacterDatabase.h5
-rw-r--r--src/server/database/Database/Implementation/LoginDatabase.cpp4
-rw-r--r--src/server/database/Database/Implementation/LoginDatabase.h2
-rw-r--r--src/server/database/Database/Implementation/WorldDatabase.h2
-rw-r--r--src/server/database/Database/MySQLConnection.cpp87
-rw-r--r--src/server/database/Database/MySQLConnection.h12
-rw-r--r--src/server/database/Database/MySQLThreading.h2
-rw-r--r--src/server/database/Database/PreparedStatement.h6
-rw-r--r--src/server/database/Database/QueryHolder.h4
-rw-r--r--src/server/database/Database/QueryResult.h4
-rw-r--r--src/server/database/Database/SQLOperation.h2
-rw-r--r--src/server/database/Database/Transaction.h4
-rw-r--r--src/server/database/Logging/AppenderDB.h2
-rw-r--r--src/server/database/Updater/DBUpdater.cpp39
-rw-r--r--src/server/database/Updater/DBUpdater.h10
-rw-r--r--src/server/database/Updater/UpdateFetcher.cpp37
-rw-r--r--src/server/database/Updater/UpdateFetcher.h10
-rw-r--r--src/server/game/AI/CoreAI/CombatAI.h12
-rw-r--r--src/server/game/AI/CoreAI/GameObjectAI.h4
-rw-r--r--src/server/game/AI/CoreAI/GuardAI.h2
-rw-r--r--src/server/game/AI/CoreAI/PassiveAI.h10
-rw-r--r--src/server/game/AI/CoreAI/PetAI.cpp27
-rw-r--r--src/server/game/AI/CoreAI/PetAI.h2
-rw-r--r--src/server/game/AI/CoreAI/ReactorAI.h2
-rw-r--r--src/server/game/AI/CoreAI/TotemAI.h2
-rw-r--r--src/server/game/AI/CoreAI/UnitAI.cpp33
-rw-r--r--src/server/game/AI/CoreAI/UnitAI.h29
-rw-r--r--src/server/game/AI/CreatureAI.cpp4
-rw-r--r--src/server/game/AI/CreatureAI.h12
-rw-r--r--src/server/game/AI/CreatureAISelector.h6
-rw-r--r--src/server/game/AI/PlayerAI/PlayerAI.cpp226
-rw-r--r--src/server/game/AI/PlayerAI/PlayerAI.h60
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedCreature.cpp12
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedCreature.h22
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp2
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedEscortAI.h2
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp2
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h2
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.cpp3
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.h8
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp15
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.h2
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.cpp13
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h24
-rw-r--r--src/server/game/Accounts/AccountMgr.cpp93
-rw-r--r--src/server/game/Accounts/AccountMgr.h14
-rw-r--r--src/server/game/Accounts/RBAC.cpp6
-rw-r--r--src/server/game/Accounts/RBAC.h12
-rw-r--r--src/server/game/Achievements/AchievementMgr.cpp128
-rw-r--r--src/server/game/Achievements/AchievementMgr.h12
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.cpp8
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.h12
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBot.cpp12
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBot.h16
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.h2
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h2
-rw-r--r--src/server/game/Battlefield/Battlefield.cpp16
-rw-r--r--src/server/game/Battlefield/Battlefield.h6
-rw-r--r--src/server/game/Battlefield/BattlefieldMgr.cpp6
-rw-r--r--src/server/game/Battlefield/BattlefieldMgr.h8
-rw-r--r--src/server/game/Battlefield/Zones/BattlefieldWG.h6
-rw-r--r--src/server/game/Battlegrounds/Arena.h2
-rw-r--r--src/server/game/Battlegrounds/ArenaScore.h4
-rw-r--r--src/server/game/Battlegrounds/ArenaTeam.h4
-rw-r--r--src/server/game/Battlegrounds/ArenaTeamMgr.cpp6
-rw-r--r--src/server/game/Battlegrounds/ArenaTeamMgr.h8
-rw-r--r--src/server/game/Battlegrounds/Battleground.h2
-rw-r--r--src/server/game/Battlegrounds/BattlegroundMgr.cpp22
-rw-r--r--src/server/game/Battlegrounds/BattlegroundMgr.h8
-rw-r--r--src/server/game/Battlegrounds/BattlegroundQueue.h6
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp22
-rw-r--r--src/server/game/CMakeLists.txt239
-rw-r--r--src/server/game/Calendar/CalendarMgr.cpp6
-rw-r--r--src/server/game/Calendar/CalendarMgr.h12
-rw-r--r--src/server/game/Chat/Channels/Channel.h2
-rw-r--r--src/server/game/Chat/Channels/ChannelMgr.h2
-rw-r--r--src/server/game/Chat/Chat.cpp16
-rw-r--r--src/server/game/Chat/Chat.h6
-rw-r--r--src/server/game/Chat/ChatLink.h20
-rw-r--r--src/server/game/Combat/HostileRefManager.h2
-rw-r--r--src/server/game/Combat/ThreatManager.cpp5
-rw-r--r--src/server/game/Combat/ThreatManager.h10
-rw-r--r--src/server/game/Combat/UnitEvents.h2
-rw-r--r--src/server/game/Conditions/ConditionMgr.cpp65
-rw-r--r--src/server/game/Conditions/ConditionMgr.h21
-rw-r--r--src/server/game/Conditions/DisableMgr.h10
-rw-r--r--src/server/game/DataStores/DBCStores.h288
-rw-r--r--src/server/game/DungeonFinding/LFG.h6
-rw-r--r--src/server/game/DungeonFinding/LFGGroupData.h2
-rw-r--r--src/server/game/DungeonFinding/LFGMgr.cpp6
-rw-r--r--src/server/game/DungeonFinding/LFGMgr.h8
-rw-r--r--src/server/game/DungeonFinding/LFGPlayerData.h2
-rw-r--r--src/server/game/DungeonFinding/LFGQueue.h2
-rw-r--r--src/server/game/DungeonFinding/LFGScripts.h4
-rw-r--r--src/server/game/Entities/Corpse/Corpse.cpp2
-rw-r--r--src/server/game/Entities/Corpse/Corpse.h2
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp24
-rw-r--r--src/server/game/Entities/Creature/Creature.h14
-rw-r--r--src/server/game/Entities/Creature/CreatureGroups.cpp6
-rw-r--r--src/server/game/Entities/Creature/CreatureGroups.h10
-rw-r--r--src/server/game/Entities/Creature/GossipDef.h6
-rw-r--r--src/server/game/Entities/Creature/TemporarySummon.cpp5
-rw-r--r--src/server/game/Entities/Creature/TemporarySummon.h11
-rw-r--r--src/server/game/Entities/DynamicObject/DynamicObject.h2
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h2
-rw-r--r--src/server/game/Entities/Item/Container/Bag.h2
-rw-r--r--src/server/game/Entities/Item/Item.cpp3
-rw-r--r--src/server/game/Entities/Item/Item.h2
-rw-r--r--src/server/game/Entities/Item/ItemEnchantmentMgr.cpp6
-rw-r--r--src/server/game/Entities/Item/ItemEnchantmentMgr.h7
-rw-r--r--src/server/game/Entities/Object/Object.cpp4
-rw-r--r--src/server/game/Entities/Object/Object.h11
-rw-r--r--src/server/game/Entities/Object/ObjectGuid.cpp17
-rw-r--r--src/server/game/Entities/Object/ObjectGuid.h19
-rw-r--r--src/server/game/Entities/Object/ObjectPosSelector.h2
-rw-r--r--src/server/game/Entities/Object/Position.h14
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateFieldFlags.h10
-rw-r--r--src/server/game/Entities/Pet/Pet.h2
-rw-r--r--src/server/game/Entities/Player/KillRewarder.h2
-rw-r--r--src/server/game/Entities/Player/Player.cpp1678
-rw-r--r--src/server/game/Entities/Player/Player.h302
-rw-r--r--src/server/game/Entities/Player/SocialMgr.cpp6
-rw-r--r--src/server/game/Entities/Player/SocialMgr.h8
-rw-r--r--src/server/game/Entities/Player/TradeData.h2
-rw-r--r--src/server/game/Entities/Totem/Totem.h2
-rw-r--r--src/server/game/Entities/Transport/Transport.h2
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp185
-rw-r--r--src/server/game/Entities/Unit/Unit.h33
-rw-r--r--src/server/game/Entities/Vehicle/Vehicle.h4
-rw-r--r--src/server/game/Events/GameEventMgr.cpp106
-rw-r--r--src/server/game/Events/GameEventMgr.h12
-rw-r--r--src/server/game/Globals/ObjectAccessor.cpp63
-rw-r--r--src/server/game/Globals/ObjectAccessor.h83
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp13
-rw-r--r--src/server/game/Globals/ObjectMgr.h26
-rw-r--r--src/server/game/Grids/GridReference.h6
-rw-r--r--src/server/game/Grids/GridStates.h10
-rw-r--r--src/server/game/Grids/Notifiers/GridNotifiers.h16
-rw-r--r--src/server/game/Grids/ObjectGridLoader.h6
-rw-r--r--src/server/game/Groups/Group.h2
-rw-r--r--src/server/game/Groups/GroupMgr.cpp6
-rw-r--r--src/server/game/Groups/GroupMgr.h8
-rw-r--r--src/server/game/Groups/GroupReference.h2
-rw-r--r--src/server/game/Guilds/Guild.h4
-rw-r--r--src/server/game/Guilds/GuildMgr.cpp6
-rw-r--r--src/server/game/Guilds/GuildMgr.h8
-rw-r--r--src/server/game/Handlers/AddonHandler.cpp6
-rw-r--r--src/server/game/Handlers/AddonHandler.h6
-rw-r--r--src/server/game/Handlers/CalendarHandler.cpp2
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp8
-rw-r--r--src/server/game/Handlers/MailHandler.cpp6
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp16
-rw-r--r--src/server/game/Instances/InstanceSaveMgr.cpp8
-rw-r--r--src/server/game/Instances/InstanceSaveMgr.h10
-rw-r--r--src/server/game/Instances/InstanceScript.h4
-rw-r--r--src/server/game/Loot/LootMgr.cpp17
-rw-r--r--src/server/game/Loot/LootMgr.h81
-rw-r--r--src/server/game/Mails/Mail.cpp4
-rw-r--r--src/server/game/Mails/Mail.h8
-rw-r--r--src/server/game/Maps/AreaBoundary.h14
-rw-r--r--src/server/game/Maps/Map.cpp29
-rw-r--r--src/server/game/Maps/Map.h13
-rw-r--r--src/server/game/Maps/MapInstanced.cpp3
-rw-r--r--src/server/game/Maps/MapInstanced.h2
-rw-r--r--src/server/game/Maps/MapManager.cpp6
-rw-r--r--src/server/game/Maps/MapManager.h8
-rw-r--r--src/server/game/Maps/MapUpdater.h2
-rw-r--r--src/server/game/Maps/TransportMgr.cpp6
-rw-r--r--src/server/game/Maps/TransportMgr.h12
-rw-r--r--src/server/game/Miscellaneous/Language.h4
-rw-r--r--src/server/game/Movement/MotionMaster.cpp52
-rw-r--r--src/server/game/Movement/MotionMaster.h2
-rwxr-xr-xsrc/server/game/Movement/MovementGenerator.h2
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/IdleMovementGenerator.h2
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h2
-rw-r--r--src/server/game/Movement/PathGenerator.h2
-rw-r--r--src/server/game/Movement/Spline/MoveSpline.h2
-rw-r--r--src/server/game/Movement/Spline/MoveSplineInit.h4
-rw-r--r--src/server/game/Movement/Spline/MovementTypedefs.h4
-rw-r--r--src/server/game/Movement/Waypoints/WaypointManager.cpp6
-rw-r--r--src/server/game/Movement/Waypoints/WaypointManager.h8
-rw-r--r--src/server/game/OutdoorPvP/OutdoorPvP.h4
-rw-r--r--src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp6
-rw-r--r--src/server/game/OutdoorPvP/OutdoorPvPMgr.h8
-rw-r--r--src/server/game/Pools/PoolMgr.cpp11
-rw-r--r--src/server/game/Pools/PoolMgr.h12
-rw-r--r--src/server/game/Quests/QuestDef.h2
-rw-r--r--src/server/game/Reputation/ReputationMgr.h2
-rw-r--r--src/server/game/Scripting/ScriptLoader.cpp1421
-rw-r--r--src/server/game/Scripting/ScriptMgr.cpp82
-rw-r--r--src/server/game/Scripting/ScriptMgr.h80
-rw-r--r--src/server/game/Scripting/ScriptSystem.cpp8
-rw-r--r--src/server/game/Scripting/ScriptSystem.h8
-rw-r--r--src/server/game/Server/Protocol/Opcodes.h2
-rw-r--r--src/server/game/Server/Protocol/PacketLog.cpp6
-rw-r--r--src/server/game/Server/Protocol/PacketLog.h8
-rw-r--r--src/server/game/Server/WorldSession.cpp198
-rw-r--r--src/server/game/Server/WorldSession.h4
-rw-r--r--src/server/game/Server/WorldSocket.cpp105
-rw-r--r--src/server/game/Server/WorldSocket.h7
-rw-r--r--src/server/game/Server/WorldSocketMgr.cpp18
-rw-r--r--src/server/game/Server/WorldSocketMgr.h10
-rw-r--r--src/server/game/Skills/SkillDiscovery.cpp16
-rw-r--r--src/server/game/Skills/SkillDiscovery.h9
-rw-r--r--src/server/game/Skills/SkillExtraItems.cpp18
-rw-r--r--src/server/game/Skills/SkillExtraItems.h10
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.h2
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.h12
-rw-r--r--src/server/game/Spells/Spell.cpp44
-rw-r--r--src/server/game/Spells/Spell.h18
-rw-r--r--src/server/game/Spells/SpellEffects.cpp42
-rw-r--r--src/server/game/Spells/SpellHistory.h2
-rw-r--r--src/server/game/Spells/SpellInfo.h7
-rw-r--r--src/server/game/Spells/SpellMgr.cpp165
-rw-r--r--src/server/game/Spells/SpellMgr.h22
-rw-r--r--src/server/game/Spells/SpellScript.h60
-rw-r--r--src/server/game/Texts/CreatureTextMgr.cpp6
-rw-r--r--src/server/game/Texts/CreatureTextMgr.h8
-rw-r--r--src/server/game/Tickets/TicketMgr.cpp6
-rw-r--r--src/server/game/Tickets/TicketMgr.h10
-rw-r--r--src/server/game/Tools/CharacterDatabaseCleaner.h22
-rw-r--r--src/server/game/Tools/PlayerDump.cpp10
-rw-r--r--src/server/game/Tools/PlayerDump.h6
-rw-r--r--src/server/game/Warden/Warden.h2
-rw-r--r--src/server/game/Warden/WardenCheckMgr.cpp6
-rw-r--r--src/server/game/Warden/WardenCheckMgr.h8
-rw-r--r--src/server/game/Warden/WardenMac.h2
-rw-r--r--src/server/game/Warden/WardenWin.h2
-rw-r--r--src/server/game/Weather/Weather.cpp2
-rw-r--r--src/server/game/Weather/Weather.h2
-rw-r--r--src/server/game/Weather/WeatherMgr.h12
-rw-r--r--src/server/game/World/World.cpp68
-rw-r--r--src/server/game/World/World.h28
-rw-r--r--src/server/scripts/CMakeLists.txt159
-rw-r--r--src/server/scripts/Commands/CMakeLists.txt18
-rw-r--r--src/server/scripts/Commands/cs_account.cpp52
-rw-r--r--src/server/scripts/Commands/cs_ahbot.cpp2
-rw-r--r--src/server/scripts/Commands/cs_ban.cpp6
-rw-r--r--src/server/scripts/Commands/cs_character.cpp14
-rw-r--r--src/server/scripts/Commands/cs_debug.cpp10
-rw-r--r--src/server/scripts/Commands/cs_gm.cpp2
-rw-r--r--src/server/scripts/Commands/cs_lookup.cpp2
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp9
-rw-r--r--src/server/scripts/Commands/cs_modify.cpp12
-rw-r--r--src/server/scripts/Commands/cs_rbac.cpp6
-rw-r--r--src/server/scripts/Commands/cs_script_loader.cpp104
-rw-r--r--src/server/scripts/Commands/cs_send.cpp10
-rw-r--r--src/server/scripts/Commands/cs_ticket.cpp6
-rw-r--r--src/server/scripts/Commands/cs_titles.cpp2
-rw-r--r--src/server/scripts/Commands/cs_wp.cpp102
-rw-r--r--src/server/scripts/Custom/CMakeLists.txt18
-rw-r--r--src/server/scripts/Custom/custom_script_loader.cpp25
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp77
-rw-r--r--src/server/scripts/EasternKingdoms/CMakeLists.txt204
-rw-r--r--src/server/scripts/EasternKingdoms/Deadmines/boss_mr_smite.cpp111
-rw-r--r--src/server/scripts/EasternKingdoms/Deadmines/deadmines.h13
-rw-r--r--src/server/scripts/EasternKingdoms/Deadmines/instance_deadmines.cpp45
-rw-r--r--src/server/scripts/EasternKingdoms/Karazhan/boss_maiden_of_virtue.cpp17
-rw-r--r--src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp10
-rw-r--r--src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp16
-rw-r--r--src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp10
-rw-r--r--src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp6
-rw-r--r--src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp5
-rw-r--r--src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp42
-rw-r--r--src/server/scripts/EasternKingdoms/Karazhan/instance_karazhan.cpp341
-rw-r--r--src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/Karazhan/karazhan.h56
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/SunkenTemple/instance_sunken_temple.cpp40
-rw-r--r--src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp137
-rw-r--r--src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp114
-rw-r--r--src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp372
-rw-r--r--src/server/scripts/EasternKingdoms/zone_burning_steppes.cpp87
-rw-r--r--src/server/scripts/EasternKingdoms/zone_eastern_plaguelands.cpp57
-rw-r--r--src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp114
-rw-r--r--src/server/scripts/Events/CMakeLists.txt18
-rw-r--r--src/server/scripts/Events/events_script_loader.cpp26
-rw-r--r--src/server/scripts/Kalimdor/CMakeLists.txt121
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h18
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h6
-rw-r--r--src/server/scripts/Kalimdor/kalimdor_script_loader.cpp206
-rw-r--r--src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp20
-rw-r--r--src/server/scripts/Kalimdor/zone_desolace.cpp29
-rw-r--r--src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp45
-rw-r--r--src/server/scripts/Kalimdor/zone_orgrimmar.cpp66
-rw-r--r--src/server/scripts/Northrend/CMakeLists.txt199
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/instance_ruby_sanctum.cpp2
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.cpp51
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp2
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp12
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp4
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp6
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp4
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp77
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp6
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp6
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp2
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp29
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp18
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp42
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp38
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp14
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp104
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_loatheb.cpp94
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp22
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_noth.cpp40
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_patchwerk.cpp12
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_razuvious.cpp22
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp501
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp132
-rw-r--r--src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp151
-rw-r--r--src/server/scripts/Northrend/Naxxramas/naxxramas.h14
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp1
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp3
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp8
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp17
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/instance_utgarde_pinnacle.cpp2
-rw-r--r--src/server/scripts/Northrend/isle_of_conquest.cpp2
-rw-r--r--src/server/scripts/Northrend/northrend_script_loader.cpp374
-rw-r--r--src/server/scripts/Northrend/zone_dragonblight.cpp4
-rw-r--r--src/server/scripts/OutdoorPvP/CMakeLists.txt27
-rw-r--r--src/server/scripts/OutdoorPvP/OutdoorPvPHP.h18
-rw-r--r--src/server/scripts/OutdoorPvP/OutdoorPvPNA.h14
-rw-r--r--src/server/scripts/OutdoorPvP/OutdoorPvPSI.h18
-rw-r--r--src/server/scripts/OutdoorPvP/OutdoorPvPScriptLoader.cpp36
-rw-r--r--src/server/scripts/OutdoorPvP/OutdoorPvPTF.h18
-rw-r--r--src/server/scripts/OutdoorPvP/OutdoorPvPZM.h18
-rw-r--r--src/server/scripts/Outland/CMakeLists.txt128
-rw-r--r--src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp1
-rw-r--r--src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp146
-rw-r--r--src/server/scripts/Outland/outland_script_loader.cpp256
-rw-r--r--src/server/scripts/Outland/zone_terokkar_forest.cpp221
-rw-r--r--src/server/scripts/Pet/CMakeLists.txt21
-rw-r--r--src/server/scripts/Pet/pet_generic.cpp173
-rw-r--r--src/server/scripts/Pet/pet_script_loader.cpp36
-rw-r--r--src/server/scripts/ScriptLoader.cpp51
-rw-r--r--src/server/scripts/ScriptLoader.h (renamed from src/server/game/Scripting/ScriptLoader.h)12
-rw-r--r--src/server/scripts/Spells/CMakeLists.txt30
-rw-r--r--src/server/scripts/Spells/spell_dk.cpp100
-rw-r--r--src/server/scripts/Spells/spell_holiday.cpp163
-rw-r--r--src/server/scripts/Spells/spell_hunter.cpp69
-rw-r--r--src/server/scripts/Spells/spell_paladin.cpp2
-rw-r--r--src/server/scripts/Spells/spell_script_loader.cpp52
-rw-r--r--src/server/scripts/World/CMakeLists.txt18
-rw-r--r--src/server/scripts/World/duel_reset.cpp12
-rw-r--r--src/server/scripts/World/go_scripts.cpp2
-rw-r--r--src/server/scripts/World/npcs_special.cpp168
-rw-r--r--src/server/scripts/World/world_script_loader.cpp59
-rw-r--r--src/server/shared/CMakeLists.txt90
-rw-r--r--src/server/shared/DataStores/DBCFileLoader.h2
-rw-r--r--src/server/shared/Networking/AsyncAcceptor.h41
-rw-r--r--src/server/shared/Networking/MessageBuffer.h2
-rw-r--r--src/server/shared/Networking/NetworkThread.h84
-rw-r--r--src/server/shared/Networking/Socket.h103
-rw-r--r--src/server/shared/Networking/SocketMgr.h37
-rw-r--r--src/server/shared/Packets/ByteBuffer.h20
-rw-r--r--src/server/shared/Realm/Realm.cpp18
-rw-r--r--src/server/shared/Realm/Realm.h85
-rw-r--r--src/server/worldserver/CMakeLists.txt151
-rw-r--r--src/server/worldserver/Main.cpp90
-rw-r--r--src/server/worldserver/RemoteAccess/RASession.cpp6
-rw-r--r--src/server/worldserver/worldserver.conf.dist117
-rw-r--r--src/tools/map_extractor/CMakeLists.txt57
-rw-r--r--src/tools/mmaps_generator/CMakeLists.txt62
-rw-r--r--src/tools/mmaps_generator/MapBuilder.cpp4
-rw-r--r--src/tools/vmap4_assembler/CMakeLists.txt20
-rw-r--r--src/tools/vmap4_extractor/CMakeLists.txt36
440 files changed, 9003 insertions, 8589 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 8dee99c65e7..4250df6d1f1 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -8,42 +8,33 @@
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-if( USE_COREPCH )
- include_directories(${CMAKE_CURRENT_BINARY_DIR})
-endif()
-
-file(GLOB_RECURSE sources_Common Common.cpp Common.h)
-file(GLOB_RECURSE sources_Collision Collision/*.cpp Collision/*.h)
-file(GLOB_RECURSE sources_Threading Threading/*.cpp Threading/*.h)
-file(GLOB_RECURSE sources_Utilities Utilities/*.cpp Utilities/*.h)
-file(GLOB_RECURSE sources_Configuration Configuration/*.cpp Configuration/*.h)
-file(GLOB_RECURSE sources_Logging Logging/*.cpp Logging/*.h)
-if (SERVERS)
- file(GLOB_RECURSE sources_Cryptography Cryptography/*.cpp Cryptography/*.h)
-endif (SERVERS)
+CollectSourceFiles(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ PRIVATE_SOURCES
+ # Exclude
+ ${CMAKE_CURRENT_SOURCE_DIR}/Debugging
+ ${CMAKE_CURRENT_SOURCE_DIR}/Platform
+ ${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders)
# Manually set sources for Debugging directory as we don't want to include WheatyExceptionReport in common project
# It needs to be included both in authserver and worldserver for the static global variable to be properly initialized
# and to handle crash logs on windows
-set(sources_Debugging Debugging/Errors.cpp Debugging/Errors.h)
-file(GLOB sources_localdir *.cpp *.h)
+list(APPEND PRIVATE_SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/Debugging/Errors.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/Debugging/Errors.h)
if (USE_COREPCH)
- set(common_STAT_PCH_HDR PrecompiledHeaders/commonPCH.h)
- set(common_STAT_PCH_SRC PrecompiledHeaders/commonPCH.cpp)
+ set(PRIVATE_PCH_HEADER PrecompiledHeaders/commonPCH.h)
+ set(PRIVATE_PCH_SOURCE PrecompiledHeaders/commonPCH.cpp)
endif (USE_COREPCH)
-set(common_STAT_SRCS
- ${common_STAT_SRCS}
- ${sources_Common}
- ${sources_Collision}
- ${sources_Threading}
- ${sources_Utilities}
- ${sources_Debugging}
- ${sources_Configuration}
- ${sources_Logging}
- ${sources_Cryptography}
- ${sources_localdir}
+GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
+
+add_definitions(-DTRINITY_API_EXPORT_COMMON)
+
+add_library(common
+ ${PRIVATE_SOURCES}
+ ${PRIVATE_PCH_SOURCE}
)
# Do NOT add any extra include directory here, as we don't want the common
@@ -55,37 +46,53 @@ set(common_STAT_SRCS
# linkage (enums, defines...) it is discouraged to do so unless necessary, as it will pullute
# include_directories leading to further unnoticed dependency aditions
# Linker Depencency requirements: none
-include_directories(
- ${CMAKE_BINARY_DIR}
+CollectIncludeDirectories(
${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR}/Collision
- ${CMAKE_CURRENT_SOURCE_DIR}/Collision/Management
- ${CMAKE_CURRENT_SOURCE_DIR}/Collision/Maps
- ${CMAKE_CURRENT_SOURCE_DIR}/Collision/Models
- ${CMAKE_CURRENT_SOURCE_DIR}/Configuration
- ${CMAKE_CURRENT_SOURCE_DIR}/Cryptography
- ${CMAKE_CURRENT_SOURCE_DIR}/Debugging
- ${CMAKE_CURRENT_SOURCE_DIR}/Logging
- ${CMAKE_CURRENT_SOURCE_DIR}/Utilities
- ${CMAKE_SOURCE_DIR}/dep/cppformat
- ${CMAKE_SOURCE_DIR}/dep/g3dlite/include
- ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour/Include
- ${CMAKE_SOURCE_DIR}/dep/SFMT
- ${CMAKE_SOURCE_DIR}/dep/utf8cpp
- ${OPENSSL_INCLUDE_DIR}
- ${VALGRIND_INCLUDE_DIR}
-)
+ PUBLIC_INCLUDES
+ # Exclude
+ ${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders)
-GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
+target_include_directories(common
+ PUBLIC
+ # Provide the binary dir for all child targets
+ ${CMAKE_BINARY_DIR}
+ ${PUBLIC_INCLUDES}
+ PRIVATE
+ ${CMAKE_CURRENT_BINARY_DIR})
-add_library(common STATIC
- ${common_STAT_SRCS}
- ${common_STAT_PCH_SRC}
-)
+target_link_libraries(common
+ PUBLIC
+ boost
+ cppformat
+ g3dlib
+ Detour
+ sfmt
+ utf8cpp
+ openssl
+ valgrind
+ threads
+ jemalloc)
add_dependencies(common revision_data.h)
+set_target_properties(common
+ PROPERTIES
+ FOLDER
+ "server")
+
+if( BUILD_SHARED_LIBS )
+ if( UNIX )
+ install(TARGETS common
+ LIBRARY
+ DESTINATION lib)
+ elseif( WIN32 )
+ install(TARGETS common
+ RUNTIME
+ DESTINATION "${CMAKE_INSTALL_PREFIX}")
+ endif()
+endif()
+
# Generate precompiled header
if (USE_COREPCH)
- add_cxx_pch(common ${common_STAT_PCH_HDR} ${common_STAT_PCH_SRC})
+ add_cxx_pch(common ${PRIVATE_PCH_HEADER} ${PRIVATE_PCH_SOURCE})
endif ()
diff --git a/src/common/Collision/BoundingIntervalHierarchy.h b/src/common/Collision/BoundingIntervalHierarchy.h
index 0b15bd2d92f..eb0a102806f 100644
--- a/src/common/Collision/BoundingIntervalHierarchy.h
+++ b/src/common/Collision/BoundingIntervalHierarchy.h
@@ -67,7 +67,7 @@ struct AABound
Copyright (c) 2003-2007 Christopher Kulla
*/
-class BIH
+class TC_COMMON_API BIH
{
private:
void init_empty()
diff --git a/src/common/Collision/DynamicTree.h b/src/common/Collision/DynamicTree.h
index 0f18bb265f8..85707efebd2 100644
--- a/src/common/Collision/DynamicTree.h
+++ b/src/common/Collision/DynamicTree.h
@@ -31,7 +31,7 @@ namespace G3D
class GameObjectModel;
struct DynTreeImpl;
-class DynamicMapTree
+class TC_COMMON_API DynamicMapTree
{
DynTreeImpl *impl;
diff --git a/src/common/Collision/Management/IVMapManager.h b/src/common/Collision/Management/IVMapManager.h
index 1e64551956c..35437b7b816 100644
--- a/src/common/Collision/Management/IVMapManager.h
+++ b/src/common/Collision/Management/IVMapManager.h
@@ -42,7 +42,7 @@ namespace VMAP
#define VMAP_INVALID_HEIGHT_VALUE -200000.0f // real assigned value in unknown height case
//===========================================================
- class IVMapManager
+ class TC_COMMON_API IVMapManager
{
private:
bool iEnableLineOfSightCalc;
diff --git a/src/common/Collision/Management/MMapFactory.h b/src/common/Collision/Management/MMapFactory.h
index edd074fc93d..6dda7a40a22 100644
--- a/src/common/Collision/Management/MMapFactory.h
+++ b/src/common/Collision/Management/MMapFactory.h
@@ -38,7 +38,7 @@ namespace MMAP
// static class
// holds all mmap global data
// access point to MMapManager singleton
- class MMapFactory
+ class TC_COMMON_API MMapFactory
{
public:
static MMapManager* createOrGetMMapManager();
diff --git a/src/common/Collision/Management/MMapManager.h b/src/common/Collision/Management/MMapManager.h
index 1a502a916dd..afb693553a4 100644
--- a/src/common/Collision/Management/MMapManager.h
+++ b/src/common/Collision/Management/MMapManager.h
@@ -58,7 +58,7 @@ namespace MMAP
// singleton class
// holds all all access to mmap loading unloading and meshes
- class MMapManager
+ class TC_COMMON_API MMapManager
{
public:
MMapManager() : loadedTiles(0), thread_safe_environment(true) {}
diff --git a/src/common/Collision/Management/VMapFactory.h b/src/common/Collision/Management/VMapFactory.h
index 1a45bd5094b..a730fa12ef2 100644
--- a/src/common/Collision/Management/VMapFactory.h
+++ b/src/common/Collision/Management/VMapFactory.h
@@ -29,7 +29,7 @@ namespace VMAP
{
//===========================================================
- class VMapFactory
+ class TC_COMMON_API VMapFactory
{
public:
static IVMapManager* createOrGetVMapManager();
diff --git a/src/common/Collision/Management/VMapManager2.h b/src/common/Collision/Management/VMapManager2.h
index 722ac4935c6..61c5025e41f 100644
--- a/src/common/Collision/Management/VMapManager2.h
+++ b/src/common/Collision/Management/VMapManager2.h
@@ -51,7 +51,7 @@ namespace VMAP
class StaticMapTree;
class WorldModel;
- class ManagedModel
+ class TC_COMMON_API ManagedModel
{
public:
ManagedModel() : iModel(nullptr), iRefCount(0) { }
@@ -75,7 +75,7 @@ namespace VMAP
VMAP_DISABLE_LIQUIDSTATUS = 0x8
};
- class VMapManager2 : public IVMapManager
+ class TC_COMMON_API VMapManager2 : public IVMapManager
{
protected:
// Tree to check collision
diff --git a/src/common/Collision/Maps/MapTree.h b/src/common/Collision/Maps/MapTree.h
index 63d542754c1..c6a283cac4d 100644
--- a/src/common/Collision/Maps/MapTree.h
+++ b/src/common/Collision/Maps/MapTree.h
@@ -29,7 +29,7 @@ namespace VMAP
class GroupModel;
class VMapManager2;
- struct LocationInfo
+ struct TC_COMMON_API LocationInfo
{
LocationInfo(): hitInstance(nullptr), hitModel(nullptr), ground_Z(-G3D::finf()) { }
const ModelInstance* hitInstance;
@@ -37,7 +37,7 @@ namespace VMAP
float ground_Z;
};
- class StaticMapTree
+ class TC_COMMON_API StaticMapTree
{
typedef std::unordered_map<uint32, bool> loadedTileMap;
typedef std::unordered_map<uint32, uint32> loadedSpawnMap;
@@ -87,7 +87,7 @@ namespace VMAP
StaticMapTree& operator=(StaticMapTree const& right) = delete;
};
- struct AreaInfo
+ struct TC_COMMON_API AreaInfo
{
AreaInfo(): result(false), ground_Z(-G3D::finf()), flags(0), adtId(0),
rootId(0), groupId(0) { }
diff --git a/src/common/Collision/Maps/TileAssembler.h b/src/common/Collision/Maps/TileAssembler.h
index 1e2dc1924f1..74111f69910 100644
--- a/src/common/Collision/Maps/TileAssembler.h
+++ b/src/common/Collision/Maps/TileAssembler.h
@@ -35,7 +35,7 @@ namespace VMAP
*/
//===============================================
- class ModelPosition
+ class TC_COMMON_API ModelPosition
{
private:
G3D::Matrix3 iRotation;
@@ -55,7 +55,7 @@ namespace VMAP
typedef std::map<uint32, ModelSpawn> UniqueEntryMap;
typedef std::multimap<uint32, uint32> TileMap;
- struct MapSpawns
+ struct TC_COMMON_API MapSpawns
{
UniqueEntryMap UniqueEntries;
TileMap TileEntries;
@@ -64,7 +64,7 @@ namespace VMAP
typedef std::map<uint32, MapSpawns*> MapData;
//===============================================
- struct GroupModel_Raw
+ struct TC_COMMON_API GroupModel_Raw
{
uint32 mogpflags;
uint32 GroupWMOID;
@@ -82,7 +82,7 @@ namespace VMAP
bool Read(FILE* f);
};
- struct WorldModel_Raw
+ struct TC_COMMON_API WorldModel_Raw
{
uint32 RootWMOID;
std::vector<GroupModel_Raw> groupsArray;
@@ -90,7 +90,7 @@ namespace VMAP
bool Read(const char * path);
};
- class TileAssembler
+ class TC_COMMON_API TileAssembler
{
private:
std::string iDestDir;
diff --git a/src/common/Collision/Models/GameObjectModel.h b/src/common/Collision/Models/GameObjectModel.h
index 9d8687233c1..37f11af20ac 100644
--- a/src/common/Collision/Models/GameObjectModel.h
+++ b/src/common/Collision/Models/GameObjectModel.h
@@ -35,7 +35,7 @@ namespace VMAP
class GameObject;
struct GameObjectDisplayInfoEntry;
-class GameObjectModelOwnerBase
+class TC_COMMON_API GameObjectModelOwnerBase
{
public:
virtual bool IsSpawned() const { return false; }
@@ -47,7 +47,7 @@ public:
virtual void DebugVisualizeCorner(G3D::Vector3 const& /*corner*/) const { }
};
-class GameObjectModel /*, public Intersectable*/
+class TC_COMMON_API GameObjectModel /*, public Intersectable*/
{
GameObjectModel() : phasemask(0), iInvScale(0), iScale(0), iModel(NULL) { }
public:
@@ -84,4 +84,6 @@ private:
std::unique_ptr<GameObjectModelOwnerBase> owner;
};
+TC_COMMON_API void LoadGameObjectModelList(std::string const& dataPath);
+
#endif // _GAMEOBJECT_MODEL_H
diff --git a/src/common/Collision/Models/ModelInstance.h b/src/common/Collision/Models/ModelInstance.h
index d101630d1e9..84a41b15ce6 100644
--- a/src/common/Collision/Models/ModelInstance.h
+++ b/src/common/Collision/Models/ModelInstance.h
@@ -39,7 +39,7 @@ namespace VMAP
MOD_HAS_BOUND = 1<<2
};
- class ModelSpawn
+ class TC_COMMON_API ModelSpawn
{
public:
//mapID, tileX, tileY, Flags, ID, Pos, Rot, Scale, Bound_lo, Bound_hi, name
@@ -60,7 +60,7 @@ namespace VMAP
static bool writeToFile(FILE* rw, const ModelSpawn &spawn);
};
- class ModelInstance: public ModelSpawn
+ class TC_COMMON_API ModelInstance: public ModelSpawn
{
public:
ModelInstance(): iInvScale(0.0f), iModel(nullptr) { }
diff --git a/src/common/Collision/Models/WorldModel.h b/src/common/Collision/Models/WorldModel.h
index 39787f6c664..bfc0367627f 100644
--- a/src/common/Collision/Models/WorldModel.h
+++ b/src/common/Collision/Models/WorldModel.h
@@ -33,7 +33,7 @@ namespace VMAP
struct AreaInfo;
struct LocationInfo;
- class MeshTriangle
+ class TC_COMMON_API MeshTriangle
{
public:
MeshTriangle() : idx0(0), idx1(0), idx2(0) { }
@@ -44,7 +44,7 @@ namespace VMAP
uint32 idx2;
};
- class WmoLiquid
+ class TC_COMMON_API WmoLiquid
{
public:
WmoLiquid(uint32 width, uint32 height, const G3D::Vector3 &corner, uint32 type);
@@ -70,7 +70,7 @@ namespace VMAP
};
/*! holding additional info for WMO group files */
- class GroupModel
+ class TC_COMMON_API GroupModel
{
public:
GroupModel() : iBound(), iMogpFlags(0), iGroupWMOID(0), iLiquid(NULL) { }
@@ -103,7 +103,7 @@ namespace VMAP
};
/*! Holds a model (converted M2 or WMO) in its original coordinate space */
- class WorldModel
+ class TC_COMMON_API WorldModel
{
public:
WorldModel(): RootWMOID(0) { }
diff --git a/src/common/Collision/RegularGrid.h b/src/common/Collision/RegularGrid.h
index 6a2a07968ad..563cf516406 100644
--- a/src/common/Collision/RegularGrid.h
+++ b/src/common/Collision/RegularGrid.h
@@ -20,7 +20,7 @@ class NodeCreatorFunc = NodeCreator<Node>,
/*class BoundsFunc = BoundsTrait<T>,*/
class PositionFunc = PositionTrait<T>
>
-class RegularGrid2D
+class TC_COMMON_API RegularGrid2D
{
public:
diff --git a/src/common/Common.h b/src/common/Common.h
index e8adc55d20d..4ab5ae867b9 100644
--- a/src/common/Common.h
+++ b/src/common/Common.h
@@ -130,9 +130,9 @@ enum LocaleConstant
#define MAX_LOCALES 8
#define MAX_ACCOUNT_TUTORIAL_VALUES 8
-extern char const* localeNames[TOTAL_LOCALES];
+TC_COMMON_API extern char const* localeNames[TOTAL_LOCALES];
-LocaleConstant GetLocaleByName(const std::string& name);
+TC_COMMON_API LocaleConstant GetLocaleByName(const std::string& name);
typedef std::vector<std::string> StringVector;
diff --git a/src/common/Configuration/BuiltInConfig.cpp b/src/common/Configuration/BuiltInConfig.cpp
new file mode 100644
index 00000000000..c2fc3b91766
--- /dev/null
+++ b/src/common/Configuration/BuiltInConfig.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "BuiltInConfig.h"
+#include "Config.h"
+#include "GitRevision.h"
+
+template<typename Fn>
+static std::string GetStringWithDefaultValueFromFunction(
+ std::string const& key, Fn getter)
+{
+ std::string const value = sConfigMgr->GetStringDefault(key, "");
+ return value.empty() ? getter() : value;
+}
+
+std::string BuiltInConfig::GetCMakeCommand()
+{
+ return GetStringWithDefaultValueFromFunction(
+ "CMakeCommand", GitRevision::GetCMakeCommand);
+}
+
+std::string BuiltInConfig::GetBuildDirectory()
+{
+ return GetStringWithDefaultValueFromFunction(
+ "BuildDirectory", GitRevision::GetBuildDirectory);
+}
+
+std::string BuiltInConfig::GetSourceDirectory()
+{
+ return GetStringWithDefaultValueFromFunction(
+ "SourceDirectory", GitRevision::GetSourceDirectory);
+}
+
+std::string BuiltInConfig::GetMySQLExecutable()
+{
+ return GetStringWithDefaultValueFromFunction(
+ "MySQLExecutable", GitRevision::GetMySQLExecutable);
+}
diff --git a/src/common/Configuration/BuiltInConfig.h b/src/common/Configuration/BuiltInConfig.h
new file mode 100644
index 00000000000..0ffa059bc41
--- /dev/null
+++ b/src/common/Configuration/BuiltInConfig.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef BUILT_IN_CONFIG_H
+#define BUILT_IN_CONFIG_H
+
+#include <string>
+#include "Define.h"
+
+/// Provides helper functions to access built-in values
+/// which can be overwritten in config
+namespace BuiltInConfig
+{
+ /// Returns the CMake command when any is specified in the config,
+ /// returns the built-in path otherwise
+ TC_COMMON_API std::string GetCMakeCommand();
+ /// Returns the build directory path when any is specified in the config,
+ /// returns the built-in one otherwise
+ TC_COMMON_API std::string GetBuildDirectory();
+ /// Returns the source directory path when any is specified in the config,
+ /// returns the built-in one otherwise
+ TC_COMMON_API std::string GetSourceDirectory();
+ /// Returns the path to the mysql executable (`mysql`) when any is specified
+ /// in the config, returns the built-in one otherwise
+ TC_COMMON_API std::string GetMySQLExecutable();
+
+} // namespace BuiltInConfig
+
+#endif // BUILT_IN_CONFIG_H
diff --git a/src/common/Configuration/Config.cpp b/src/common/Configuration/Config.cpp
index 6ac04615315..fba438dbd33 100644
--- a/src/common/Configuration/Config.cpp
+++ b/src/common/Configuration/Config.cpp
@@ -56,12 +56,18 @@ bool ConfigMgr::LoadInitial(std::string const& file, std::string& error)
return true;
}
+ConfigMgr* ConfigMgr::instance()
+{
+ static ConfigMgr instance;
+ return &instance;
+}
+
bool ConfigMgr::Reload(std::string& error)
{
return LoadInitial(_filename, error);
}
-std::string ConfigMgr::GetStringDefault(std::string const& name, const std::string& def)
+std::string ConfigMgr::GetStringDefault(std::string const& name, const std::string& def) const
{
std::string value = _config.get<std::string>(ptree::path_type(name, '/'), def);
@@ -70,7 +76,7 @@ std::string ConfigMgr::GetStringDefault(std::string const& name, const std::stri
return value;
}
-bool ConfigMgr::GetBoolDefault(std::string const& name, bool def)
+bool ConfigMgr::GetBoolDefault(std::string const& name, bool def) const
{
try
{
@@ -84,12 +90,12 @@ bool ConfigMgr::GetBoolDefault(std::string const& name, bool def)
}
}
-int ConfigMgr::GetIntDefault(std::string const& name, int def)
+int ConfigMgr::GetIntDefault(std::string const& name, int def) const
{
return _config.get<int>(ptree::path_type(name, '/'), def);
}
-float ConfigMgr::GetFloatDefault(std::string const& name, float def)
+float ConfigMgr::GetFloatDefault(std::string const& name, float def) const
{
return _config.get<float>(ptree::path_type(name, '/'), def);
}
diff --git a/src/common/Configuration/Config.h b/src/common/Configuration/Config.h
index 5b04212ed7c..ff6d279f9ce 100644
--- a/src/common/Configuration/Config.h
+++ b/src/common/Configuration/Config.h
@@ -19,12 +19,14 @@
#ifndef CONFIG_H
#define CONFIG_H
+#include "Define.h"
+
#include <string>
#include <list>
#include <mutex>
#include <boost/property_tree/ptree.hpp>
-class ConfigMgr
+class TC_COMMON_API ConfigMgr
{
ConfigMgr() { }
~ConfigMgr() { }
@@ -33,18 +35,14 @@ public:
/// Method used only for loading main configuration files (authserver.conf and worldserver.conf)
bool LoadInitial(std::string const& file, std::string& error);
- static ConfigMgr* instance()
- {
- static ConfigMgr instance;
- return &instance;
- }
+ static ConfigMgr* instance();
bool Reload(std::string& error);
- std::string GetStringDefault(std::string const& name, const std::string& def);
- bool GetBoolDefault(std::string const& name, bool def);
- int GetIntDefault(std::string const& name, int def);
- float GetFloatDefault(std::string const& name, float def);
+ std::string GetStringDefault(std::string const& name, const std::string& def) const;
+ bool GetBoolDefault(std::string const& name, bool def) const;
+ int GetIntDefault(std::string const& name, int def) const;
+ float GetFloatDefault(std::string const& name, float def) const;
std::string const& GetFilename();
std::list<std::string> GetKeysByString(std::string const& name);
diff --git a/src/common/Cryptography/ARC4.h b/src/common/Cryptography/ARC4.h
index f39e662e295..7e680176836 100644
--- a/src/common/Cryptography/ARC4.h
+++ b/src/common/Cryptography/ARC4.h
@@ -22,7 +22,7 @@
#include <openssl/evp.h>
#include "Define.h"
-class ARC4
+class TC_COMMON_API ARC4
{
public:
ARC4(uint8 len);
diff --git a/src/common/Cryptography/Authentication/AuthCrypt.h b/src/common/Cryptography/Authentication/AuthCrypt.h
index 878391e3ce8..db4de8a7bd1 100644
--- a/src/common/Cryptography/Authentication/AuthCrypt.h
+++ b/src/common/Cryptography/Authentication/AuthCrypt.h
@@ -23,7 +23,7 @@
class BigNumber;
-class AuthCrypt
+class TC_COMMON_API AuthCrypt
{
public:
AuthCrypt();
diff --git a/src/common/Cryptography/BigNumber.h b/src/common/Cryptography/BigNumber.h
index a5bda50dc72..1d21be1b431 100644
--- a/src/common/Cryptography/BigNumber.h
+++ b/src/common/Cryptography/BigNumber.h
@@ -24,7 +24,7 @@
struct bignum_st;
-class BigNumber
+class TC_COMMON_API BigNumber
{
public:
BigNumber();
diff --git a/src/common/Cryptography/HMACSHA1.h b/src/common/Cryptography/HMACSHA1.h
index 29a926d5b16..049847489a6 100644
--- a/src/common/Cryptography/HMACSHA1.h
+++ b/src/common/Cryptography/HMACSHA1.h
@@ -28,7 +28,7 @@ class BigNumber;
#define SEED_KEY_SIZE 16
-class HmacHash
+class TC_COMMON_API HmacHash
{
public:
HmacHash(uint32 len, uint8 *seed);
diff --git a/src/common/Cryptography/OpenSSLCrypto.h b/src/common/Cryptography/OpenSSLCrypto.h
index df1b14b5eda..65155df9af8 100644
--- a/src/common/Cryptography/OpenSSLCrypto.h
+++ b/src/common/Cryptography/OpenSSLCrypto.h
@@ -18,6 +18,8 @@
#ifndef OPENSSL_CRYPTO_H
#define OPENSSL_CRYPTO_H
+#include "Define.h"
+
/**
* A group of functions which setup openssl crypto module to work properly in multithreaded enviroment
* If not setup properly - it will crash
@@ -25,9 +27,9 @@
namespace OpenSSLCrypto
{
/// Needs to be called before threads using openssl are spawned
- void threadsSetup();
+ TC_COMMON_API void threadsSetup();
/// Needs to be called after threads using openssl are despawned
- void threadsCleanup();
+ TC_COMMON_API void threadsCleanup();
}
-#endif \ No newline at end of file
+#endif
diff --git a/src/common/Cryptography/SHA1.h b/src/common/Cryptography/SHA1.h
index ffa02176a2d..970ab5c0cb9 100644
--- a/src/common/Cryptography/SHA1.h
+++ b/src/common/Cryptography/SHA1.h
@@ -25,7 +25,7 @@
class BigNumber;
-class SHA1Hash
+class TC_COMMON_API SHA1Hash
{
public:
SHA1Hash();
diff --git a/src/common/Debugging/Errors.cpp b/src/common/Debugging/Errors.cpp
index 1ec66ff6d59..2ce00229e53 100644
--- a/src/common/Debugging/Errors.cpp
+++ b/src/common/Debugging/Errors.cpp
@@ -96,4 +96,11 @@ void Abort(char const* file, int line, char const* function)
exit(1);
}
+void AbortHandler(int /*sigval*/)
+{
+ // nothing useful to log here, no way to pass args
+ *((volatile int*)NULL) = 0;
+ exit(1);
+}
+
} // namespace Trinity
diff --git a/src/common/Debugging/Errors.h b/src/common/Debugging/Errors.h
index 38e311a6b13..e4b3563ca96 100644
--- a/src/common/Debugging/Errors.h
+++ b/src/common/Debugging/Errors.h
@@ -23,16 +23,18 @@
namespace Trinity
{
- DECLSPEC_NORETURN void Assert(char const* file, int line, char const* function, char const* message) ATTR_NORETURN;
- DECLSPEC_NORETURN void Assert(char const* file, int line, char const* function, char const* message, char const* format, ...) ATTR_NORETURN ATTR_PRINTF(5, 6);
+ DECLSPEC_NORETURN TC_COMMON_API void Assert(char const* file, int line, char const* function, char const* message) ATTR_NORETURN;
+ DECLSPEC_NORETURN TC_COMMON_API void Assert(char const* file, int line, char const* function, char const* message, char const* format, ...) ATTR_NORETURN ATTR_PRINTF(5, 6);
- DECLSPEC_NORETURN void Fatal(char const* file, int line, char const* function, char const* message, ...) ATTR_NORETURN ATTR_PRINTF(4, 5);
+ DECLSPEC_NORETURN TC_COMMON_API void Fatal(char const* file, int line, char const* function, char const* message, ...) ATTR_NORETURN ATTR_PRINTF(4, 5);
- DECLSPEC_NORETURN void Error(char const* file, int line, char const* function, char const* message) ATTR_NORETURN;
+ DECLSPEC_NORETURN TC_COMMON_API void Error(char const* file, int line, char const* function, char const* message) ATTR_NORETURN;
- DECLSPEC_NORETURN void Abort(char const* file, int line, char const* function) ATTR_NORETURN;
+ DECLSPEC_NORETURN TC_COMMON_API void Abort(char const* file, int line, char const* function) ATTR_NORETURN;
- void Warning(char const* file, int line, char const* function, char const* message);
+ TC_COMMON_API void Warning(char const* file, int line, char const* function, char const* message);
+
+ DECLSPEC_NORETURN TC_COMMON_API void AbortHandler(int sigval) ATTR_NORETURN;
} // namespace Trinity
diff --git a/src/common/Define.h b/src/common/Define.h
index b34edb6a549..d03d26ad780 100644
--- a/src/common/Define.h
+++ b/src/common/Define.h
@@ -95,6 +95,45 @@
#endif
#endif //COMPILER == COMPILER_GNU
+#ifdef TRINITY_API_USE_DYNAMIC_LINKING
+# if COMPILER == COMPILER_MICROSOFT
+# define TC_API_EXPORT __declspec(dllexport)
+# define TC_API_IMPORT __declspec(dllimport)
+# elif COMPILER == COMPILER_GNU
+# define TC_API_EXPORT __attribute__((visibility("default")))
+# define TC_API_IMPORT
+# else
+# error compiler not supported!
+# endif
+#else
+# define TC_API_EXPORT
+# define TC_API_IMPORT
+#endif
+
+#ifdef TRINITY_API_EXPORT_COMMON
+# define TC_COMMON_API TC_API_EXPORT
+#else
+# define TC_COMMON_API TC_API_IMPORT
+#endif
+
+#ifdef TRINITY_API_EXPORT_DATABASE
+# define TC_DATABASE_API TC_API_EXPORT
+#else
+# define TC_DATABASE_API TC_API_IMPORT
+#endif
+
+#ifdef TRINITY_API_EXPORT_SHARED
+# define TC_SHARED_API TC_API_EXPORT
+#else
+# define TC_SHARED_API TC_API_IMPORT
+#endif
+
+#ifdef TRINITY_API_EXPORT_GAME
+# define TC_GAME_API TC_API_EXPORT
+#else
+# define TC_GAME_API TC_API_IMPORT
+#endif
+
#define UI64FMTD "%" PRIu64
#define UI64LIT(N) UINT64_C(N)
diff --git a/src/common/GitRevision.cpp b/src/common/GitRevision.cpp
index d0719c09959..2162e36847f 100644
--- a/src/common/GitRevision.cpp
+++ b/src/common/GitRevision.cpp
@@ -1,5 +1,4 @@
#include "GitRevision.h"
-#include "CompilerDefs.h"
#include "revision_data.h"
char const* GitRevision::GetHash()
@@ -17,6 +16,16 @@ char const* GitRevision::GetBranch()
return _BRANCH;
}
+char const* GitRevision::GetCMakeCommand()
+{
+ return _CMAKE_COMMAND;
+}
+
+char const* GitRevision::GetBuildDirectory()
+{
+ return _BUILD_DIRECTORY;
+}
+
char const* GitRevision::GetSourceDirectory()
{
return _SOURCE_DIRECTORY;
@@ -66,13 +75,3 @@ char const* GitRevision::GetProductVersionStr()
{
return VER_PRODUCTVERSION_STR;
}
-
-char const* GitRevision::GetCompilerCFlags()
-{
- return COMPILER_C_FLAGS;
-}
-
-char const* GitRevision::GetCompilerCXXFlags()
-{
- return COMPILER_CXX_FLAGS;
-}
diff --git a/src/common/GitRevision.h b/src/common/GitRevision.h
index 8d2764ba861..aace8ad2076 100644
--- a/src/common/GitRevision.h
+++ b/src/common/GitRevision.h
@@ -19,22 +19,23 @@
#define __GITREVISION_H__
#include <string>
+#include "Define.h"
namespace GitRevision
{
- char const* GetHash();
- char const* GetDate();
- char const* GetBranch();
- char const* GetSourceDirectory();
- char const* GetMySQLExecutable();
- char const* GetFullDatabase();
- char const* GetFullVersion();
- char const* GetCompanyNameStr();
- char const* GetLegalCopyrightStr();
- char const* GetFileVersionStr();
- char const* GetProductVersionStr();
- char const* GetCompilerCFlags();
- char const* GetCompilerCXXFlags();
+ TC_COMMON_API char const* GetHash();
+ TC_COMMON_API char const* GetDate();
+ TC_COMMON_API char const* GetBranch();
+ TC_COMMON_API char const* GetCMakeCommand();
+ TC_COMMON_API char const* GetBuildDirectory();
+ TC_COMMON_API char const* GetSourceDirectory();
+ TC_COMMON_API char const* GetMySQLExecutable();
+ TC_COMMON_API char const* GetFullDatabase();
+ TC_COMMON_API char const* GetFullVersion();
+ TC_COMMON_API char const* GetCompanyNameStr();
+ TC_COMMON_API char const* GetLegalCopyrightStr();
+ TC_COMMON_API char const* GetFileVersionStr();
+ TC_COMMON_API char const* GetProductVersionStr();
}
#endif
diff --git a/src/common/Logging/Appender.h b/src/common/Logging/Appender.h
index f0bfe423a66..22fe1112239 100644
--- a/src/common/Logging/Appender.h
+++ b/src/common/Logging/Appender.h
@@ -59,7 +59,7 @@ enum AppenderFlags
APPENDER_FLAGS_MAKE_FILE_BACKUP = 0x10 // only used by FileAppender
};
-struct LogMessage
+struct TC_COMMON_API LogMessage
{
LogMessage(LogLevel _level, std::string const& _type, std::string&& _text)
: level(_level), type(_type), text(std::forward<std::string>(_text)), mtime(time(NULL))
@@ -85,7 +85,7 @@ struct LogMessage
}
};
-class Appender
+class TC_COMMON_API Appender
{
public:
Appender(uint8 _id, std::string const& name, LogLevel level = LOG_LEVEL_DISABLED, AppenderFlags flags = APPENDER_FLAGS_NONE);
@@ -123,7 +123,7 @@ Appender* CreateAppender(uint8 id, std::string const& name, LogLevel level, Appe
return new AppenderImpl(id, name, level, flags, std::forward<ExtraAppenderArgs>(extraArgs));
}
-class InvalidAppenderArgsException : public std::length_error
+class TC_COMMON_API InvalidAppenderArgsException : public std::length_error
{
public:
explicit InvalidAppenderArgsException(std::string const& message) : std::length_error(message) { }
diff --git a/src/common/Logging/AppenderConsole.h b/src/common/Logging/AppenderConsole.h
index 5d7eae36b40..96d17207158 100644
--- a/src/common/Logging/AppenderConsole.h
+++ b/src/common/Logging/AppenderConsole.h
@@ -42,7 +42,7 @@ enum ColorTypes
const uint8 MaxColors = uint8(WHITE) + 1;
-class AppenderConsole : public Appender
+class TC_COMMON_API AppenderConsole : public Appender
{
public:
typedef std::integral_constant<AppenderType, APPENDER_CONSOLE>::type TypeIndex;
diff --git a/src/common/Logging/AppenderFile.h b/src/common/Logging/AppenderFile.h
index 9ba5d59259c..956b7a70b93 100644
--- a/src/common/Logging/AppenderFile.h
+++ b/src/common/Logging/AppenderFile.h
@@ -21,7 +21,7 @@
#include <atomic>
#include "Appender.h"
-class AppenderFile : public Appender
+class TC_COMMON_API AppenderFile : public Appender
{
public:
typedef std::integral_constant<AppenderType, APPENDER_FILE>::type TypeIndex;
diff --git a/src/common/Logging/Log.cpp b/src/common/Logging/Log.cpp
index 4bd0487343d..f7a84fb8b47 100644
--- a/src/common/Logging/Log.cpp
+++ b/src/common/Logging/Log.cpp
@@ -214,13 +214,13 @@ void Log::ReadLoggersFromConfig()
AppenderConsole* appender = new AppenderConsole(NextAppenderId(), "Console", LOG_LEVEL_DEBUG, APPENDER_FLAGS_NONE, ExtraAppenderArgs());
appenders[appender->getId()] = appender;
- Logger& logger = loggers[LOGGER_ROOT];
- logger.Create(LOGGER_ROOT, LOG_LEVEL_ERROR);
- logger.addAppender(appender->getId(), appender);
+ Logger& rootLogger = loggers[LOGGER_ROOT];
+ rootLogger.Create(LOGGER_ROOT, LOG_LEVEL_ERROR);
+ rootLogger.addAppender(appender->getId(), appender);
- logger = loggers["server"];
- logger.Create("server", LOG_LEVEL_ERROR);
- logger.addAppender(appender->getId(), appender);
+ Logger& serverLogger = loggers["server"];
+ serverLogger.Create("server", LOG_LEVEL_INFO);
+ serverLogger.addAppender(appender->getId(), appender);
}
}
@@ -320,6 +320,12 @@ void Log::Close()
appenders.clear();
}
+Log* Log::instance()
+{
+ static Log instance;
+ return &instance;
+}
+
void Log::Initialize(boost::asio::io_service* ioService)
{
if (ioService)
@@ -331,6 +337,13 @@ void Log::Initialize(boost::asio::io_service* ioService)
LoadFromConfig();
}
+void Log::SetSynchronous()
+{
+ delete _strand;
+ _strand = nullptr;
+ _ioService = nullptr;
+}
+
void Log::LoadFromConfig()
{
Close();
diff --git a/src/common/Logging/Log.h b/src/common/Logging/Log.h
index a90481ad5d2..6460e404c90 100644
--- a/src/common/Logging/Log.h
+++ b/src/common/Logging/Log.h
@@ -34,7 +34,7 @@
#define LOGGER_ROOT "root"
-class Log
+class TC_COMMON_API Log
{
typedef std::unordered_map<std::string, Logger> LoggerMap;
@@ -44,13 +44,10 @@ class Log
public:
- static Log* instance()
- {
- static Log instance;
- return &instance;
- }
+ static Log* instance();
void Initialize(boost::asio::io_service* ioService);
+ void SetSynchronous(); // Not threadsafe - should only be called from main() after all threads are joined
void LoadFromConfig();
void Close();
bool ShouldLog(std::string const& type, LogLevel level) const;
diff --git a/src/common/Logging/LogOperation.h b/src/common/Logging/LogOperation.h
index 618629b5423..56e2307d492 100644
--- a/src/common/Logging/LogOperation.h
+++ b/src/common/Logging/LogOperation.h
@@ -19,11 +19,12 @@
#define LOGOPERATION_H
#include <memory>
+#include "Define.h"
class Logger;
struct LogMessage;
-class LogOperation
+class TC_COMMON_API LogOperation
{
public:
LogOperation(Logger const* _logger, std::unique_ptr<LogMessage>&& _msg)
diff --git a/src/common/Logging/Logger.h b/src/common/Logging/Logger.h
index 67eab4295a4..4ac2e4494cc 100644
--- a/src/common/Logging/Logger.h
+++ b/src/common/Logging/Logger.h
@@ -20,7 +20,7 @@
#include "Appender.h"
-class Logger
+class TC_COMMON_API Logger
{
public:
Logger();
diff --git a/src/server/shared/Service/ServiceWin32.cpp b/src/common/Platform/ServiceWin32.cpp
index b6a1682993b..3c34f3e322c 100644
--- a/src/server/shared/Service/ServiceWin32.cpp
+++ b/src/common/Platform/ServiceWin32.cpp
@@ -261,4 +261,3 @@ bool WinServiceRun()
return true;
}
#endif
-
diff --git a/src/server/shared/Service/ServiceWin32.h b/src/common/Platform/ServiceWin32.h
index 3d67bfe5445..b892ba4e3b6 100644
--- a/src/server/shared/Service/ServiceWin32.h
+++ b/src/common/Platform/ServiceWin32.h
@@ -26,4 +26,3 @@ bool WinServiceRun();
#endif // _WIN32_SERVICE_
#endif // _WIN32
-
diff --git a/src/common/Threading/LockedQueue.h b/src/common/Threading/LockedQueue.h
index c6faaaf81ca..21a29d7e53b 100644
--- a/src/common/Threading/LockedQueue.h
+++ b/src/common/Threading/LockedQueue.h
@@ -57,6 +57,14 @@ public:
unlock();
}
+ //! Adds items back to front of the queue
+ template<class Iterator>
+ void readd(Iterator begin, Iterator end)
+ {
+ std::lock_guard<std::mutex> lock(_lock);
+ _queue.insert(_queue.begin(), begin, end);
+ }
+
//! Gets the next result in the queue, if any.
bool next(T& result)
{
diff --git a/src/common/Threading/MPSCQueue.h b/src/common/Threading/MPSCQueue.h
new file mode 100644
index 00000000000..09648b844be
--- /dev/null
+++ b/src/common/Threading/MPSCQueue.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MPSCQueue_h__
+#define MPSCQueue_h__
+
+#include <atomic>
+#include <utility>
+
+// C++ implementation of Dmitry Vyukov's lock free MPSC queue
+// http://www.1024cores.net/home/lock-free-algorithms/queues/non-intrusive-mpsc-node-based-queue
+template<typename T>
+class MPSCQueue
+{
+public:
+ MPSCQueue() : _head(new Node()), _tail(_head.load(std::memory_order_relaxed))
+ {
+ Node* front = _head.load(std::memory_order_relaxed);
+ front->Next.store(nullptr, std::memory_order_relaxed);
+ }
+
+ ~MPSCQueue()
+ {
+ T* output;
+ while (this->Dequeue(output))
+ ;
+
+ Node* front = _head.load(std::memory_order_relaxed);
+ delete front;
+ }
+
+ void Enqueue(T* input)
+ {
+ Node* node = new Node(input);
+ Node* prevHead = _head.exchange(node, std::memory_order_acq_rel);
+ prevHead->Next.store(node, std::memory_order_release);
+ }
+
+ bool Dequeue(T*& result)
+ {
+ Node* tail = _tail.load(std::memory_order_relaxed);
+ Node* next = tail->Next.load(std::memory_order_acquire);
+ if (!next)
+ return false;
+
+ result = next->Data;
+ _tail.store(next, std::memory_order_release);
+ delete tail;
+ return true;
+ }
+
+private:
+ struct Node
+ {
+ Node() = default;
+ explicit Node(T* data) : Data(data) { Next.store(nullptr, std::memory_order_relaxed); }
+
+ T* Data;
+ std::atomic<Node*> Next;
+ };
+
+ std::atomic<Node*> _head;
+ std::atomic<Node*> _tail;
+
+ MPSCQueue(MPSCQueue const&) = delete;
+ MPSCQueue& operator=(MPSCQueue const&) = delete;
+};
+
+#endif // MPSCQueue_h__
diff --git a/src/common/Utilities/Containers.h b/src/common/Utilities/Containers.h
index f3e9432ca4c..7c889068011 100644
--- a/src/common/Utilities/Containers.h
+++ b/src/common/Utilities/Containers.h
@@ -20,6 +20,7 @@
#include "Define.h"
#include "Random.h"
+#include "Util.h"
#include <algorithm>
#include <functional>
#include <list>
diff --git a/src/common/Utilities/EventMap.h b/src/common/Utilities/EventMap.h
index a1aaa9af269..bb40980181d 100644
--- a/src/common/Utilities/EventMap.h
+++ b/src/common/Utilities/EventMap.h
@@ -22,7 +22,7 @@
#include "Duration.h"
#include "Util.h"
-class EventMap
+class TC_COMMON_API EventMap
{
/**
* Internal storage type.
diff --git a/src/common/Utilities/EventProcessor.h b/src/common/Utilities/EventProcessor.h
index e5eafed79b9..e10558e6a21 100644
--- a/src/common/Utilities/EventProcessor.h
+++ b/src/common/Utilities/EventProcessor.h
@@ -25,7 +25,7 @@
// Note. All times are in milliseconds here.
-class BasicEvent
+class TC_COMMON_API BasicEvent
{
public:
BasicEvent()
@@ -55,7 +55,7 @@ class BasicEvent
typedef std::multimap<uint64, BasicEvent*> EventList;
-class EventProcessor
+class TC_COMMON_API EventProcessor
{
public:
EventProcessor();
diff --git a/src/common/Utilities/Random.cpp b/src/common/Utilities/Random.cpp
index cc013110b01..31318e8f52d 100644
--- a/src/common/Utilities/Random.cpp
+++ b/src/common/Utilities/Random.cpp
@@ -61,6 +61,14 @@ float frand(float min, float max)
return float(GetRng()->Random() * (max - min) + min);
}
+Milliseconds randtime(Milliseconds const& min, Milliseconds const& max)
+{
+ long long diff = max.count() - min.count();
+ ASSERT(diff >= 0);
+ ASSERT(diff <= (uint32)-1);
+ return min + Milliseconds(urand(0, diff));
+}
+
uint32 rand32()
{
return GetRng()->BRandom();
diff --git a/src/common/Utilities/Random.h b/src/common/Utilities/Random.h
index 5610651a83b..b3ca00219ef 100644
--- a/src/common/Utilities/Random.h
+++ b/src/common/Utilities/Random.h
@@ -19,29 +19,33 @@
#define Random_h__
#include "Define.h"
+#include "Duration.h"
#include <limits>
#include <random>
/* Return a random number in the range min..max. */
-int32 irand(int32 min, int32 max);
+TC_COMMON_API int32 irand(int32 min, int32 max);
/* Return a random number in the range min..max (inclusive). */
-uint32 urand(uint32 min, uint32 max);
+TC_COMMON_API uint32 urand(uint32 min, uint32 max);
/* Return a random millisecond value between min and max seconds. Functionally equivalent to urand(min*IN_MILLISECONDS, max*IN_MILLISECONDS). */
-uint32 urandms(uint32 min, uint32 max);
+TC_COMMON_API uint32 urandms(uint32 min, uint32 max);
/* Return a random number in the range 0 .. UINT32_MAX. */
-uint32 rand32();
+TC_COMMON_API uint32 rand32();
+
+/* Return a random time in the range min..max (up to millisecond precision). Only works for values where millisecond difference is a valid uint32. */
+TC_COMMON_API Milliseconds randtime(Milliseconds const& min, Milliseconds const& max);
/* Return a random number in the range min..max */
-float frand(float min, float max);
+TC_COMMON_API float frand(float min, float max);
/* Return a random double from 0.0 to 1.0 (exclusive). */
-double rand_norm();
+TC_COMMON_API double rand_norm();
/* Return a random double from 0.0 to 100.0 (exclusive). */
-double rand_chance();
+TC_COMMON_API double rand_chance();
/* Return true if a random roll fits in the specified chance (range 0-100). */
inline bool roll_chance_f(float chance)
@@ -58,7 +62,7 @@ inline bool roll_chance_i(int chance)
/*
* SFMT wrapper satisfying UniformRandomNumberGenerator concept for use in <random> algorithms
*/
-class SFMTEngine
+class TC_COMMON_API SFMTEngine
{
public:
typedef uint32 result_type;
diff --git a/src/common/Utilities/StringFormat.h b/src/common/Utilities/StringFormat.h
index d85523bc11f..e21b1024e87 100644
--- a/src/common/Utilities/StringFormat.h
+++ b/src/common/Utilities/StringFormat.h
@@ -19,7 +19,7 @@
#ifndef TRINITYCORE_STRING_FORMAT_H
#define TRINITYCORE_STRING_FORMAT_H
-#include "format.h"
+#include "cppformat/format.h"
namespace Trinity
{
diff --git a/src/common/Utilities/TaskScheduler.h b/src/common/Utilities/TaskScheduler.h
index 8cf5d914128..c5163ef33d5 100644
--- a/src/common/Utilities/TaskScheduler.h
+++ b/src/common/Utilities/TaskScheduler.h
@@ -46,7 +46,7 @@ class TaskContext;
/// with the same duration or a new one.
/// It also provides access to the repeat counter which is useful for task that repeat itself often
/// but behave different every time (spoken event dialogs for example).
-class TaskScheduler
+class TC_COMMON_API TaskScheduler
{
friend class TaskContext;
@@ -131,7 +131,7 @@ class TaskScheduler
};
};
- class TaskQueue
+ class TC_COMMON_API TaskQueue
{
std::multiset<TaskContainer, Compare> container;
@@ -408,7 +408,7 @@ private:
void Dispatch(success_t const& callback);
};
-class TaskContext
+class TC_COMMON_API TaskContext
{
friend class TaskScheduler;
diff --git a/src/common/Utilities/Util.cpp b/src/common/Utilities/Util.cpp
index 1360253294f..6572280d00b 100644
--- a/src/common/Utilities/Util.cpp
+++ b/src/common/Utilities/Util.cpp
@@ -218,22 +218,29 @@ bool IsIPAddress(char const* ipaddress)
}
/// create PID file
-uint32 CreatePIDFile(const std::string& filename)
+uint32 CreatePIDFile(std::string const& filename)
{
- FILE* pid_file = fopen (filename.c_str(), "w" );
+ FILE* pid_file = fopen(filename.c_str(), "w");
if (pid_file == NULL)
return 0;
+ uint32 pid = GetPID();
+
+ fprintf(pid_file, "%u", pid);
+ fclose(pid_file);
+
+ return pid;
+}
+
+uint32 GetPID()
+{
#ifdef _WIN32
DWORD pid = GetCurrentProcessId();
#else
pid_t pid = getpid();
#endif
- fprintf(pid_file, "%u", pid );
- fclose(pid_file);
-
- return (uint32)pid;
+ return uint32(pid);
}
size_t utf8length(std::string& utf8str)
@@ -487,6 +494,17 @@ void vutf8printf(FILE* out, const char *str, va_list* ap)
#endif
}
+bool Utf8ToUpperOnlyLatin(std::string& utf8String)
+{
+ std::wstring wstr;
+ if (!Utf8toWStr(utf8String, wstr))
+ return false;
+
+ std::transform(wstr.begin(), wstr.end(), wstr.begin(), wcharToUpperOnlyLatin);
+
+ return WStrToUtf8(wstr, utf8String);
+}
+
std::string ByteArrayToHexStr(uint8 const* bytes, uint32 arrayLen, bool reverse /* = false */)
{
int32 init = 0;
diff --git a/src/common/Utilities/Util.h b/src/common/Utilities/Util.h
index ab5cabca8d2..cd0a8bae823 100644
--- a/src/common/Utilities/Util.h
+++ b/src/common/Utilities/Util.h
@@ -40,7 +40,7 @@ template<typename T, class S> struct Finder
bool operator()(const std::pair<int, S> &obj) { return obj.second.*idMember_ == val_; }
};
-class Tokenizer
+class TC_COMMON_API Tokenizer
{
public:
typedef std::vector<char const*> StorageType;
@@ -68,15 +68,15 @@ private:
StorageType m_storage;
};
-void stripLineInvisibleChars(std::string &src);
+TC_COMMON_API void stripLineInvisibleChars(std::string &src);
-int32 MoneyStringToMoney(const std::string& moneyString);
+TC_COMMON_API int32 MoneyStringToMoney(const std::string& moneyString);
-struct tm* localtime_r(const time_t* time, struct tm *result);
+TC_COMMON_API struct tm* localtime_r(const time_t* time, struct tm *result);
-std::string secsToTimeString(uint64 timeInSecs, bool shortText = false, bool hoursOnly = false);
-uint32 TimeStringToSecs(const std::string& timestring);
-std::string TimeToTimestampStr(time_t t);
+TC_COMMON_API std::string secsToTimeString(uint64 timeInSecs, bool shortText = false, bool hoursOnly = false);
+TC_COMMON_API uint32 TimeStringToSecs(const std::string& timestring);
+TC_COMMON_API std::string TimeToTimestampStr(time_t t);
inline void ApplyPercentModFloatVar(float& var, float val, bool apply)
{
@@ -111,20 +111,20 @@ inline T RoundToInterval(T& num, T floor, T ceil)
}
// UTF8 handling
-bool Utf8toWStr(const std::string& utf8str, std::wstring& wstr);
+TC_COMMON_API bool Utf8toWStr(const std::string& utf8str, std::wstring& wstr);
// in wsize==max size of buffer, out wsize==real string size
-bool Utf8toWStr(char const* utf8str, size_t csize, wchar_t* wstr, size_t& wsize);
+TC_COMMON_API bool Utf8toWStr(char const* utf8str, size_t csize, wchar_t* wstr, size_t& wsize);
inline bool Utf8toWStr(const std::string& utf8str, wchar_t* wstr, size_t& wsize)
{
return Utf8toWStr(utf8str.c_str(), utf8str.size(), wstr, wsize);
}
-bool WStrToUtf8(std::wstring const& wstr, std::string& utf8str);
+TC_COMMON_API bool WStrToUtf8(std::wstring const& wstr, std::string& utf8str);
// size==real string size
-bool WStrToUtf8(wchar_t* wstr, size_t size, std::string& utf8str);
+TC_COMMON_API bool WStrToUtf8(wchar_t* wstr, size_t size, std::string& utf8str);
-size_t utf8length(std::string& utf8str); // set string to "" if invalid utf8 sequence
-void utf8truncate(std::string& utf8str, size_t len);
+TC_COMMON_API size_t utf8length(std::string& utf8str); // set string to "" if invalid utf8 sequence
+TC_COMMON_API void utf8truncate(std::string& utf8str, size_t len);
inline bool isBasicLatinCharacter(wchar_t wchar)
{
@@ -303,19 +303,21 @@ inline void wstrToLower(std::wstring& str)
std::transform( str.begin(), str.end(), str.begin(), wcharToLower );
}
-std::wstring GetMainPartOfName(std::wstring const& wname, uint32 declension);
+TC_COMMON_API std::wstring GetMainPartOfName(std::wstring const& wname, uint32 declension);
-bool utf8ToConsole(const std::string& utf8str, std::string& conStr);
-bool consoleToUtf8(const std::string& conStr, std::string& utf8str);
-bool Utf8FitTo(const std::string& str, std::wstring const& search);
-void utf8printf(FILE* out, const char *str, ...);
-void vutf8printf(FILE* out, const char *str, va_list* ap);
+TC_COMMON_API bool utf8ToConsole(const std::string& utf8str, std::string& conStr);
+TC_COMMON_API bool consoleToUtf8(const std::string& conStr, std::string& utf8str);
+TC_COMMON_API bool Utf8FitTo(const std::string& str, std::wstring const& search);
+TC_COMMON_API void utf8printf(FILE* out, const char *str, ...);
+TC_COMMON_API void vutf8printf(FILE* out, const char *str, va_list* ap);
+TC_COMMON_API bool Utf8ToUpperOnlyLatin(std::string& utf8String);
-bool IsIPAddress(char const* ipaddress);
+TC_COMMON_API bool IsIPAddress(char const* ipaddress);
-uint32 CreatePIDFile(const std::string& filename);
+TC_COMMON_API uint32 CreatePIDFile(std::string const& filename);
+TC_COMMON_API uint32 GetPID();
-std::string ByteArrayToHexStr(uint8 const* bytes, uint32 length, bool reverse = false);
+TC_COMMON_API std::string ByteArrayToHexStr(uint8 const* bytes, uint32 length, bool reverse = false);
// simple class for not-modifyable list
template <typename T>
diff --git a/src/genrev/CMakeLists.txt b/src/genrev/CMakeLists.txt
index 91a13609037..355e2043b51 100644
--- a/src/genrev/CMakeLists.txt
+++ b/src/genrev/CMakeLists.txt
@@ -13,3 +13,8 @@ add_custom_target(revision_data.h ALL
COMMAND "${CMAKE_COMMAND}" -DBUILDDIR="${CMAKE_BINARY_DIR}" -P "${CMAKE_SOURCE_DIR}/cmake/genrev.cmake" "${CMAKE_BINARY_DIR}"
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
)
+
+set_target_properties(revision_data.h
+ PROPERTIES
+ FOLDER
+ "server")
diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt
index 9a454696ca8..2c7a4773e88 100644
--- a/src/server/CMakeLists.txt
+++ b/src/server/CMakeLists.txt
@@ -12,16 +12,19 @@
# This to stop a few silly crashes that could have been avoided IF people
# weren't doing some -O3 psychooptimizations etc.
-find_package(MySQL REQUIRED)
-
if(CMAKE_COMPILER_IS_GNUCXX AND NOT MINGW)
add_definitions(-fno-delete-null-pointer-checks)
endif()
-set(sources_windows_Debugging
- ${CMAKE_SOURCE_DIR}/src/common/Debugging/WheatyExceptionReport.cpp
- ${CMAKE_SOURCE_DIR}/src/common/Debugging/WheatyExceptionReport.h
-)
+if(WIN32)
+ set(sources_windows
+ ${CMAKE_SOURCE_DIR}/src/common/Debugging/WheatyExceptionReport.cpp
+ ${CMAKE_SOURCE_DIR}/src/common/Debugging/WheatyExceptionReport.h
+ ${CMAKE_SOURCE_DIR}/src/common/Platform/ServiceWin32.cpp
+ ${CMAKE_SOURCE_DIR}/src/common/Platform/ServiceWin32.h
+ )
+endif(WIN32)
+
add_subdirectory(database)
add_subdirectory(shared)
add_subdirectory(game)
diff --git a/src/server/authserver/CMakeLists.txt b/src/server/authserver/CMakeLists.txt
index c11deec39bb..1d40129ec1b 100644
--- a/src/server/authserver/CMakeLists.txt
+++ b/src/server/authserver/CMakeLists.txt
@@ -10,66 +10,29 @@
########### authserver ###############
-file(GLOB_RECURSE sources_authentication Authentication/*.cpp Authentication/*.h)
-file(GLOB_RECURSE sources_realms Realms/*.cpp Realms/*.h)
-file(GLOB_RECURSE sources_server Server/*.cpp Server/*.h)
-file(GLOB sources_localdir *.cpp *.h)
-
-if (USE_COREPCH)
- set(authserver_PCH_HDR PrecompiledHeaders/authPCH.h)
- set(authserver_PCH_SRC PrecompiledHeaders/authPCH.cpp)
-endif()
-
-set(authserver_SRCS
- ${authserver_SRCS}
- ${sources_authentication}
- ${sources_realms}
- ${sources_server}
- ${sources_localdir}
-)
+CollectSourceFiles(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ PRIVATE_SOURCES
+ # Exclude
+ ${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders)
if( WIN32 )
- set(authserver_SRCS
- ${authserver_SRCS}
- ${sources_windows_Debugging}
- )
+ list(APPEND PRIVATE_SOURCES ${sources_windows})
if ( MSVC )
- set(authserver_SRCS
- ${authserver_SRCS}
- authserver.rc
- )
- endif ()
+ list(APPEND PRIVATE_SOURCES authserver.rc)
+ endif()
endif()
-include_directories(
- ${CMAKE_BINARY_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR}/Authentication
- ${CMAKE_CURRENT_SOURCE_DIR}/Realms
- ${CMAKE_CURRENT_SOURCE_DIR}/Server
- ${CMAKE_SOURCE_DIR}/dep/cppformat
- ${CMAKE_SOURCE_DIR}/src/common/
- ${CMAKE_SOURCE_DIR}/src/common/Configuration
- ${CMAKE_SOURCE_DIR}/src/common/Cryptography
- ${CMAKE_SOURCE_DIR}/src/common/Debugging
- ${CMAKE_SOURCE_DIR}/src/common/Logging
- ${CMAKE_SOURCE_DIR}/src/common/Threading
- ${CMAKE_SOURCE_DIR}/src/common/Utilities
- ${CMAKE_SOURCE_DIR}/src/server/database
- ${CMAKE_SOURCE_DIR}/src/server/database/Database
- ${CMAKE_SOURCE_DIR}/src/server/database/Logging
- ${CMAKE_SOURCE_DIR}/src/server/shared/Networking
- ${CMAKE_SOURCE_DIR}/src/server/shared/Packets
- ${CMAKE_SOURCE_DIR}/src/server/shared/Service
- ${MYSQL_INCLUDE_DIR}
- ${OPENSSL_INCLUDE_DIR}
- ${VALGRIND_INCLUDE_DIR}
-)
+if (USE_COREPCH)
+ set(PRIVATE_PCH_HEADER PrecompiledHeaders/authPCH.h)
+ set(PRIVATE_PCH_SOURCE PrecompiledHeaders/authPCH.cpp)
+endif()
GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
add_executable(authserver
- ${authserver_SRCS}
- ${authserver_PCH_SRC}
+ ${PRIVATE_SOURCES}
+ ${PRIVATE_PCH_SOURCE}
)
if( NOT WIN32 )
@@ -79,15 +42,25 @@ if( NOT WIN32 )
endif()
target_link_libraries(authserver
- common
- shared
- format
- database
- ${MYSQL_LIBRARY}
- ${OPENSSL_LIBRARIES}
- ${CMAKE_THREAD_LIBS_INIT}
- ${Boost_LIBRARIES}
-)
+ PUBLIC
+ shared)
+
+CollectIncludeDirectories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ PUBLIC_INCLUDES
+ # Exclude
+ ${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders)
+
+target_include_directories(authserver
+ PUBLIC
+ ${PUBLIC_INCLUDES}
+ PRIVATE
+ ${CMAKE_CURRENT_BINARY_DIR})
+
+set_target_properties(authserver
+ PROPERTIES
+ FOLDER
+ "server")
if( WIN32 )
if ( MSVC )
@@ -113,5 +86,5 @@ endif()
# Generate precompiled header
if (USE_COREPCH)
- add_cxx_pch(authserver ${authserver_PCH_HDR} ${authserver_PCH_SRC})
+ add_cxx_pch(authserver ${PRIVATE_PCH_HEADER} ${PRIVATE_PCH_SOURCE})
endif()
diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp
index 0c812ebd494..a53187ad737 100644
--- a/src/server/authserver/Main.cpp
+++ b/src/server/authserver/Main.cpp
@@ -68,15 +68,19 @@ bool StartDB();
void StopDB();
void SignalHandler(const boost::system::error_code& error, int signalNumber);
void KeepDatabaseAliveHandler(const boost::system::error_code& error);
+void BanExpiryHandler(boost::system::error_code const& error);
variables_map GetConsoleArguments(int argc, char** argv, std::string& configFile, std::string& configService);
boost::asio::io_service* _ioService;
boost::asio::deadline_timer* _dbPingTimer;
uint32 _dbPingInterval;
-LoginDatabaseWorkerPool LoginDatabase;
+boost::asio::deadline_timer* _banExpiryCheckTimer;
+uint32 _banExpiryCheckInterval;
int main(int argc, char** argv)
{
+ signal(SIGABRT, &Trinity::AbortHandler);
+
std::string configFile = _TRINITY_REALM_CONFIG;
std::string configService;
auto vm = GetConsoleArguments(argc, argv, configFile, configService);
@@ -131,7 +135,7 @@ int main(int argc, char** argv)
// Get the list of realms for the server
sRealmList->Initialize(*_ioService, sConfigMgr->GetIntDefault("RealmsStateUpdateDelay", 20));
- if (sRealmList->size() == 0)
+ if (sRealmList->GetRealms().empty())
{
TC_LOG_ERROR("server.authserver", "No valid realms specified.");
StopDB();
@@ -169,6 +173,11 @@ int main(int argc, char** argv)
_dbPingTimer->expires_from_now(boost::posix_time::minutes(_dbPingInterval));
_dbPingTimer->async_wait(KeepDatabaseAliveHandler);
+ _banExpiryCheckInterval = sConfigMgr->GetIntDefault("BanExpiryCheckInterval", 60);
+ _banExpiryCheckTimer = new boost::asio::deadline_timer(*_ioService);
+ _banExpiryCheckTimer->expires_from_now(boost::posix_time::seconds(_banExpiryCheckInterval));
+ _banExpiryCheckTimer->async_wait(BanExpiryHandler);
+
#if PLATFORM == PLATFORM_WINDOWS
if (m_ServiceStatus != -1)
{
@@ -181,10 +190,13 @@ int main(int argc, char** argv)
// Start the io service worker loop
_ioService->run();
+ _banExpiryCheckTimer->cancel();
_dbPingTimer->cancel();
sAuthSocketMgr.StopNetwork();
+ sRealmList->Close();
+
// Close the Database Pool and library
StopDB();
@@ -192,6 +204,7 @@ int main(int argc, char** argv)
signals.cancel();
+ delete _banExpiryCheckTimer;
delete _dbPingTimer;
delete _ioService;
return 0;
@@ -242,6 +255,18 @@ void KeepDatabaseAliveHandler(const boost::system::error_code& error)
}
}
+void BanExpiryHandler(boost::system::error_code const& error)
+{
+ if (!error)
+ {
+ LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS));
+ LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_UPD_EXPIRED_ACCOUNT_BANS));
+
+ _banExpiryCheckTimer->expires_from_now(boost::posix_time::seconds(_banExpiryCheckInterval));
+ _banExpiryCheckTimer->async_wait(BanExpiryHandler);
+ }
+}
+
#if PLATFORM == PLATFORM_WINDOWS
void ServiceStatusWatcher(boost::system::error_code const& error)
{
diff --git a/src/server/authserver/Realms/RealmList.cpp b/src/server/authserver/Realms/RealmList.cpp
index 53aeff6133b..f1b25d8554d 100644
--- a/src/server/authserver/Realms/RealmList.cpp
+++ b/src/server/authserver/Realms/RealmList.cpp
@@ -16,69 +16,62 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <boost/asio/ip/tcp.hpp>
#include "Common.h"
-#include "RealmList.h"
#include "Database/DatabaseEnv.h"
+#include "RealmList.h"
+#include <boost/asio/ip/tcp.hpp>
namespace boost { namespace asio { namespace ip { class address; } } }
-RealmList::RealmList() : m_UpdateInterval(0), m_NextUpdateTime(time(NULL)), _resolver(nullptr) { }
+RealmList::RealmList() : _updateInterval(0), _updateTimer(nullptr), _resolver(nullptr) { }
RealmList::~RealmList()
{
delete _resolver;
+ delete _updateTimer;
}
// Load the realm list from the database
void RealmList::Initialize(boost::asio::io_service& ioService, uint32 updateInterval)
{
+ _updateInterval = updateInterval;
+ _updateTimer = new boost::asio::deadline_timer(ioService);
_resolver = new boost::asio::ip::tcp::resolver(ioService);
- m_UpdateInterval = updateInterval;
// Get the content of the realmlist table in the database
- UpdateRealms(true);
+ UpdateRealms(true, boost::system::error_code());
}
-void RealmList::UpdateRealm(uint32 id, const std::string& name, ip::address const& address, ip::address const& localAddr,
- ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population, uint32 build)
+void RealmList::Close()
{
- // Create new if not exist or update existed
- Realm& realm = m_realms[name];
-
- realm.m_ID = id;
- realm.name = name;
- realm.icon = icon;
- realm.flag = flag;
- realm.timezone = timezone;
- realm.allowedSecurityLevel = allowedSecurityLevel;
- realm.populationLevel = population;
-
- // Append port to IP address.
+ _updateTimer->cancel();
+}
+void RealmList::UpdateRealm(RealmHandle const& id, uint32 build, const std::string& name, ip::address const& address, ip::address const& localAddr,
+ ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel,
+ float population)
+{
+ // Create new if not exist or update existed
+ Realm& realm = _realms[id];
+
+ realm.Id = id;
+ realm.Build = build;
+ realm.Name = name;
+ realm.Type = icon;
+ realm.Flags = flag;
+ realm.Timezone = timezone;
+ realm.AllowedSecurityLevel = allowedSecurityLevel;
+ realm.PopulationLevel = population;
realm.ExternalAddress = address;
realm.LocalAddress = localAddr;
realm.LocalSubnetMask = localSubmask;
- realm.port = port;
- realm.gamebuild = build;
+ realm.Port = port;
}
-void RealmList::UpdateIfNeed()
+void RealmList::UpdateRealms(bool init, boost::system::error_code const& error)
{
- // maybe disabled or updated recently
- if (!m_UpdateInterval || m_NextUpdateTime > time(NULL))
+ if (error)
return;
- m_NextUpdateTime = time(NULL) + m_UpdateInterval;
-
- // Clears Realm list
- m_realms.clear();
-
- // Get the content of the realmlist table in the database
- UpdateRealms();
-}
-
-void RealmList::UpdateRealms(bool init)
-{
TC_LOG_INFO("server.authserver", "Updating Realm List...");
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST);
@@ -130,17 +123,23 @@ void RealmList::UpdateRealms(bool init)
uint16 port = fields[5].GetUInt16();
uint8 icon = fields[6].GetUInt8();
+ if (icon == REALM_TYPE_FFA_PVP)
+ icon = REALM_TYPE_PVP;
+ if (icon >= MAX_CLIENT_REALM_TYPE)
+ icon = REALM_TYPE_NORMAL;
RealmFlags flag = RealmFlags(fields[7].GetUInt8());
uint8 timezone = fields[8].GetUInt8();
uint8 allowedSecurityLevel = fields[9].GetUInt8();
float pop = fields[10].GetFloat();
uint32 build = fields[11].GetUInt32();
- UpdateRealm(realmId, name, externalAddress, localAddress, localSubmask, port, icon, flag, timezone,
- (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build);
+ RealmHandle id{ realmId };
+
+ UpdateRealm(id, build, name, externalAddress, localAddress, localSubmask, port, icon, flag,
+ timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop);
if (init)
- TC_LOG_INFO("server.authserver", "Added realm \"%s\" at %s:%u.", name.c_str(), m_realms[name].ExternalAddress.to_string().c_str(), port);
+ TC_LOG_INFO("server.authserver", "Added realm \"%s\" at %s:%u.", name.c_str(), externalAddress.to_string().c_str(), port);
}
catch (std::exception& ex)
{
@@ -150,4 +149,19 @@ void RealmList::UpdateRealms(bool init)
}
while (result->NextRow());
}
+
+ if (_updateInterval)
+ {
+ _updateTimer->expires_from_now(boost::posix_time::seconds(_updateInterval));
+ _updateTimer->async_wait(std::bind(&RealmList::UpdateRealms, this, false, std::placeholders::_1));
+ }
+}
+
+Realm const* RealmList::GetRealm(RealmHandle const& id) const
+{
+ auto itr = _realms.find(id);
+ if (itr != _realms.end())
+ return &itr->second;
+
+ return NULL;
}
diff --git a/src/server/authserver/Realms/RealmList.h b/src/server/authserver/Realms/RealmList.h
index cc5c88c01f2..e35975b215a 100644
--- a/src/server/authserver/Realms/RealmList.h
+++ b/src/server/authserver/Realms/RealmList.h
@@ -19,48 +19,20 @@
#ifndef _REALMLIST_H
#define _REALMLIST_H
+#include "Common.h"
+#include "Realm/Realm.h"
#include <boost/asio/ip/address.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/io_service.hpp>
-#include "Common.h"
+#include <boost/asio/deadline_timer.hpp>
using namespace boost::asio;
-enum RealmFlags
-{
- REALM_FLAG_NONE = 0x00,
- REALM_FLAG_INVALID = 0x01,
- REALM_FLAG_OFFLINE = 0x02,
- REALM_FLAG_SPECIFYBUILD = 0x04,
- REALM_FLAG_UNK1 = 0x08,
- REALM_FLAG_UNK2 = 0x10,
- REALM_FLAG_RECOMMENDED = 0x20,
- REALM_FLAG_NEW = 0x40,
- REALM_FLAG_FULL = 0x80
-};
-
-// Storage object for a realm
-struct Realm
-{
- ip::address ExternalAddress;
- ip::address LocalAddress;
- ip::address LocalSubnetMask;
- uint16 port;
- std::string name;
- uint8 icon;
- RealmFlags flag;
- uint8 timezone;
- uint32 m_ID;
- AccountTypes allowedSecurityLevel;
- float populationLevel;
- uint32 gamebuild;
-};
-
/// Storage object for the list of realms on the server
class RealmList
{
public:
- typedef std::map<std::string, Realm> RealmMap;
+ typedef std::map<RealmHandle, Realm> RealmMap;
static RealmList* instance()
{
@@ -71,25 +43,21 @@ public:
~RealmList();
void Initialize(boost::asio::io_service& ioService, uint32 updateInterval);
+ void Close();
- void UpdateIfNeed();
-
- void AddRealm(const Realm& NewRealm) { m_realms[NewRealm.name] = NewRealm; }
-
- 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(); }
+ RealmMap const& GetRealms() const { return _realms; }
+ Realm const* GetRealm(RealmHandle const& id) const;
private:
RealmList();
- void UpdateRealms(bool init = false);
- void UpdateRealm(uint32 id, const std::string& name, ip::address const& address, ip::address const& localAddr,
- ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population, uint32 build);
+ void UpdateRealms(bool init, boost::system::error_code const& error);
+ void UpdateRealm(RealmHandle const& id, uint32 build, const std::string& name, ip::address const& address, ip::address const& localAddr,
+ ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population);
- RealmMap m_realms;
- uint32 m_UpdateInterval;
- time_t m_NextUpdateTime;
+ RealmMap _realms;
+ uint32 _updateInterval;
+ boost::asio::deadline_timer* _updateTimer;
boost::asio::ip::tcp::resolver* _resolver;
};
diff --git a/src/server/authserver/Server/AuthSession.cpp b/src/server/authserver/Server/AuthSession.cpp
index acab29a5b86..982aca58eee 100644
--- a/src/server/authserver/Server/AuthSession.cpp
+++ b/src/server/authserver/Server/AuthSession.cpp
@@ -146,6 +146,11 @@ void AccountInfo::LoadResult(Field* fields)
IsBanned = fields[6].GetUInt64() != 0;
IsPermanenetlyBanned = fields[7].GetUInt64() != 0;
SecurityLevel = AccountTypes(fields[8].GetUInt8());
+
+ // Use our own uppercasing of the account name instead of using UPPER() in mysql query
+ // This is how the account was created in the first place and changing it now would result in breaking
+ // login for all accounts having accented characters in their name
+ Utf8ToUpperOnlyLatin(Login);
}
AuthSession::AuthSession(tcp::socket&& socket) : Socket(std::move(socket)),
@@ -161,10 +166,6 @@ void AuthSession::Start()
std::string ip_address = GetRemoteIpAddress().to_string();
TC_LOG_TRACE("session", "Accepted connection from %s", ip_address.c_str());
- // Remove expired ip ban if needed - login might fail for the first time
- // but its better than allowing ourselves to be flooded by connections triggering blocking queries
- LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS));
-
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_INFO);
stmt->setString(0, ip_address);
stmt->setUInt32(1, inet_addr(ip_address.c_str()));
@@ -278,10 +279,7 @@ void AuthSession::SendPacket(ByteBuffer& packet)
{
MessageBuffer buffer;
buffer.Write(packet.contents(), packet.size());
-
- std::unique_lock<std::mutex> guard(_writeLock);
-
- QueuePacket(std::move(buffer), guard);
+ QueuePacket(std::move(buffer));
}
}
@@ -382,9 +380,6 @@ void AuthSession::LogonChallengeCallback(PreparedQueryResult result)
}
}
- //set expired bans to inactive
- LoginDatabase.DirectExecute(LoginDatabase.GetPreparedStatement(LOGIN_UPD_EXPIRED_ACCOUNT_BANS));
-
// If the account is banned, reject the logon attempt
if (_accountInfo.IsBanned)
{
@@ -854,7 +849,7 @@ tcp::endpoint const GetAddressForClient(Realm const& realm, ip::address const& c
realmIp = realm.ExternalAddress;
}
- tcp::endpoint endpoint(realmIp, realm.port);
+ tcp::endpoint endpoint(realmIp, realm.Port);
// Return external IP
return endpoint;
@@ -890,22 +885,19 @@ void AuthSession::RealmListCallback(PreparedQueryResult result)
} while (result->NextRow());
}
- // Update realm list if need
- sRealmList->UpdateIfNeed();
-
// Circle through realms in the RealmList and construct the return packet (including # of user characters in each realm)
ByteBuffer pkt;
size_t RealmListSize = 0;
- for (RealmList::RealmMap::const_iterator i = sRealmList->begin(); i != sRealmList->end(); ++i)
+ for (RealmList::RealmMap::value_type const& i : sRealmList->GetRealms())
{
- const Realm &realm = i->second;
+ const Realm &realm = i.second;
// don't work with realms which not compatible with the client
- bool okBuild = ((_expversion & POST_BC_EXP_FLAG) && realm.gamebuild == _build) || ((_expversion & PRE_BC_EXP_FLAG) && !AuthHelper::IsPreBCAcceptedClientBuild(realm.gamebuild));
+ bool okBuild = ((_expversion & POST_BC_EXP_FLAG) && realm.Build == _build) || ((_expversion & PRE_BC_EXP_FLAG) && !AuthHelper::IsPreBCAcceptedClientBuild(realm.Build));
// No SQL injection. id of realm is controlled by the database.
- uint32 flag = realm.flag;
- RealmBuildInfo const* buildInfo = AuthHelper::GetBuildInfo(realm.gamebuild);
+ uint32 flag = realm.Flags;
+ RealmBuildInfo const* buildInfo = AuthHelper::GetBuildInfo(realm.Build);
if (!okBuild)
{
if (!buildInfo)
@@ -917,7 +909,7 @@ void AuthSession::RealmListCallback(PreparedQueryResult result)
if (!buildInfo)
flag &= ~REALM_FLAG_SPECIFYBUILD;
- std::string name = i->first;
+ std::string name = realm.Name;
if (_expversion & PRE_BC_EXP_FLAG && flag & REALM_FLAG_SPECIFYBUILD)
{
std::ostringstream ss;
@@ -925,19 +917,19 @@ void AuthSession::RealmListCallback(PreparedQueryResult result)
name = ss.str();
}
- uint8 lock = (realm.allowedSecurityLevel > _accountInfo.SecurityLevel) ? 1 : 0;
+ uint8 lock = (realm.AllowedSecurityLevel > _accountInfo.SecurityLevel) ? 1 : 0;
- pkt << uint8(realm.icon); // realm type
+ pkt << uint8(realm.Type); // realm type
if (_expversion & POST_BC_EXP_FLAG) // only 2.x and 3.x clients
pkt << uint8(lock); // if 1, then realm locked
pkt << uint8(flag); // RealmFlags
pkt << name;
pkt << boost::lexical_cast<std::string>(GetAddressForClient(realm, GetRemoteIpAddress()));
- pkt << float(realm.populationLevel);
- pkt << uint8(characterCounts[realm.m_ID]);
- pkt << uint8(realm.timezone); // realm category
+ pkt << float(realm.PopulationLevel);
+ pkt << uint8(characterCounts[realm.Id.Realm]);
+ pkt << uint8(realm.Timezone); // realm category
if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients
- pkt << uint8(realm.m_ID);
+ pkt << uint8(realm.Id.Realm);
else
pkt << uint8(0x0); // 1.12.1 and 1.12.2 clients
diff --git a/src/server/authserver/Server/AuthSocketMgr.h b/src/server/authserver/Server/AuthSocketMgr.h
index fa96502663f..a16b7d405b9 100644
--- a/src/server/authserver/Server/AuthSocketMgr.h
+++ b/src/server/authserver/Server/AuthSocketMgr.h
@@ -21,8 +21,6 @@
#include "SocketMgr.h"
#include "AuthSession.h"
-void OnSocketAccept(tcp::socket&& sock);
-
class AuthSocketMgr : public SocketMgr<AuthSession>
{
typedef SocketMgr<AuthSession> BaseSocketMgr;
@@ -39,7 +37,7 @@ public:
if (!BaseSocketMgr::StartNetwork(service, bindIp, port))
return false;
- _acceptor->AsyncAcceptManaged(&OnSocketAccept);
+ _acceptor->AsyncAcceptWithCallback<&AuthSocketMgr::OnSocketAccept>();
return true;
}
@@ -48,14 +46,13 @@ protected:
{
return new NetworkThread<AuthSession>[1];
}
+
+ static void OnSocketAccept(tcp::socket&& sock, uint32 threadIndex)
+ {
+ Instance().OnSocketOpen(std::forward<tcp::socket>(sock), threadIndex);
+ }
};
#define sAuthSocketMgr AuthSocketMgr::Instance()
-void OnSocketAccept(tcp::socket&& sock)
-{
- sAuthSocketMgr.OnSocketOpen(std::forward<tcp::socket>(sock));
-}
-
-
#endif // AuthSocketMgr_h__
diff --git a/src/server/authserver/authserver.conf.dist b/src/server/authserver/authserver.conf.dist
index 604988d62e5..a97d75b3f57 100644
--- a/src/server/authserver/authserver.conf.dist
+++ b/src/server/authserver/authserver.conf.dist
@@ -131,6 +131,33 @@ WrongPass.BanType = 0
WrongPass.Logging = 0
#
+# BanExpiryCheckInterval
+# Description: Time (in seconds) between checks for expired bans
+# Default: 60
+
+BanExpiryCheckInterval = 60
+
+#
+# SourceDirectory
+# Description: The path to your TrinityCore source directory.
+# If the path is left empty, the built-in CMAKE_SOURCE_DIR is used.
+# Example: "../TrinityCore"
+# Default: ""
+
+SourceDirectory = ""
+
+#
+# MySQLExecutable
+# Description: The path to your mysql cli binary.
+# If the path is left empty, built-in path from cmake is used.
+# Example: "C:/Program Files/MySQL/MySQL Server 5.6/bin/mysql.exe"
+# "mysql.exe"
+# "/usr/bin/mysql"
+# Default: ""
+
+MySQLExecutable = ""
+
+#
###################################################################################################
###################################################################################################
@@ -174,26 +201,6 @@ LoginDatabase.WorkerThreads = 1
Updates.EnableDatabases = 0
#
-# Updates.SourcePath
-# Description: The path to your TrinityCore source directory.
-# If the path is left empty, built-in CMAKE_SOURCE_DIR is used.
-# Example: "../TrinityCore"
-# Default: ""
-
-Updates.SourcePath = ""
-
-#
-# Updates.MySqlCLIPath
-# Description: The path to your mysql cli binary.
-# If the path is left empty, built-in path from cmake is used.
-# Example: "C:/Program Files/MySQL/MySQL Server 5.6/bin/mysql.exe"
-# "mysql.exe"
-# "/usr/bin/mysql"
-# Default: ""
-
-Updates.MySqlCLIPath = ""
-
-#
# Updates.AutoSetup
# Description: Auto populate empty databases.
# Default: 1 - (Enabled)
diff --git a/src/server/database/CMakeLists.txt b/src/server/database/CMakeLists.txt
index 5a53899f4cb..06772cd5309 100644
--- a/src/server/database/CMakeLists.txt
+++ b/src/server/database/CMakeLists.txt
@@ -8,34 +8,22 @@
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-if (NOT MYSQL_FOUND)
- message(SEND_ERROR "MySQL wasn't found on your system but it's required to build the servers!")
-endif()
-
-if( USE_COREPCH )
- include_directories(${CMAKE_CURRENT_BINARY_DIR})
-endif()
-
-file(GLOB_RECURSE sources_Database Database/*.cpp Database/*.h)
-file(GLOB_RECURSE sources_Logging Logging/*.cpp Logging/*.h)
-file(GLOB_RECURSE sources_Updater Updater/*.cpp Updater/*.h)
-
-file(GLOB sources_localdir *.cpp *.h)
-
-#
-# Build shared sourcelist
-#
+CollectSourceFiles(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ PRIVATE_SOURCES
+ # Exclude
+ ${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders)
if (USE_COREPCH)
- set(database_STAT_PCH_HDR PrecompiledHeaders/databasePCH.h)
- set(database_STAT_PCH_SRC PrecompiledHeaders/databasePCH.cpp)
+ set(PRIVATE_PCH_HEADER PrecompiledHeaders/databasePCH.h)
+ set(PRIVATE_PCH_SOURCE PrecompiledHeaders/databasePCH.cpp)
endif()
-set(database_STAT_SRCS
- ${database_STAT_SRCS}
- ${sources_Database}
- ${sources_Logging}
- ${sources_Updater}
+GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
+
+add_library(database
+ ${PRIVATE_SOURCES}
+ ${PRIVATE_PCH_SOURCE}
)
# Do NOT add any extra include directory unless it does not create unneeded extra dependencies,
@@ -47,31 +35,44 @@ set(database_STAT_SRCS
# linkage (enums, defines...) it is discouraged to do so unless necessary, as it will pullute
# include_directories leading to further unnoticed dependency aditions
# Linker Depencency requirements: common
-include_directories(
+CollectIncludeDirectories(
${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR}/Database
- ${CMAKE_CURRENT_SOURCE_DIR}/Updater
- ${CMAKE_SOURCE_DIR}/dep/cppformat
- ${CMAKE_SOURCE_DIR}/dep/process
- ${CMAKE_SOURCE_DIR}/src/common/
- ${CMAKE_SOURCE_DIR}/src/common/Configuration
- ${CMAKE_SOURCE_DIR}/src/common/Debugging
- ${CMAKE_SOURCE_DIR}/src/common/Logging
- ${CMAKE_SOURCE_DIR}/src/common/Threading
- ${CMAKE_SOURCE_DIR}/src/common/Utilities
- ${MYSQL_INCLUDE_DIR}
- ${OPENSSL_INCLUDE_DIR}
- ${VALGRIND_INCLUDE_DIR}
-)
+ PUBLIC_INCLUDES
+ # Exclude
+ ${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders)
-GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
+target_include_directories(database
+ PUBLIC
+ ${PUBLIC_INCLUDES}
+ PRIVATE
+ ${CMAKE_CURRENT_BINARY_DIR})
-add_library(database STATIC
- ${database_STAT_SRCS}
- ${database_STAT_PCH_SRC}
-)
+add_definitions(-DTRINITY_API_EXPORT_DATABASE)
+
+target_link_libraries(database
+ PUBLIC
+ common
+ process
+ mysql)
+
+set_target_properties(database
+ PROPERTIES
+ FOLDER
+ "server")
+
+if( BUILD_SHARED_LIBS )
+ if( UNIX )
+ install(TARGETS database
+ LIBRARY
+ DESTINATION lib)
+ elseif( WIN32 )
+ install(TARGETS database
+ RUNTIME
+ DESTINATION "${CMAKE_INSTALL_PREFIX}")
+ endif()
+endif()
# Generate precompiled header
if (USE_COREPCH)
- add_cxx_pch(database ${database_STAT_PCH_HDR} ${database_STAT_PCH_SRC})
+ add_cxx_pch(database ${PRIVATE_PCH_HEADER} ${PRIVATE_PCH_SOURCE})
endif ()
diff --git a/src/server/database/Database/AdhocStatement.h b/src/server/database/Database/AdhocStatement.h
index ab85493a14e..9315038bce1 100644
--- a/src/server/database/Database/AdhocStatement.h
+++ b/src/server/database/Database/AdhocStatement.h
@@ -25,7 +25,7 @@ typedef std::future<QueryResult> QueryResultFuture;
typedef std::promise<QueryResult> QueryResultPromise;
/*! Raw, ad-hoc query. */
-class BasicStatementTask : public SQLOperation
+class TC_DATABASE_API BasicStatementTask : public SQLOperation
{
public:
BasicStatementTask(const char* sql, bool async = false);
diff --git a/src/server/database/Database/DatabaseEnv.cpp b/src/server/database/Database/DatabaseEnv.cpp
new file mode 100644
index 00000000000..3b2e632e4fb
--- /dev/null
+++ b/src/server/database/Database/DatabaseEnv.cpp
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "DatabaseEnv.h"
+
+WorldDatabaseWorkerPool WorldDatabase;
+CharacterDatabaseWorkerPool CharacterDatabase;
+LoginDatabaseWorkerPool LoginDatabase;
diff --git a/src/server/database/Database/DatabaseEnv.h b/src/server/database/Database/DatabaseEnv.h
index cc8355a1302..05a4d5aad75 100644
--- a/src/server/database/Database/DatabaseEnv.h
+++ b/src/server/database/Database/DatabaseEnv.h
@@ -38,9 +38,11 @@
#include "Implementation/CharacterDatabase.h"
#include "Implementation/WorldDatabase.h"
-extern WorldDatabaseWorkerPool WorldDatabase;
-extern CharacterDatabaseWorkerPool CharacterDatabase;
-extern LoginDatabaseWorkerPool LoginDatabase;
+/// Accessor to the world database
+TC_DATABASE_API extern WorldDatabaseWorkerPool WorldDatabase;
+/// Accessor to the character database
+TC_DATABASE_API extern CharacterDatabaseWorkerPool CharacterDatabase;
+/// Accessor to the realm/login database
+TC_DATABASE_API extern LoginDatabaseWorkerPool LoginDatabase;
#endif
-
diff --git a/src/server/database/Database/DatabaseLoader.cpp b/src/server/database/Database/DatabaseLoader.cpp
index 92d8730cd12..f358bdd54b4 100644
--- a/src/server/database/Database/DatabaseLoader.cpp
+++ b/src/server/database/Database/DatabaseLoader.cpp
@@ -32,7 +32,7 @@ DatabaseLoader& DatabaseLoader::AddDatabase(DatabaseWorkerPool<T>& pool, std::st
{
bool const updatesEnabledForThis = DBUpdater<T>::IsEnabled(_updateFlags);
- _open.push(std::make_pair([this, name, updatesEnabledForThis, &pool]() -> bool
+ _open.push([this, name, updatesEnabledForThis, &pool]() -> bool
{
std::string const dbString = sConfigMgr->GetStringDefault(name + "DatabaseInfo", "");
if (dbString.empty())
@@ -71,12 +71,13 @@ DatabaseLoader& DatabaseLoader::AddDatabase(DatabaseWorkerPool<T>& pool, std::st
return false;
}
}
+ // Add the close operation
+ _close.push([&pool]
+ {
+ pool.Close();
+ });
return true;
- },
- [&pool]()
- {
- pool.Close();
- }));
+ });
// Populate and update only if updates are enabled for this pool
if (updatesEnabledForThis)
@@ -137,38 +138,7 @@ bool DatabaseLoader::Load()
bool DatabaseLoader::OpenDatabases()
{
- while (!_open.empty())
- {
- std::pair<Predicate, std::function<void()>> const load = _open.top();
- if (load.first())
- _close.push(load.second);
- else
- {
- // Close all loaded databases
- while (!_close.empty())
- {
- _close.top()();
- _close.pop();
- }
- return false;
- }
-
- _open.pop();
- }
- return true;
-}
-
-// Processes the elements of the given stack until a predicate returned false.
-bool DatabaseLoader::Process(std::stack<Predicate>& stack)
-{
- while (!stack.empty())
- {
- if (!stack.top()())
- return false;
-
- stack.pop();
- }
- return true;
+ return Process(_open);
}
bool DatabaseLoader::PopulateDatabases()
@@ -186,9 +156,30 @@ bool DatabaseLoader::PrepareStatements()
return Process(_prepare);
}
-template
-DatabaseLoader& DatabaseLoader::AddDatabase<LoginDatabaseConnection>(DatabaseWorkerPool<LoginDatabaseConnection>& pool, std::string const& name);
-template
-DatabaseLoader& DatabaseLoader::AddDatabase<WorldDatabaseConnection>(DatabaseWorkerPool<WorldDatabaseConnection>& pool, std::string const& name);
-template
-DatabaseLoader& DatabaseLoader::AddDatabase<CharacterDatabaseConnection>(DatabaseWorkerPool<CharacterDatabaseConnection>& pool, std::string const& name);
+bool DatabaseLoader::Process(std::queue<Predicate>& queue)
+{
+ while (!queue.empty())
+ {
+ if (!queue.front()())
+ {
+ // Close all open databases which have a registered close operation
+ while (!_close.empty())
+ {
+ _close.top()();
+ _close.pop();
+ }
+
+ return false;
+ }
+
+ queue.pop();
+ }
+ return true;
+}
+
+template TC_DATABASE_API
+DatabaseLoader& DatabaseLoader::AddDatabase<LoginDatabaseConnection>(LoginDatabaseWorkerPool&, std::string const&);
+template TC_DATABASE_API
+DatabaseLoader& DatabaseLoader::AddDatabase<CharacterDatabaseConnection>(CharacterDatabaseWorkerPool&, std::string const&);
+template TC_DATABASE_API
+DatabaseLoader& DatabaseLoader::AddDatabase<WorldDatabaseConnection>(WorldDatabaseWorkerPool&, std::string const&);
diff --git a/src/server/database/Database/DatabaseLoader.h b/src/server/database/Database/DatabaseLoader.h
index da92cf85a9f..647c1e113e3 100644
--- a/src/server/database/Database/DatabaseLoader.h
+++ b/src/server/database/Database/DatabaseLoader.h
@@ -19,14 +19,15 @@
#define DatabaseLoader_h__
#include "DatabaseWorkerPool.h"
-#include "DatabaseEnv.h"
+#include "DBUpdater.h"
-#include <stack>
#include <functional>
+#include <stack>
+#include <queue>
// A helper class to initiate all database worker pools,
// handles updating, delays preparing of statements and cleans up on failure.
-class DatabaseLoader
+class TC_DATABASE_API DatabaseLoader
{
public:
DatabaseLoader(std::string const& logger, uint32 const defaultUpdateMask);
@@ -56,16 +57,18 @@ private:
bool PrepareStatements();
using Predicate = std::function<bool()>;
+ using Closer = std::function<void()>;
- static bool Process(std::stack<Predicate>& stack);
+ // Invokes all functions in the given queue and closes the databases on errors.
+ // Returns false when there was an error.
+ bool Process(std::queue<Predicate>& queue);
std::string const _logger;
bool const _autoSetup;
uint32 const _updateFlags;
- std::stack<std::pair<Predicate, std::function<void()>>> _open;
- std::stack<std::function<void()>> _close;
- std::stack<Predicate> _populate, _update, _prepare;
+ std::queue<Predicate> _open, _populate, _update, _prepare;
+ std::stack<Closer> _close;
};
#endif // DatabaseLoader_h__
diff --git a/src/server/database/Database/DatabaseWorker.h b/src/server/database/Database/DatabaseWorker.h
index c21a3d2a343..d6b43943f7d 100644
--- a/src/server/database/Database/DatabaseWorker.h
+++ b/src/server/database/Database/DatabaseWorker.h
@@ -24,7 +24,7 @@
class MySQLConnection;
class SQLOperation;
-class DatabaseWorker
+class TC_DATABASE_API DatabaseWorker
{
public:
DatabaseWorker(ProducerConsumerQueue<SQLOperation*>* newQueue, MySQLConnection* connection);
diff --git a/src/server/database/Database/DatabaseWorkerPool.cpp b/src/server/database/Database/DatabaseWorkerPool.cpp
new file mode 100644
index 00000000000..087a35682aa
--- /dev/null
+++ b/src/server/database/Database/DatabaseWorkerPool.cpp
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "DatabaseWorkerPool.h"
+#include "DatabaseEnv.h"
+
+#define MIN_MYSQL_SERVER_VERSION 50100u
+#define MIN_MYSQL_CLIENT_VERSION 50100u
+
+template <class T>
+DatabaseWorkerPool<T>::DatabaseWorkerPool()
+ : _queue(new ProducerConsumerQueue<SQLOperation*>()),
+ _async_threads(0), _synch_threads(0)
+{
+ WPFatal(mysql_thread_safe(), "Used MySQL library isn't thread-safe.");
+ WPFatal(mysql_get_client_version() >= MIN_MYSQL_CLIENT_VERSION, "TrinityCore does not support MySQL versions below 5.1");
+ WPFatal(mysql_get_client_version() == MYSQL_VERSION_ID, "Used MySQL library version (%s) does not match the version used to compile TrinityCore (%s).",
+ mysql_get_client_info(), MYSQL_SERVER_VERSION);
+}
+
+template <class T>
+void DatabaseWorkerPool<T>::SetConnectionInfo(std::string const& infoString,
+ uint8 const asyncThreads, uint8 const synchThreads)
+{
+ _connectionInfo = Trinity::make_unique<MySQLConnectionInfo>(infoString);
+
+ _async_threads = asyncThreads;
+ _synch_threads = synchThreads;
+}
+
+template <class T>
+uint32 DatabaseWorkerPool<T>::Open()
+{
+ WPFatal(_connectionInfo.get(), "Connection info was not set!");
+
+ TC_LOG_INFO("sql.driver", "Opening DatabasePool '%s'. "
+ "Asynchronous connections: %u, synchronous connections: %u.",
+ GetDatabaseName(), _async_threads, _synch_threads);
+
+ uint32 error = OpenConnections(IDX_ASYNC, _async_threads);
+
+ if (error)
+ return error;
+
+ error = OpenConnections(IDX_SYNCH, _synch_threads);
+
+ if (!error)
+ {
+ TC_LOG_INFO("sql.driver", "DatabasePool '%s' opened successfully. " SZFMTD
+ " total connections running.", GetDatabaseName(),
+ (_connections[IDX_SYNCH].size() + _connections[IDX_ASYNC].size()));
+ }
+
+ return error;
+}
+
+template <class T>
+void DatabaseWorkerPool<T>::Close()
+{
+ TC_LOG_INFO("sql.driver", "Closing down DatabasePool '%s'.", GetDatabaseName());
+
+ //! Closes the actualy MySQL connection.
+ _connections[IDX_ASYNC].clear();
+
+ TC_LOG_INFO("sql.driver", "Asynchronous connections on DatabasePool '%s' terminated. "
+ "Proceeding with synchronous connections.",
+ GetDatabaseName());
+
+ //! Shut down the synchronous connections
+ //! There's no need for locking the connection, because DatabaseWorkerPool<>::Close
+ //! should only be called after any other thread tasks in the core have exited,
+ //! meaning there can be no concurrent access at this point.
+ _connections[IDX_SYNCH].clear();
+
+ TC_LOG_INFO("sql.driver", "All connections on DatabasePool '%s' closed.", GetDatabaseName());
+}
+
+template <class T>
+bool DatabaseWorkerPool<T>::PrepareStatements()
+{
+ for (auto& connections : _connections)
+ for (auto& connection : connections)
+ {
+ connection->LockIfReady();
+ if (!connection->PrepareStatements())
+ {
+ connection->Unlock();
+ Close();
+ return false;
+ }
+ else
+ connection->Unlock();
+ }
+
+ return true;
+}
+
+template <class T>
+QueryResult DatabaseWorkerPool<T>::Query(const char* sql, T* connection /*= nullptr*/)
+{
+ if (!connection)
+ connection = GetFreeConnection();
+
+ ResultSet* result = connection->Query(sql);
+ connection->Unlock();
+ if (!result || !result->GetRowCount() || !result->NextRow())
+ {
+ delete result;
+ return QueryResult(NULL);
+ }
+
+ return QueryResult(result);
+}
+
+template <class T>
+PreparedQueryResult DatabaseWorkerPool<T>::Query(PreparedStatement* stmt)
+{
+ auto connection = GetFreeConnection();
+ PreparedResultSet* ret = connection->Query(stmt);
+ connection->Unlock();
+
+ //! Delete proxy-class. Not needed anymore
+ delete stmt;
+
+ if (!ret || !ret->GetRowCount())
+ {
+ delete ret;
+ return PreparedQueryResult(NULL);
+ }
+
+ return PreparedQueryResult(ret);
+}
+
+template <class T>
+QueryResultFuture DatabaseWorkerPool<T>::AsyncQuery(const char* sql)
+{
+ BasicStatementTask* task = new BasicStatementTask(sql, true);
+ // Store future result before enqueueing - task might get already processed and deleted before returning from this method
+ QueryResultFuture result = task->GetFuture();
+ Enqueue(task);
+ return result;
+}
+
+template <class T>
+PreparedQueryResultFuture DatabaseWorkerPool<T>::AsyncQuery(PreparedStatement* stmt)
+{
+ PreparedStatementTask* task = new PreparedStatementTask(stmt, true);
+ // Store future result before enqueueing - task might get already processed and deleted before returning from this method
+ PreparedQueryResultFuture result = task->GetFuture();
+ Enqueue(task);
+ return result;
+}
+
+template <class T>
+QueryResultHolderFuture DatabaseWorkerPool<T>::DelayQueryHolder(SQLQueryHolder* holder)
+{
+ SQLQueryHolderTask* task = new SQLQueryHolderTask(holder);
+ // Store future result before enqueueing - task might get already processed and deleted before returning from this method
+ QueryResultHolderFuture result = task->GetFuture();
+ Enqueue(task);
+ return result;
+}
+
+template <class T>
+void DatabaseWorkerPool<T>::CommitTransaction(SQLTransaction transaction)
+{
+#ifdef TRINITY_DEBUG
+ //! Only analyze transaction weaknesses in Debug mode.
+ //! Ideally we catch the faults in Debug mode and then correct them,
+ //! so there's no need to waste these CPU cycles in Release mode.
+ switch (transaction->GetSize())
+ {
+ case 0:
+ TC_LOG_DEBUG("sql.driver", "Transaction contains 0 queries. Not executing.");
+ return;
+ case 1:
+ TC_LOG_DEBUG("sql.driver", "Warning: Transaction only holds 1 query, consider removing Transaction context in code.");
+ break;
+ default:
+ break;
+ }
+#endif // TRINITY_DEBUG
+
+ Enqueue(new TransactionTask(transaction));
+}
+
+template <class T>
+void DatabaseWorkerPool<T>::DirectCommitTransaction(SQLTransaction& transaction)
+{
+ T* connection = GetFreeConnection();
+ int errorCode = connection->ExecuteTransaction(transaction);
+ if (!errorCode)
+ {
+ connection->Unlock(); // OK, operation succesful
+ return;
+ }
+
+ //! Handle MySQL Errno 1213 without extending deadlock to the core itself
+ /// @todo More elegant way
+ if (errorCode == ER_LOCK_DEADLOCK)
+ {
+ uint8 loopBreaker = 5;
+ for (uint8 i = 0; i < loopBreaker; ++i)
+ {
+ if (!connection->ExecuteTransaction(transaction))
+ break;
+ }
+ }
+
+ //! Clean up now.
+ transaction->Cleanup();
+
+ connection->Unlock();
+}
+
+template <class T>
+void DatabaseWorkerPool<T>::EscapeString(std::string& str)
+{
+ if (str.empty())
+ return;
+
+ char* buf = new char[str.size() * 2 + 1];
+ EscapeString(buf, str.c_str(), str.size());
+ str = buf;
+ delete[] buf;
+}
+
+template <class T>
+void DatabaseWorkerPool<T>::KeepAlive()
+{
+ //! Ping synchronous connections
+ for (auto& connection : _connections[IDX_SYNCH])
+ {
+ if (connection->LockIfReady())
+ {
+ connection->Ping();
+ connection->Unlock();
+ }
+ }
+
+ //! Assuming all worker threads are free, every worker thread will receive 1 ping operation request
+ //! If one or more worker threads are busy, the ping operations will not be split evenly, but this doesn't matter
+ //! as the sole purpose is to prevent connections from idling.
+ auto const count = _connections[IDX_ASYNC].size();
+ for (uint8 i = 0; i < count; ++i)
+ Enqueue(new PingOperation);
+}
+
+template <class T>
+uint32 DatabaseWorkerPool<T>::OpenConnections(InternalIndex type, uint8 numConnections)
+{
+ for (uint8 i = 0; i < numConnections; ++i)
+ {
+ // Create the connection
+ auto connection = [&] {
+ switch (type)
+ {
+ case IDX_ASYNC:
+ return Trinity::make_unique<T>(_queue.get(), *_connectionInfo);
+ case IDX_SYNCH:
+ return Trinity::make_unique<T>(*_connectionInfo);
+ default:
+ ABORT();
+ }
+ }();
+
+ if (uint32 error = connection->Open())
+ {
+ // Failed to open a connection or invalid version, abort and cleanup
+ _connections[type].clear();
+ return error;
+ }
+ else if (mysql_get_server_version(connection->GetHandle()) < MIN_MYSQL_SERVER_VERSION)
+ {
+ TC_LOG_ERROR("sql.driver", "TrinityCore does not support MySQL versions below 5.1");
+ return 1;
+ }
+ else
+ {
+ _connections[type].push_back(std::move(connection));
+ }
+ }
+
+ // Everything is fine
+ return 0;
+}
+
+template <class T>
+T* DatabaseWorkerPool<T>::GetFreeConnection()
+{
+ uint8 i = 0;
+ auto const num_cons = _connections[IDX_SYNCH].size();
+ T* connection = nullptr;
+ //! Block forever until a connection is free
+ for (;;)
+ {
+ connection = _connections[IDX_SYNCH][++i % num_cons].get();
+ //! Must be matched with t->Unlock() or you will get deadlocks
+ if (connection->LockIfReady())
+ break;
+ }
+
+ return connection;
+}
+
+template class TC_DATABASE_API DatabaseWorkerPool<LoginDatabaseConnection>;
+template class TC_DATABASE_API DatabaseWorkerPool<WorldDatabaseConnection>;
+template class TC_DATABASE_API DatabaseWorkerPool<CharacterDatabaseConnection>;
diff --git a/src/server/database/Database/DatabaseWorkerPool.h b/src/server/database/Database/DatabaseWorkerPool.h
index d5a254647eb..d883366237f 100644
--- a/src/server/database/Database/DatabaseWorkerPool.h
+++ b/src/server/database/Database/DatabaseWorkerPool.h
@@ -32,9 +32,7 @@
#include <mysqld_error.h>
#include <memory>
-
-#define MIN_MYSQL_SERVER_VERSION 50100u
-#define MIN_MYSQL_CLIENT_VERSION 50100u
+#include <array>
class PingOperation : public SQLOperation
{
@@ -59,97 +57,21 @@ class DatabaseWorkerPool
public:
/* Activity state */
- DatabaseWorkerPool() : _queue(new ProducerConsumerQueue<SQLOperation*>()),
- _async_threads(0), _synch_threads(0)
- {
- memset(_connectionCount, 0, sizeof(_connectionCount));
- _connections.resize(IDX_SIZE);
-
- WPFatal(mysql_thread_safe(), "Used MySQL library isn't thread-safe.");
- WPFatal(mysql_get_client_version() >= MIN_MYSQL_CLIENT_VERSION, "TrinityCore does not support MySQL versions below 5.1");
- WPFatal(mysql_get_client_version() == MYSQL_VERSION_ID, "Used MySQL library version (%s) does not match the version used to compile TrinityCore (%s).",
- mysql_get_client_info(), MYSQL_SERVER_VERSION);
- }
+ DatabaseWorkerPool();
~DatabaseWorkerPool()
{
_queue->Cancel();
}
- void SetConnectionInfo(std::string const& infoString, uint8 const asyncThreads, uint8 const synchThreads)
- {
- _connectionInfo.reset(new MySQLConnectionInfo(infoString));
-
- _async_threads = asyncThreads;
- _synch_threads = synchThreads;
- }
-
- uint32 Open()
- {
- WPFatal(_connectionInfo.get(), "Connection info was not set!");
-
- TC_LOG_INFO("sql.driver", "Opening DatabasePool '%s'. Asynchronous connections: %u, synchronous connections: %u.",
- GetDatabaseName(), _async_threads, _synch_threads);
-
- uint32 error = OpenConnections(IDX_ASYNC, _async_threads);
-
- if (error)
- return error;
-
- error = OpenConnections(IDX_SYNCH, _synch_threads);
-
- if (!error)
- {
- TC_LOG_INFO("sql.driver", "DatabasePool '%s' opened successfully. %u total connections running.", GetDatabaseName(),
- (_connectionCount[IDX_SYNCH] + _connectionCount[IDX_ASYNC]));
- }
-
- return error;
- }
-
- void Close()
- {
- TC_LOG_INFO("sql.driver", "Closing down DatabasePool '%s'.", GetDatabaseName());
+ void SetConnectionInfo(std::string const& infoString, uint8 const asyncThreads, uint8 const synchThreads);
- for (uint8 i = 0; i < _connectionCount[IDX_ASYNC]; ++i)
- {
- T* t = _connections[IDX_ASYNC][i];
- t->Close(); //! Closes the actualy MySQL connection.
- }
+ uint32 Open();
- TC_LOG_INFO("sql.driver", "Asynchronous connections on DatabasePool '%s' terminated. Proceeding with synchronous connections.",
- GetDatabaseName());
-
- //! Shut down the synchronous connections
- //! There's no need for locking the connection, because DatabaseWorkerPool<>::Close
- //! should only be called after any other thread tasks in the core have exited,
- //! meaning there can be no concurrent access at this point.
- for (uint8 i = 0; i < _connectionCount[IDX_SYNCH]; ++i)
- _connections[IDX_SYNCH][i]->Close();
-
- TC_LOG_INFO("sql.driver", "All connections on DatabasePool '%s' closed.", GetDatabaseName());
- }
+ void Close();
//! Prepares all prepared statements
- bool PrepareStatements()
- {
- for (uint8 i = 0; i < IDX_SIZE; ++i)
- for (uint32 c = 0; c < _connectionCount[i]; ++c)
- {
- T* t = _connections[i][c];
- t->LockIfReady();
- if (!t->PrepareStatements())
- {
- t->Unlock();
- Close();
- return false;
- }
- else
- t->Unlock();
- }
-
- return true;
- }
+ bool PrepareStatements();
inline MySQLConnectionInfo const* GetConnectionInfo() const
{
@@ -201,9 +123,9 @@ class DatabaseWorkerPool
if (!sql)
return;
- T* t = GetFreeConnection();
- t->Execute(sql);
- t->Unlock();
+ T* connection = GetFreeConnection();
+ connection->Execute(sql);
+ connection->Unlock();
}
//! Directly executes a one-way SQL operation in string format -with variable args-, that will block the calling thread until finished.
@@ -221,9 +143,9 @@ class DatabaseWorkerPool
//! Statement must be prepared with the CONNECTION_SYNCH flag.
void DirectExecute(PreparedStatement* stmt)
{
- T* t = GetFreeConnection();
- t->Execute(stmt);
- t->Unlock();
+ T* connection = GetFreeConnection();
+ connection->Execute(stmt);
+ connection->Unlock();
//! Delete proxy-class. Not needed anymore
delete stmt;
@@ -235,21 +157,7 @@ class DatabaseWorkerPool
//! Directly executes an SQL query in string format that will block the calling thread until finished.
//! Returns reference counted auto pointer, no need for manual memory management in upper level code.
- QueryResult Query(const char* sql, T* conn = nullptr)
- {
- if (!conn)
- conn = GetFreeConnection();
-
- ResultSet* result = conn->Query(sql);
- conn->Unlock();
- if (!result || !result->GetRowCount() || !result->NextRow())
- {
- delete result;
- return QueryResult(NULL);
- }
-
- return QueryResult(result);
- }
+ QueryResult Query(const char* sql, T* connection = nullptr);
//! Directly executes an SQL query in string format -with variable args- that will block the calling thread until finished.
//! Returns reference counted auto pointer, no need for manual memory management in upper level code.
@@ -276,23 +184,7 @@ class DatabaseWorkerPool
//! Directly executes an SQL query in prepared format that will block the calling thread until finished.
//! Returns reference counted auto pointer, no need for manual memory management in upper level code.
//! Statement must be prepared with CONNECTION_SYNCH flag.
- PreparedQueryResult Query(PreparedStatement* stmt)
- {
- T* t = GetFreeConnection();
- PreparedResultSet* ret = t->Query(stmt);
- t->Unlock();
-
- //! Delete proxy-class. Not needed anymore
- delete stmt;
-
- if (!ret || !ret->GetRowCount())
- {
- delete ret;
- return PreparedQueryResult(NULL);
- }
-
- return PreparedQueryResult(ret);
- }
+ PreparedQueryResult Query(PreparedStatement* stmt);
/**
Asynchronous query (with resultset) methods.
@@ -300,14 +192,7 @@ class DatabaseWorkerPool
//! Enqueues a query in string format that will set the value of the QueryResultFuture return object as soon as the query is executed.
//! The return value is then processed in ProcessQueryCallback methods.
- QueryResultFuture AsyncQuery(const char* sql)
- {
- BasicStatementTask* task = new BasicStatementTask(sql, true);
- // Store future result before enqueueing - task might get already processed and deleted before returning from this method
- QueryResultFuture result = task->GetFuture();
- Enqueue(task);
- return result;
- }
+ QueryResultFuture AsyncQuery(const char* sql);
//! Enqueues a query in string format -with variable args- that will set the value of the QueryResultFuture return object as soon as the query is executed.
//! The return value is then processed in ProcessQueryCallback methods.
@@ -320,27 +205,13 @@ class DatabaseWorkerPool
//! Enqueues a query in prepared format that will set the value of the PreparedQueryResultFuture return object as soon as the query is executed.
//! The return value is then processed in ProcessQueryCallback methods.
//! Statement must be prepared with CONNECTION_ASYNC flag.
- PreparedQueryResultFuture AsyncQuery(PreparedStatement* stmt)
- {
- PreparedStatementTask* task = new PreparedStatementTask(stmt, true);
- // Store future result before enqueueing - task might get already processed and deleted before returning from this method
- PreparedQueryResultFuture result = task->GetFuture();
- Enqueue(task);
- return result;
- }
+ PreparedQueryResultFuture AsyncQuery(PreparedStatement* stmt);
//! Enqueues a vector of SQL operations (can be both adhoc and prepared) that will set the value of the QueryResultHolderFuture
//! return object as soon as the query is executed.
//! The return value is then processed in ProcessQueryCallback methods.
//! Any prepared statements added to this holder need to be prepared with the CONNECTION_ASYNC flag.
- QueryResultHolderFuture DelayQueryHolder(SQLQueryHolder* holder)
- {
- SQLQueryHolderTask* task = new SQLQueryHolderTask(holder);
- // Store future result before enqueueing - task might get already processed and deleted before returning from this method
- QueryResultHolderFuture result = task->GetFuture();
- Enqueue(task);
- return result;
- }
+ QueryResultHolderFuture DelayQueryHolder(SQLQueryHolder* holder);
/**
Transaction context methods.
@@ -354,57 +225,11 @@ class DatabaseWorkerPool
//! Enqueues a collection of one-way SQL operations (can be both adhoc and prepared). The order in which these operations
//! were appended to the transaction will be respected during execution.
- void CommitTransaction(SQLTransaction transaction)
- {
- #ifdef TRINITY_DEBUG
- //! Only analyze transaction weaknesses in Debug mode.
- //! Ideally we catch the faults in Debug mode and then correct them,
- //! so there's no need to waste these CPU cycles in Release mode.
- switch (transaction->GetSize())
- {
- case 0:
- TC_LOG_DEBUG("sql.driver", "Transaction contains 0 queries. Not executing.");
- return;
- case 1:
- TC_LOG_DEBUG("sql.driver", "Warning: Transaction only holds 1 query, consider removing Transaction context in code.");
- break;
- default:
- break;
- }
- #endif // TRINITY_DEBUG
-
- Enqueue(new TransactionTask(transaction));
- }
+ void CommitTransaction(SQLTransaction transaction);
//! Directly executes a collection of one-way SQL operations (can be both adhoc and prepared). The order in which these operations
//! were appended to the transaction will be respected during execution.
- void DirectCommitTransaction(SQLTransaction& transaction)
- {
- T* con = GetFreeConnection();
- int errorCode = con->ExecuteTransaction(transaction);
- if (!errorCode)
- {
- con->Unlock(); // OK, operation succesful
- return;
- }
-
- //! Handle MySQL Errno 1213 without extending deadlock to the core itself
- /// @todo More elegant way
- if (errorCode == ER_LOCK_DEADLOCK)
- {
- uint8 loopBreaker = 5;
- for (uint8 i = 0; i < loopBreaker; ++i)
- {
- if (!con->ExecuteTransaction(transaction))
- break;
- }
- }
-
- //! Clean up now.
- transaction->Cleanup();
-
- con->Unlock();
- }
+ void DirectCommitTransaction(SQLTransaction& transaction);
//! Method used to execute prepared statements in a diverse context.
//! Will be wrapped in a transaction if valid object is present, otherwise executed standalone.
@@ -441,90 +266,21 @@ class DatabaseWorkerPool
}
//! Apply escape string'ing for current collation. (utf8)
- void EscapeString(std::string& str)
- {
- if (str.empty())
- return;
-
- char* buf = new char[str.size() * 2 + 1];
- EscapeString(buf, str.c_str(), str.size());
- str = buf;
- delete[] buf;
- }
+ void EscapeString(std::string& str);
//! Keeps all our MySQL connections alive, prevent the server from disconnecting us.
- void KeepAlive()
- {
- //! Ping synchronous connections
- for (uint8 i = 0; i < _connectionCount[IDX_SYNCH]; ++i)
- {
- T* t = _connections[IDX_SYNCH][i];
- if (t->LockIfReady())
- {
- t->Ping();
- t->Unlock();
- }
- }
-
- //! Assuming all worker threads are free, every worker thread will receive 1 ping operation request
- //! If one or more worker threads are busy, the ping operations will not be split evenly, but this doesn't matter
- //! as the sole purpose is to prevent connections from idling.
- for (size_t i = 0; i < _connections[IDX_ASYNC].size(); ++i)
- Enqueue(new PingOperation);
- }
+ void KeepAlive();
private:
- uint32 OpenConnections(InternalIndex type, uint8 numConnections)
- {
- _connections[type].resize(numConnections);
- for (uint8 i = 0; i < numConnections; ++i)
- {
- T* t;
-
- if (type == IDX_ASYNC)
- t = new T(_queue.get(), *_connectionInfo);
- else if (type == IDX_SYNCH)
- t = new T(*_connectionInfo);
- else
- ABORT();
-
- _connections[type][i] = t;
- ++_connectionCount[type];
-
- uint32 error = t->Open();
-
- if (!error)
- {
- if (mysql_get_server_version(t->GetHandle()) < MIN_MYSQL_SERVER_VERSION)
- {
- TC_LOG_ERROR("sql.driver", "TrinityCore does not support MySQL versions below 5.1");
- error = 1;
- }
- }
-
- // Failed to open a connection or invalid version, abort and cleanup
- if (error)
- {
- while (_connectionCount[type] != 0)
- {
- t = _connections[type][i--];
- delete t;
- --_connectionCount[type];
- }
- return error;
- }
- }
-
- // Everything is fine
- return 0;
- }
+ uint32 OpenConnections(InternalIndex type, uint8 numConnections);
unsigned long EscapeString(char *to, const char *from, unsigned long length)
{
if (!to || !from || !length)
return 0;
- return mysql_real_escape_string(_connections[IDX_SYNCH][0]->GetHandle(), to, from, length);
+ return mysql_real_escape_string(
+ _connections[IDX_SYNCH].front()->GetHandle(), to, from, length);
}
void Enqueue(SQLOperation* op)
@@ -534,22 +290,7 @@ class DatabaseWorkerPool
//! Gets a free connection in the synchronous connection pool.
//! Caller MUST call t->Unlock() after touching the MySQL context to prevent deadlocks.
- T* GetFreeConnection()
- {
- uint8 i = 0;
- size_t num_cons = _connectionCount[IDX_SYNCH];
- T* t = NULL;
- //! Block forever until a connection is free
- for (;;)
- {
- t = _connections[IDX_SYNCH][++i % num_cons];
- //! Must be matched with t->Unlock() or you will get deadlocks
- if (t->LockIfReady())
- break;
- }
-
- return t;
- }
+ T* GetFreeConnection();
char const* GetDatabaseName() const
{
@@ -558,9 +299,7 @@ class DatabaseWorkerPool
//! Queue shared by async worker threads.
std::unique_ptr<ProducerConsumerQueue<SQLOperation*>> _queue;
- std::vector<std::vector<T*>> _connections;
- //! Counter of MySQL connections;
- uint32 _connectionCount[IDX_SIZE];
+ std::array<std::vector<std::unique_ptr<T>>, IDX_SIZE> _connections;
std::unique_ptr<MySQLConnectionInfo> _connectionInfo;
uint8 _async_threads, _synch_threads;
};
diff --git a/src/server/database/Database/Field.h b/src/server/database/Database/Field.h
index ec9e626ee1b..fd4ddc79450 100644
--- a/src/server/database/Database/Field.h
+++ b/src/server/database/Database/Field.h
@@ -53,7 +53,7 @@
| SUM, AVG | DECIMAL |
| COUNT | BIGINT |
*/
-class Field
+class TC_DATABASE_API Field
{
friend class ResultSet;
friend class PreparedResultSet;
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp
index ab68aca2a8c..ce01b0eb245 100644
--- a/src/server/database/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp
@@ -42,11 +42,11 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_SEL_MAIL_LIST_INFO, "SELECT id, sender, (SELECT name FROM characters WHERE guid = sender) AS sendername, receiver, (SELECT name FROM characters WHERE guid = receiver) AS receivername, "
"subject, deliver_time, expire_time, money, has_items FROM mail WHERE receiver = ? ", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_MAIL_LIST_ITEMS, "SELECT itemEntry,count FROM item_instance WHERE guid = ?", CONNECTION_SYNCH);
- PrepareStatement(CHAR_SEL_ENUM, "SELECT c.guid, c.name, c.race, c.class, c.gender, c.playerBytes, c.playerBytes2, c.level, c.zone, c.map, c.position_x, c.position_y, c.position_z, "
+ PrepareStatement(CHAR_SEL_ENUM, "SELECT c.guid, c.name, c.race, c.class, c.gender, c.skin, c.face, c.hairStyle, c.hairColor, c.facialStyle, c.level, c.zone, c.map, c.position_x, c.position_y, c.position_z, "
"gm.guildid, c.playerFlags, c.at_login, cp.entry, cp.modelid, cp.level, c.equipmentCache, cb.guid "
"FROM characters AS c LEFT JOIN character_pet AS cp ON c.guid = cp.owner AND cp.slot = ? LEFT JOIN guild_member AS gm ON c.guid = gm.guid "
"LEFT JOIN character_banned AS cb ON c.guid = cb.guid AND cb.active = 1 WHERE c.account = ? AND c.deleteInfos_Name IS NULL ORDER BY c.guid", CONNECTION_ASYNC);
- PrepareStatement(CHAR_SEL_ENUM_DECLINED_NAME, "SELECT c.guid, c.name, c.race, c.class, c.gender, c.playerBytes, c.playerBytes2, c.level, c.zone, c.map, "
+ PrepareStatement(CHAR_SEL_ENUM_DECLINED_NAME, "SELECT c.guid, c.name, c.race, c.class, c.gender, c.skin, c.face, c.hairStyle, c.hairColor, c.facialStyle, c.level, c.zone, c.map, "
"c.position_x, c.position_y, c.position_z, gm.guildid, c.playerFlags, c.at_login, cp.entry, cp.modelid, cp.level, c.equipmentCache, "
"cb.guid, cd.genitive FROM characters AS c LEFT JOIN character_pet AS cp ON c.guid = cp.owner AND cp.slot = ? "
"LEFT JOIN character_declinedname AS cd ON c.guid = cd.guid LEFT JOIN guild_member AS gm ON c.guid = gm.guid "
@@ -64,7 +64,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_BATTLEGROUND_RANDOM, "DELETE FROM character_battleground_random WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_BATTLEGROUND_RANDOM, "INSERT INTO character_battleground_random (guid) VALUES (?)", CONNECTION_ASYNC);
- PrepareStatement(CHAR_SEL_CHARACTER, "SELECT guid, account, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags, "
+ PrepareStatement(CHAR_SEL_CHARACTER, "SELECT guid, account, name, race, class, gender, level, xp, money, skin, face, hairStyle, hairColor, facialStyle, bankSlots, restState, playerFlags, "
"position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, "
"resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, instance_mode_mask, "
"arenaPoints, totalHonorPoints, todayHonorPoints, yesterdayHonorPoints, totalKills, todayKills, yesterdayKills, chosenTitle, knownCurrencies, watchedFaction, drunk, "
@@ -351,7 +351,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_LFG_DATA, "DELETE FROM lfg_data WHERE guid = ?", CONNECTION_ASYNC);
// Player saving
- PrepareStatement(CHAR_INS_CHARACTER, "INSERT INTO characters (guid, account, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags, "
+ PrepareStatement(CHAR_INS_CHARACTER, "INSERT INTO characters (guid, account, name, race, class, gender, level, xp, money, skin, face, hairStyle, hairColor, facialStyle, bankSlots, restState, playerFlags, "
"map, instance_id, instance_mode_mask, position_x, position_y, position_z, orientation, trans_x, trans_y, trans_z, trans_o, transguid, "
"taximask, cinematic, "
"totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, "
@@ -359,8 +359,8 @@ void CharacterDatabaseConnection::DoPrepareStatements()
"death_expire_time, taxi_path, arenaPoints, totalHonorPoints, todayHonorPoints, yesterdayHonorPoints, totalKills, "
"todayKills, yesterdayKills, chosenTitle, knownCurrencies, watchedFaction, drunk, health, power1, power2, power3, "
"power4, power5, power6, power7, latency, talentGroupsCount, activeTalentGroup, exploredZones, equipmentCache, ammoId, knownTitles, actionBars, grantableLevels) VALUES "
- "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", CONNECTION_ASYNC);
- PrepareStatement(CHAR_UPD_CHARACTER, "UPDATE characters SET name=?,race=?,class=?,gender=?,level=?,xp=?,money=?,playerBytes=?,playerBytes2=?,playerFlags=?,"
+ "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_UPD_CHARACTER, "UPDATE characters SET name=?,race=?,class=?,gender=?,level=?,xp=?,money=?,skin=?,face=?,hairStyle=?,hairColor=?,facialStyle=?,bankSlots=?,restState=?,playerFlags=?,"
"map=?,instance_id=?,instance_mode_mask=?,position_x=?,position_y=?,position_z=?,orientation=?,trans_x=?,trans_y=?,trans_z=?,trans_o=?,transguid=?,taximask=?,cinematic=?,totaltime=?,leveltime=?,rest_bonus=?,"
"logout_time=?,is_logout_resting=?,resettalents_cost=?,resettalents_time=?,extra_flags=?,stable_slots=?,at_login=?,zone=?,death_expire_time=?,taxi_path=?,"
"arenaPoints=?,totalHonorPoints=?,todayHonorPoints=?,yesterdayHonorPoints=?,totalKills=?,todayKills=?,yesterdayKills=?,chosenTitle=?,knownCurrencies=?,"
@@ -407,7 +407,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE_GUID, "DELETE FROM character_instance WHERE guid = ? AND instance = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_CHAR_INSTANCE, "UPDATE character_instance SET instance = ?, permanent = ?, extendState = ? WHERE guid = ? AND instance = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_CHAR_INSTANCE, "INSERT INTO character_instance (guid, instance, permanent, extendState) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
- PrepareStatement(CHAR_UPD_GENDER_PLAYERBYTES, "UPDATE characters SET gender = ?, playerBytes = ?, playerBytes2 = ? WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_UPD_GENDER_AND_APPEARANCE, "UPDATE characters SET gender = ?, skin = ?, face = ?, hairStyle = ?, hairColor = ?, facialStyle = ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHARACTER_SKILL, "DELETE FROM character_skills WHERE guid = ? AND skill = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_ADD_CHARACTER_SOCIAL_FLAGS, "UPDATE character_social SET flags = flags | ? WHERE guid = ? AND friend = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_REM_CHARACTER_SOCIAL_FLAGS, "UPDATE character_social SET flags = flags & ~ ? WHERE guid = ? AND friend = ?", CONNECTION_ASYNC);
@@ -440,7 +440,6 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_SEL_CHAR_OLD_CHARS, "SELECT guid, deleteInfos_Account FROM characters WHERE deleteDate IS NOT NULL AND deleteDate < ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_ARENA_TEAM_ID_BY_PLAYER_GUID, "SELECT arena_team_member.arenateamid FROM arena_team_member JOIN arena_team ON arena_team_member.arenateamid = arena_team.arenateamid WHERE guid = ? AND type = ? LIMIT 1", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_MAIL, "SELECT id, messageType, sender, receiver, subject, body, has_items, expire_time, deliver_time, money, cod, checked, stationery, mailTemplateId FROM mail WHERE receiver = ? ORDER BY id DESC", CONNECTION_SYNCH);
- PrepareStatement(CHAR_SEL_CHAR_PLAYERBYTES2, "SELECT playerBytes2 FROM characters WHERE guid = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHAR_GUID_BY_NAME, "SELECT guid FROM characters WHERE name = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_DEL_CHAR_AURA_FROZEN, "DELETE FROM character_aura WHERE spell = 9454 AND guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHAR_INVENTORY_COUNT_ITEM, "SELECT COUNT(itemEntry) FROM character_inventory ci INNER JOIN item_instance ii ON ii.guid = ci.item WHERE itemEntry = ?", CONNECTION_SYNCH);
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.h b/src/server/database/Database/Implementation/CharacterDatabase.h
index 19d4a609e77..430243a8f1e 100644
--- a/src/server/database/Database/Implementation/CharacterDatabase.h
+++ b/src/server/database/Database/Implementation/CharacterDatabase.h
@@ -334,7 +334,7 @@ enum CharacterDatabaseStatements
CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE_GUID,
CHAR_UPD_CHAR_INSTANCE,
CHAR_INS_CHAR_INSTANCE,
- CHAR_UPD_GENDER_PLAYERBYTES,
+ CHAR_UPD_GENDER_AND_APPEARANCE,
CHAR_DEL_CHARACTER_SKILL,
CHAR_UPD_ADD_CHARACTER_SOCIAL_FLAGS,
CHAR_UPD_REM_CHARACTER_SOCIAL_FLAGS,
@@ -371,7 +371,6 @@ enum CharacterDatabaseStatements
CHAR_SEL_CHAR_OLD_CHARS,
CHAR_SEL_ARENA_TEAM_ID_BY_PLAYER_GUID,
CHAR_SEL_MAIL,
- CHAR_SEL_CHAR_PLAYERBYTES2,
CHAR_SEL_CHAR_GUID_BY_NAME,
CHAR_DEL_CHAR_AURA_FROZEN,
CHAR_SEL_CHAR_INVENTORY_COUNT_ITEM,
@@ -538,7 +537,7 @@ enum CharacterDatabaseStatements
MAX_CHARACTERDATABASE_STATEMENTS
};
-class CharacterDatabaseConnection : public MySQLConnection
+class TC_DATABASE_API CharacterDatabaseConnection : public MySQLConnection
{
public:
typedef CharacterDatabaseStatements Statements;
diff --git a/src/server/database/Database/Implementation/LoginDatabase.cpp b/src/server/database/Database/Implementation/LoginDatabase.cpp
index 163a2bebeb9..4f056e2686d 100644
--- a/src/server/database/Database/Implementation/LoginDatabase.cpp
+++ b/src/server/database/Database/Implementation/LoginDatabase.cpp
@@ -24,7 +24,7 @@ void LoginDatabaseConnection::DoPrepareStatements()
PrepareStatement(LOGIN_SEL_REALMLIST, "SELECT id, name, address, localAddress, localSubnetMask, port, icon, flag, timezone, allowedSecurityLevel, population, gamebuild FROM realmlist WHERE flag <> 3 ORDER BY name", CONNECTION_SYNCH);
PrepareStatement(LOGIN_DEL_EXPIRED_IP_BANS, "DELETE FROM ip_banned WHERE unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()", CONNECTION_ASYNC);
- PrepareStatement(LOGIN_UPD_EXPIRED_ACCOUNT_BANS, "UPDATE account_banned SET active = 0 WHERE active = 1 AND unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()", CONNECTION_SYNCH);
+ PrepareStatement(LOGIN_UPD_EXPIRED_ACCOUNT_BANS, "UPDATE account_banned SET active = 0 WHERE active = 1 AND unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()", CONNECTION_ASYNC);
PrepareStatement(LOGIN_SEL_IP_INFO, "(SELECT unbandate > UNIX_TIMESTAMP() OR unbandate = bandate AS banned, NULL as country FROM ip_banned WHERE ip = ?) "
"UNION "
"(SELECT NULL AS banned, country FROM ip2nation WHERE INET_NTOA(ip) = ?)", CONNECTION_ASYNC);
@@ -37,7 +37,7 @@ void LoginDatabaseConnection::DoPrepareStatements()
PrepareStatement(LOGIN_DEL_ACCOUNT_BANNED, "DELETE FROM account_banned WHERE id = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_UPD_VS, "UPDATE account SET v = ?, s = ? WHERE username = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_UPD_LOGONPROOF, "UPDATE account SET sessionkey = ?, last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE username = ?", CONNECTION_SYNCH);
- PrepareStatement(LOGIN_SEL_LOGONCHALLENGE, "SELECT a.id, UPPER(a.username), a.locked, a.lock_country, a.last_ip, a.failed_logins, ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, "
+ PrepareStatement(LOGIN_SEL_LOGONCHALLENGE, "SELECT a.id, a.username, a.locked, a.lock_country, a.last_ip, a.failed_logins, ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, "
"ab.unbandate = ab.bandate, aa.gmlevel, a.token_key, a.sha_pass_hash, a.v, a.s "
"FROM account a LEFT JOIN account_access aa ON a.id = aa.id LEFT JOIN account_banned ab ON ab.id = a.id AND ab.active = 1 WHERE a.username = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_SEL_RECONNECTCHALLENGE, "SELECT a.id, UPPER(a.username), a.locked, a.lock_country, a.last_ip, a.failed_logins, ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, "
diff --git a/src/server/database/Database/Implementation/LoginDatabase.h b/src/server/database/Database/Implementation/LoginDatabase.h
index a3789fa2557..e206be16d73 100644
--- a/src/server/database/Database/Implementation/LoginDatabase.h
+++ b/src/server/database/Database/Implementation/LoginDatabase.h
@@ -116,7 +116,7 @@ enum LoginDatabaseStatements
MAX_LOGINDATABASE_STATEMENTS
};
-class LoginDatabaseConnection : public MySQLConnection
+class TC_DATABASE_API LoginDatabaseConnection : public MySQLConnection
{
public:
typedef LoginDatabaseStatements Statements;
diff --git a/src/server/database/Database/Implementation/WorldDatabase.h b/src/server/database/Database/Implementation/WorldDatabase.h
index 6ac4ce589e3..e0a02423446 100644
--- a/src/server/database/Database/Implementation/WorldDatabase.h
+++ b/src/server/database/Database/Implementation/WorldDatabase.h
@@ -103,7 +103,7 @@ enum WorldDatabaseStatements
MAX_WORLDDATABASE_STATEMENTS
};
-class WorldDatabaseConnection : public MySQLConnection
+class TC_DATABASE_API WorldDatabaseConnection : public MySQLConnection
{
public:
typedef WorldDatabaseStatements Statements;
diff --git a/src/server/database/Database/MySQLConnection.cpp b/src/server/database/Database/MySQLConnection.cpp
index 41dd61d3c3a..93d2a35f310 100644
--- a/src/server/database/Database/MySQLConnection.cpp
+++ b/src/server/database/Database/MySQLConnection.cpp
@@ -37,7 +37,6 @@ MySQLConnection::MySQLConnection(MySQLConnectionInfo& connInfo) :
m_reconnecting(false),
m_prepareError(false),
m_queue(NULL),
-m_worker(NULL),
m_Mysql(NULL),
m_connectionInfo(connInfo),
m_connectionFlags(CONNECTION_SYNCH) { }
@@ -50,24 +49,26 @@ m_Mysql(NULL),
m_connectionInfo(connInfo),
m_connectionFlags(CONNECTION_ASYNC)
{
- m_worker = new DatabaseWorker(m_queue, this);
+ m_worker = Trinity::make_unique<DatabaseWorker>(m_queue, this);
}
MySQLConnection::~MySQLConnection()
{
- delete m_worker;
-
- for (size_t i = 0; i < m_stmts.size(); ++i)
- delete m_stmts[i];
-
- if (m_Mysql)
- mysql_close(m_Mysql);
+ Close();
}
void MySQLConnection::Close()
{
- /// Only close us if we're not operating
- delete this;
+ // Stop the worker thread before the statements are cleared
+ m_worker.reset();
+
+ m_stmts.clear();
+
+ if (m_Mysql)
+ {
+ mysql_close(m_Mysql);
+ m_Mysql = nullptr;
+ }
}
uint32 MySQLConnection::Open()
@@ -412,7 +413,7 @@ int MySQLConnection::ExecuteTransaction(SQLTransaction& transaction)
MySQLPreparedStatement* MySQLConnection::GetPreparedStatement(uint32 index)
{
ASSERT(index < m_stmts.size());
- MySQLPreparedStatement* ret = m_stmts[index];
+ MySQLPreparedStatement* ret = m_stmts[index].get();
if (!ret)
TC_LOG_ERROR("sql.sql", "Could not fetch prepared statement %u on database `%s`, connection type: %s.",
index, m_connectionInfo.database.c_str(), (m_connectionFlags & CONNECTION_ASYNC) ? "asynchronous" : "synchronous");
@@ -424,16 +425,12 @@ void MySQLConnection::PrepareStatement(uint32 index, const char* sql, Connection
{
m_queries.insert(PreparedStatementMap::value_type(index, std::make_pair(sql, flags)));
- // For reconnection case
- if (m_reconnecting)
- delete m_stmts[index];
-
// Check if specified query should be prepared on this connection
// i.e. don't prepare async statements on synchronous connections
// to save memory that will not be used.
if (!(m_connectionFlags & flags))
{
- m_stmts[index] = NULL;
+ m_stmts[index].reset();
return;
}
@@ -455,8 +452,7 @@ void MySQLConnection::PrepareStatement(uint32 index, const char* sql, Connection
}
else
{
- MySQLPreparedStatement* mStmt = new MySQLPreparedStatement(stmt);
- m_stmts[index] = mStmt;
+ m_stmts[index] = Trinity::make_unique<MySQLPreparedStatement>(stmt);
}
}
}
@@ -477,7 +473,7 @@ PreparedResultSet* MySQLConnection::Query(PreparedStatement* stmt)
return new PreparedResultSet(stmt->m_stmt->GetSTMT(), result, rowCount, fieldCount);
}
-bool MySQLConnection::_HandleMySQLErrno(uint32 errNo)
+bool MySQLConnection::_HandleMySQLErrno(uint32 errNo, uint8 attempts /*= 5*/)
{
switch (errNo)
{
@@ -486,9 +482,21 @@ bool MySQLConnection::_HandleMySQLErrno(uint32 errNo)
case CR_INVALID_CONN_HANDLE:
case CR_SERVER_LOST_EXTENDED:
{
+ if (m_Mysql)
+ {
+ TC_LOG_ERROR("sql.sql", "Lost the connection to the MySQL server!");
+
+ mysql_close(GetHandle());
+ m_Mysql = nullptr;
+ }
+
+ /*no break*/
+ }
+ case CR_CONN_HOST_ERROR:
+ {
+ TC_LOG_INFO("sql.sql", "Attempting to reconnect to the MySQL server...");
+
m_reconnecting = true;
- uint64 oldThreadId = mysql_thread_id(GetHandle());
- mysql_close(GetHandle());
uint32 const lErrno = Open();
if (!lErrno)
@@ -496,24 +504,37 @@ bool MySQLConnection::_HandleMySQLErrno(uint32 errNo)
// Don't remove 'this' pointer unless you want to skip loading all prepared statements...
if (!this->PrepareStatements())
{
- TC_LOG_ERROR("sql.sql", "Could not re-prepare statements!");
- Close();
- return false;
+ TC_LOG_FATAL("sql.sql", "Could not re-prepare statements!");
+ std::this_thread::sleep_for(std::chrono::seconds(10));
+ std::abort();
}
- TC_LOG_INFO("sql.sql", "Connection to the MySQL server is active.");
- if (oldThreadId != mysql_thread_id(GetHandle()))
- TC_LOG_INFO("sql.sql", "Successfully reconnected to %s @%s:%s (%s).",
- m_connectionInfo.database.c_str(), m_connectionInfo.host.c_str(), m_connectionInfo.port_or_socket.c_str(),
- (m_connectionFlags & CONNECTION_ASYNC) ? "asynchronous" : "synchronous");
+ TC_LOG_INFO("sql.sql", "Successfully reconnected to %s @%s:%s (%s).",
+ m_connectionInfo.database.c_str(), m_connectionInfo.host.c_str(), m_connectionInfo.port_or_socket.c_str(),
+ (m_connectionFlags & CONNECTION_ASYNC) ? "asynchronous" : "synchronous");
m_reconnecting = false;
return true;
}
- // It's possible this attempted reconnect throws 2006 at us. To prevent crazy recursive calls, sleep here.
- std::this_thread::sleep_for(std::chrono::seconds(3)); // Sleep 3 seconds
- return _HandleMySQLErrno(lErrno); // Call self (recursive)
+ if ((--attempts) == 0)
+ {
+ // Shut down the server when the mysql server isn't
+ // reachable for some time
+ TC_LOG_FATAL("sql.sql", "Failed to reconnect to the MySQL server, "
+ "terminating the server to prevent data corruption!");
+
+ // We could also initiate a shutdown through using std::raise(SIGTERM)
+ std::this_thread::sleep_for(std::chrono::seconds(10));
+ std::abort();
+ }
+ else
+ {
+ // It's possible this attempted reconnect throws 2006 at us.
+ // To prevent crazy recursive calls, sleep here.
+ std::this_thread::sleep_for(std::chrono::seconds(3)); // Sleep 3 seconds
+ return _HandleMySQLErrno(lErrno, attempts); // Call self (recursive)
+ }
}
case ER_LOCK_DEADLOCK:
diff --git a/src/server/database/Database/MySQLConnection.h b/src/server/database/Database/MySQLConnection.h
index a981caa607e..566995988c0 100644
--- a/src/server/database/Database/MySQLConnection.h
+++ b/src/server/database/Database/MySQLConnection.h
@@ -35,7 +35,7 @@ enum ConnectionFlags
CONNECTION_BOTH = CONNECTION_ASYNC | CONNECTION_SYNCH
};
-struct MySQLConnectionInfo
+struct TC_DATABASE_API MySQLConnectionInfo
{
explicit MySQLConnectionInfo(std::string const& infoString)
{
@@ -62,7 +62,7 @@ struct MySQLConnectionInfo
typedef std::map<uint32 /*index*/, std::pair<std::string /*query*/, ConnectionFlags /*sync/async*/> > PreparedStatementMap;
-class MySQLConnection
+class TC_DATABASE_API MySQLConnection
{
template <class T> friend class DatabaseWorkerPool;
friend class PingOperation;
@@ -116,18 +116,18 @@ class MySQLConnection
virtual void DoPrepareStatements() = 0;
protected:
- std::vector<MySQLPreparedStatement*> m_stmts; //! PreparedStatements storage
+ std::vector<std::unique_ptr<MySQLPreparedStatement>> m_stmts; //! PreparedStatements storage
PreparedStatementMap m_queries; //! Query storage
bool m_reconnecting; //! Are we reconnecting?
bool m_prepareError; //! Was there any error while preparing statements?
private:
- bool _HandleMySQLErrno(uint32 errNo);
+ bool _HandleMySQLErrno(uint32 errNo, uint8 attempts = 5);
private:
ProducerConsumerQueue<SQLOperation*>* m_queue; //! Queue shared with other asynchronous connections.
- DatabaseWorker* m_worker; //! Core worker task.
- MYSQL * m_Mysql; //! MySQL Handle.
+ std::unique_ptr<DatabaseWorker> m_worker; //! Core worker task.
+ MYSQL* m_Mysql; //! MySQL Handle.
MySQLConnectionInfo& m_connectionInfo; //! Connection info (used for logging)
ConnectionFlags m_connectionFlags; //! Connection flags (for preparing relevant statements)
std::mutex m_Mutex;
diff --git a/src/server/database/Database/MySQLThreading.h b/src/server/database/Database/MySQLThreading.h
index 1cfa11d7e5b..b6083500989 100644
--- a/src/server/database/Database/MySQLThreading.h
+++ b/src/server/database/Database/MySQLThreading.h
@@ -20,7 +20,7 @@
#include "Log.h"
-class MySQL
+class TC_DATABASE_API MySQL
{
public:
static void Library_Init()
diff --git a/src/server/database/Database/PreparedStatement.h b/src/server/database/Database/PreparedStatement.h
index 7d6c98463d0..faaec27014f 100644
--- a/src/server/database/Database/PreparedStatement.h
+++ b/src/server/database/Database/PreparedStatement.h
@@ -70,7 +70,7 @@ struct PreparedStatementData
class MySQLPreparedStatement;
//- Upper-level class that is used in code
-class PreparedStatement
+class TC_DATABASE_API PreparedStatement
{
friend class PreparedStatementTask;
friend class MySQLPreparedStatement;
@@ -109,7 +109,7 @@ class PreparedStatement
//- Class of which the instances are unique per MySQLConnection
//- access to these class objects is only done when a prepared statement task
//- is executed.
-class MySQLPreparedStatement
+class TC_DATABASE_API MySQLPreparedStatement
{
friend class MySQLConnection;
friend class PreparedStatement;
@@ -157,7 +157,7 @@ typedef std::future<PreparedQueryResult> PreparedQueryResultFuture;
typedef std::promise<PreparedQueryResult> PreparedQueryResultPromise;
//- Lower-level class, enqueuable operation
-class PreparedStatementTask : public SQLOperation
+class TC_DATABASE_API PreparedStatementTask : public SQLOperation
{
public:
PreparedStatementTask(PreparedStatement* stmt, bool async = false);
diff --git a/src/server/database/Database/QueryHolder.h b/src/server/database/Database/QueryHolder.h
index 9a5a03fda42..2446a4db2bd 100644
--- a/src/server/database/Database/QueryHolder.h
+++ b/src/server/database/Database/QueryHolder.h
@@ -20,7 +20,7 @@
#include <future>
-class SQLQueryHolder
+class TC_DATABASE_API SQLQueryHolder
{
friend class SQLQueryHolderTask;
private:
@@ -46,7 +46,7 @@ class SQLQueryHolder
typedef std::future<SQLQueryHolder*> QueryResultHolderFuture;
typedef std::promise<SQLQueryHolder*> QueryResultHolderPromise;
-class SQLQueryHolderTask : public SQLOperation
+class TC_DATABASE_API SQLQueryHolderTask : public SQLOperation
{
private:
SQLQueryHolder* m_holder;
diff --git a/src/server/database/Database/QueryResult.h b/src/server/database/Database/QueryResult.h
index d4d63b5ec85..3b1691db1a6 100644
--- a/src/server/database/Database/QueryResult.h
+++ b/src/server/database/Database/QueryResult.h
@@ -27,7 +27,7 @@
#endif
#include <mysql.h>
-class ResultSet
+class TC_DATABASE_API ResultSet
{
public:
ResultSet(MYSQL_RES* result, MYSQL_FIELD* fields, uint64 rowCount, uint32 fieldCount);
@@ -60,7 +60,7 @@ class ResultSet
typedef std::shared_ptr<ResultSet> QueryResult;
-class PreparedResultSet
+class TC_DATABASE_API PreparedResultSet
{
public:
PreparedResultSet(MYSQL_STMT* stmt, MYSQL_RES* result, uint64 rowCount, uint32 fieldCount);
diff --git a/src/server/database/Database/SQLOperation.h b/src/server/database/Database/SQLOperation.h
index f0500d1f232..5b3032eab87 100644
--- a/src/server/database/Database/SQLOperation.h
+++ b/src/server/database/Database/SQLOperation.h
@@ -53,7 +53,7 @@ union SQLResultSetUnion
class MySQLConnection;
-class SQLOperation
+class TC_DATABASE_API SQLOperation
{
public:
SQLOperation(): m_conn(NULL) { }
diff --git a/src/server/database/Database/Transaction.h b/src/server/database/Database/Transaction.h
index 5780c0363d9..7b5b6addfe4 100644
--- a/src/server/database/Database/Transaction.h
+++ b/src/server/database/Database/Transaction.h
@@ -25,7 +25,7 @@
class PreparedStatement;
/*! Transactions, high level class. */
-class Transaction
+class TC_DATABASE_API Transaction
{
friend class TransactionTask;
friend class MySQLConnection;
@@ -58,7 +58,7 @@ class Transaction
typedef std::shared_ptr<Transaction> SQLTransaction;
/*! Low level class*/
-class TransactionTask : public SQLOperation
+class TC_DATABASE_API TransactionTask : public SQLOperation
{
template <class T> friend class DatabaseWorkerPool;
friend class DatabaseWorker;
diff --git a/src/server/database/Logging/AppenderDB.h b/src/server/database/Logging/AppenderDB.h
index a6acc66b48c..225ae969802 100644
--- a/src/server/database/Logging/AppenderDB.h
+++ b/src/server/database/Logging/AppenderDB.h
@@ -20,7 +20,7 @@
#include "Appender.h"
-class AppenderDB: public Appender
+class TC_DATABASE_API AppenderDB: public Appender
{
public:
typedef std::integral_constant<AppenderType, APPENDER_DB>::type TypeIndex;
diff --git a/src/server/database/Updater/DBUpdater.cpp b/src/server/database/Updater/DBUpdater.cpp
index 170954a86f4..5f5b519d2b3 100644
--- a/src/server/database/Updater/DBUpdater.cpp
+++ b/src/server/database/Updater/DBUpdater.cpp
@@ -21,6 +21,7 @@
#include "UpdateFetcher.h"
#include "DatabaseLoader.h"
#include "Config.h"
+#include "BuiltInConfig.h"
#include <fstream>
#include <iostream>
@@ -35,23 +36,17 @@ using namespace boost::process;
using namespace boost::process::initializers;
using namespace boost::iostreams;
-std::string DBUpdaterUtil::GetMySqlCli()
+std::string DBUpdaterUtil::GetCorrectedMySQLExecutable()
{
if (!corrected_path().empty())
return corrected_path();
else
- {
- std::string const entry = sConfigMgr->GetStringDefault("Updates.MySqlCLIPath", "");
- if (!entry.empty())
- return entry;
- else
- return GitRevision::GetMySQLExecutable();
- }
+ return BuiltInConfig::GetMySQLExecutable();
}
bool DBUpdaterUtil::CheckExecutable()
{
- boost::filesystem::path exe(GetMySqlCli());
+ boost::filesystem::path exe(GetCorrectedMySQLExecutable());
if (!exists(exe))
{
exe.clear();
@@ -85,16 +80,6 @@ std::string& DBUpdaterUtil::corrected_path()
return path;
}
-template<class T>
-std::string DBUpdater<T>::GetSourceDirectory()
-{
- std::string const entry = sConfigMgr->GetStringDefault("Updates.SourcePath", "");
- if (!entry.empty())
- return entry;
- else
- return GitRevision::GetSourceDirectory();
-}
-
// Auth Database
template<>
std::string DBUpdater<LoginDatabaseConnection>::GetConfigEntry()
@@ -111,7 +96,8 @@ std::string DBUpdater<LoginDatabaseConnection>::GetTableName()
template<>
std::string DBUpdater<LoginDatabaseConnection>::GetBaseFile()
{
- return DBUpdater<LoginDatabaseConnection>::GetSourceDirectory() + "/sql/base/auth_database.sql";
+ return BuiltInConfig::GetSourceDirectory() +
+ "/sql/base/auth_database.sql";
}
template<>
@@ -169,7 +155,8 @@ std::string DBUpdater<CharacterDatabaseConnection>::GetTableName()
template<>
std::string DBUpdater<CharacterDatabaseConnection>::GetBaseFile()
{
- return DBUpdater<CharacterDatabaseConnection>::GetSourceDirectory() + "/sql/base/characters_database.sql";
+ return BuiltInConfig::GetSourceDirectory() +
+ "/sql/base/characters_database.sql";
}
template<>
@@ -239,7 +226,7 @@ bool DBUpdater<T>::Update(DatabaseWorkerPool<T>& pool)
TC_LOG_INFO("sql.updates", "Updating %s database...", DBUpdater<T>::GetTableName().c_str());
- Path const sourceDirectory(GetSourceDirectory());
+ Path const sourceDirectory(BuiltInConfig::GetSourceDirectory());
if (!is_directory(sourceDirectory))
{
@@ -410,7 +397,7 @@ void DBUpdater<T>::ApplyFile(DatabaseWorkerPool<T>& pool, std::string const& hos
boost::process::pipe errPipe = create_pipe();
child c = execute(run_exe(
- boost::filesystem::absolute(DBUpdaterUtil::GetMySqlCli()).generic_string()),
+ boost::filesystem::absolute(DBUpdaterUtil::GetCorrectedMySQLExecutable()).generic_string()),
set_args(args), bind_stdin(source), throw_on_error(),
bind_stdout(file_descriptor_sink(outPipe.sink, close_handle)),
bind_stderr(file_descriptor_sink(errPipe.sink, close_handle)));
@@ -449,6 +436,6 @@ void DBUpdater<T>::ApplyFile(DatabaseWorkerPool<T>& pool, std::string const& hos
}
}
-template class DBUpdater<LoginDatabaseConnection>;
-template class DBUpdater<WorldDatabaseConnection>;
-template class DBUpdater<CharacterDatabaseConnection>;
+template class TC_DATABASE_API DBUpdater<LoginDatabaseConnection>;
+template class TC_DATABASE_API DBUpdater<WorldDatabaseConnection>;
+template class TC_DATABASE_API DBUpdater<CharacterDatabaseConnection>;
diff --git a/src/server/database/Updater/DBUpdater.h b/src/server/database/Updater/DBUpdater.h
index c9792ffe060..cc5d3aad68b 100644
--- a/src/server/database/Updater/DBUpdater.h
+++ b/src/server/database/Updater/DBUpdater.h
@@ -23,7 +23,7 @@
#include <string>
#include <boost/filesystem.hpp>
-class UpdateException : public std::exception
+class TC_DATABASE_API UpdateException : public std::exception
{
public:
UpdateException(std::string const& msg) : _msg(msg) { }
@@ -41,7 +41,7 @@ enum BaseLocation
LOCATION_DOWNLOAD
};
-struct UpdateResult
+struct TC_DATABASE_API UpdateResult
{
UpdateResult()
: updated(0), recent(0), archived(0) { }
@@ -57,7 +57,7 @@ struct UpdateResult
class DBUpdaterUtil
{
public:
- static std::string GetMySqlCli();
+ static std::string GetCorrectedMySQLExecutable();
static bool CheckExecutable();
@@ -66,13 +66,11 @@ private:
};
template <class T>
-class DBUpdater
+class TC_DATABASE_API DBUpdater
{
public:
using Path = boost::filesystem::path;
- static std::string GetSourceDirectory();
-
static inline std::string GetConfigEntry();
static inline std::string GetTableName();
diff --git a/src/server/database/Updater/UpdateFetcher.cpp b/src/server/database/Updater/UpdateFetcher.cpp
index fd0dbdd4b5a..2d60cdb92ef 100644
--- a/src/server/database/Updater/UpdateFetcher.cpp
+++ b/src/server/database/Updater/UpdateFetcher.cpp
@@ -137,24 +137,33 @@ UpdateFetcher::AppliedFileStorage UpdateFetcher::ReceiveAppliedFiles() const
return map;
}
-UpdateFetcher::SQLUpdate UpdateFetcher::ReadSQLUpdate(boost::filesystem::path const& file) const
+std::string UpdateFetcher::ReadSQLUpdate(boost::filesystem::path const& file) const
{
std::ifstream in(file.c_str());
- WPFatal(in.is_open(), "Could not read an update file.");
+ if (!in.is_open())
+ {
+ TC_LOG_FATAL("sql.updates", "Failed to open the sql update \"%s\" for reading! "
+ "Stopping the server to keep the database integrity, "
+ "try to identify and solve the issue or disabled the database updater.",
+ file.generic_string().c_str());
- auto const start_pos = in.tellg();
- in.ignore(std::numeric_limits<std::streamsize>::max());
- auto const char_count = in.gcount();
- in.seekg(start_pos);
+ throw UpdateException("Opening the sql update failed!");
+ }
- SQLUpdate const update(new std::string(char_count, char{}));
+ auto update = [&in] {
+ std::ostringstream ss;
+ ss << in.rdbuf();
+ return ss.str();
+ }();
- in.read(&(*update)[0], update->size());
in.close();
return update;
}
-UpdateResult UpdateFetcher::Update(bool const redundancyChecks, bool const allowRehash, bool const archivedRedundancy, int32 const cleanDeadReferencesMaxCount) const
+UpdateResult UpdateFetcher::Update(bool const redundancyChecks,
+ bool const allowRehash,
+ bool const archivedRedundancy,
+ int32 const cleanDeadReferencesMaxCount) const
{
LocaleFileStorage const available = GetFileList();
AppliedFileStorage applied = ReceiveAppliedFiles();
@@ -200,11 +209,9 @@ UpdateResult UpdateFetcher::Update(bool const redundancyChecks, bool const allow
}
}
- // Read update from file
- SQLUpdate const update = ReadSQLUpdate(availableQuery.first);
-
// Calculate hash
- std::string const hash = CalculateHash(update);
+ std::string const hash =
+ CalculateHash(ReadSQLUpdate(availableQuery.first));
UpdateMode mode = MODE_APPLY;
@@ -327,11 +334,11 @@ UpdateResult UpdateFetcher::Update(bool const redundancyChecks, bool const allow
return UpdateResult(importedUpdates, countRecentUpdates, countArchivedUpdates);
}
-std::string UpdateFetcher::CalculateHash(SQLUpdate const& query) const
+std::string UpdateFetcher::CalculateHash(std::string const& query) const
{
// Calculate a Sha1 hash based on query content.
unsigned char digest[SHA_DIGEST_LENGTH];
- SHA1((unsigned char*)query->c_str(), query->length(), (unsigned char*)&digest);
+ SHA1((unsigned char*)query.c_str(), query.length(), (unsigned char*)&digest);
return ByteArrayToHexStr(digest, SHA_DIGEST_LENGTH);
}
diff --git a/src/server/database/Updater/UpdateFetcher.h b/src/server/database/Updater/UpdateFetcher.h
index 22a0d08c7f8..a17658818ce 100644
--- a/src/server/database/Updater/UpdateFetcher.h
+++ b/src/server/database/Updater/UpdateFetcher.h
@@ -25,7 +25,7 @@
#include <memory>
#include <vector>
-class UpdateFetcher
+class TC_DATABASE_API UpdateFetcher
{
typedef boost::filesystem::path Path;
@@ -103,16 +103,16 @@ private:
typedef std::unordered_map<std::string, std::string> HashToFileNameStorage;
typedef std::unordered_map<std::string, AppliedFileEntry> AppliedFileStorage;
typedef std::vector<UpdateFetcher::DirectoryEntry> DirectoryStorage;
- typedef std::shared_ptr<std::string> SQLUpdate;
LocaleFileStorage GetFileList() const;
- void FillFileListRecursively(Path const& path, LocaleFileStorage& storage, State const state, uint32 const depth) const;
+ void FillFileListRecursively(Path const& path, LocaleFileStorage& storage,
+ State const state, uint32 const depth) const;
DirectoryStorage ReceiveIncludedDirectories() const;
AppliedFileStorage ReceiveAppliedFiles() const;
- SQLUpdate ReadSQLUpdate(Path const& file) const;
- std::string CalculateHash(SQLUpdate const& query) const;
+ std::string ReadSQLUpdate(Path const& file) const;
+ std::string CalculateHash(std::string const& query) const;
uint32 Apply(Path const& path) const;
diff --git a/src/server/game/AI/CoreAI/CombatAI.h b/src/server/game/AI/CoreAI/CombatAI.h
index 55b91b6969e..f1718fbdb6a 100644
--- a/src/server/game/AI/CoreAI/CombatAI.h
+++ b/src/server/game/AI/CoreAI/CombatAI.h
@@ -25,7 +25,7 @@
class Creature;
-class AggressorAI : public CreatureAI
+class TC_GAME_API AggressorAI : public CreatureAI
{
public:
explicit AggressorAI(Creature* c) : CreatureAI(c) { }
@@ -36,7 +36,7 @@ class AggressorAI : public CreatureAI
typedef std::vector<uint32> SpellVct;
-class CombatAI : public CreatureAI
+class TC_GAME_API CombatAI : public CreatureAI
{
public:
explicit CombatAI(Creature* c) : CreatureAI(c) { }
@@ -55,7 +55,7 @@ class CombatAI : public CreatureAI
SpellVct spells;
};
-class CasterAI : public CombatAI
+class TC_GAME_API CasterAI : public CombatAI
{
public:
explicit CasterAI(Creature* c) : CombatAI(c) { m_attackDist = MELEE_RANGE; }
@@ -67,7 +67,7 @@ class CasterAI : public CombatAI
float m_attackDist;
};
-struct ArcherAI : public CreatureAI
+struct TC_GAME_API ArcherAI : public CreatureAI
{
public:
explicit ArcherAI(Creature* c);
@@ -80,7 +80,7 @@ struct ArcherAI : public CreatureAI
float m_minRange;
};
-struct TurretAI : public CreatureAI
+struct TC_GAME_API TurretAI : public CreatureAI
{
public:
explicit TurretAI(Creature* c);
@@ -97,7 +97,7 @@ struct TurretAI : public CreatureAI
#define VEHICLE_CONDITION_CHECK_TIME 1000
#define VEHICLE_DISMISS_TIME 5000
-struct VehicleAI : public CreatureAI
+struct TC_GAME_API VehicleAI : public CreatureAI
{
public:
explicit VehicleAI(Creature* creature);
diff --git a/src/server/game/AI/CoreAI/GameObjectAI.h b/src/server/game/AI/CoreAI/GameObjectAI.h
index 4f256a5de31..7a2f23ac804 100644
--- a/src/server/game/AI/CoreAI/GameObjectAI.h
+++ b/src/server/game/AI/CoreAI/GameObjectAI.h
@@ -26,7 +26,7 @@
#include "GameObject.h"
#include "CreatureAI.h"
-class GameObjectAI
+class TC_GAME_API GameObjectAI
{
protected:
GameObject* const go;
@@ -63,7 +63,7 @@ class GameObjectAI
virtual void EventInform(uint32 /*eventId*/) { }
};
-class NullGameObjectAI : public GameObjectAI
+class TC_GAME_API NullGameObjectAI : public GameObjectAI
{
public:
explicit NullGameObjectAI(GameObject* g);
diff --git a/src/server/game/AI/CoreAI/GuardAI.h b/src/server/game/AI/CoreAI/GuardAI.h
index 63f2750a5d4..a6aa4b6624a 100644
--- a/src/server/game/AI/CoreAI/GuardAI.h
+++ b/src/server/game/AI/CoreAI/GuardAI.h
@@ -23,7 +23,7 @@
class Creature;
-class GuardAI : public ScriptedAI
+class TC_GAME_API GuardAI : public ScriptedAI
{
public:
explicit GuardAI(Creature* creature);
diff --git a/src/server/game/AI/CoreAI/PassiveAI.h b/src/server/game/AI/CoreAI/PassiveAI.h
index bd72cd7fbe7..5a6dba7046d 100644
--- a/src/server/game/AI/CoreAI/PassiveAI.h
+++ b/src/server/game/AI/CoreAI/PassiveAI.h
@@ -21,7 +21,7 @@
#include "CreatureAI.h"
-class PassiveAI : public CreatureAI
+class TC_GAME_API PassiveAI : public CreatureAI
{
public:
explicit PassiveAI(Creature* c);
@@ -33,7 +33,7 @@ class PassiveAI : public CreatureAI
static int Permissible(const Creature*) { return PERMIT_BASE_IDLE; }
};
-class PossessedAI : public CreatureAI
+class TC_GAME_API PossessedAI : public CreatureAI
{
public:
explicit PossessedAI(Creature* c);
@@ -49,7 +49,7 @@ class PossessedAI : public CreatureAI
static int Permissible(const Creature*) { return PERMIT_BASE_IDLE; }
};
-class NullCreatureAI : public CreatureAI
+class TC_GAME_API NullCreatureAI : public CreatureAI
{
public:
explicit NullCreatureAI(Creature* c);
@@ -63,7 +63,7 @@ class NullCreatureAI : public CreatureAI
static int Permissible(const Creature*) { return PERMIT_BASE_IDLE; }
};
-class CritterAI : public PassiveAI
+class TC_GAME_API CritterAI : public PassiveAI
{
public:
explicit CritterAI(Creature* c) : PassiveAI(c) { }
@@ -72,7 +72,7 @@ class CritterAI : public PassiveAI
void EnterEvadeMode(EvadeReason why) override;
};
-class TriggerAI : public NullCreatureAI
+class TC_GAME_API TriggerAI : public NullCreatureAI
{
public:
explicit TriggerAI(Creature* c) : NullCreatureAI(c) { }
diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp
index 8acf6b9c9dc..bbf4f4e02ce 100644
--- a/src/server/game/AI/CoreAI/PetAI.cpp
+++ b/src/server/game/AI/CoreAI/PetAI.cpp
@@ -150,14 +150,14 @@ void PetAI::UpdateAI(uint32 diff)
if (me->GetCharmInfo() && me->GetSpellHistory()->HasGlobalCooldown(spellInfo))
continue;
+ // check spell cooldown
+ if (!me->GetSpellHistory()->IsReady(spellInfo))
+ continue;
+
if (spellInfo->IsPositive())
{
if (spellInfo->CanBeUsedInCombat())
{
- // check spell cooldown & school lock
- if (!me->GetSpellHistory()->IsReady(spellInfo))
- continue;
-
// Check if we're in combat or commanded to attack
if (!me->IsInCombat() && !me->GetCharmInfo()->IsCommandAttack())
continue;
@@ -225,26 +225,17 @@ void PetAI::UpdateAI(uint32 diff)
//found units to cast on to
if (!targetSpellStore.empty())
{
- uint32 index = urand(0, targetSpellStore.size() - 1);
+ TargetSpellList::iterator it = targetSpellStore.begin();
+ std::advance(it, urand(0, targetSpellStore.size() - 1));
- Spell* spell = targetSpellStore[index].second;
- Unit* target = targetSpellStore[index].first;
+ Spell* spell = (*it).second;
+ Unit* target = (*it).first;
- targetSpellStore.erase(targetSpellStore.begin() + index);
+ targetSpellStore.erase(it);
SpellCastTargets targets;
targets.SetUnitTarget(target);
- if (!me->HasInArc(float(M_PI), target))
- {
- me->SetInFront(target);
- if (target && target->GetTypeId() == TYPEID_PLAYER)
- me->SendUpdateToPlayer(target->ToPlayer());
-
- if (owner && owner->GetTypeId() == TYPEID_PLAYER)
- me->SendUpdateToPlayer(owner->ToPlayer());
- }
-
spell->prepare(&targets);
}
diff --git a/src/server/game/AI/CoreAI/PetAI.h b/src/server/game/AI/CoreAI/PetAI.h
index 9c33baa9a9f..3ad34047b01 100644
--- a/src/server/game/AI/CoreAI/PetAI.h
+++ b/src/server/game/AI/CoreAI/PetAI.h
@@ -25,7 +25,7 @@
class Creature;
class Spell;
-class PetAI : public CreatureAI
+class TC_GAME_API PetAI : public CreatureAI
{
public:
diff --git a/src/server/game/AI/CoreAI/ReactorAI.h b/src/server/game/AI/CoreAI/ReactorAI.h
index e5abaac2f00..d281ca11fdf 100644
--- a/src/server/game/AI/CoreAI/ReactorAI.h
+++ b/src/server/game/AI/CoreAI/ReactorAI.h
@@ -23,7 +23,7 @@
class Unit;
-class ReactorAI : public CreatureAI
+class TC_GAME_API ReactorAI : public CreatureAI
{
public:
diff --git a/src/server/game/AI/CoreAI/TotemAI.h b/src/server/game/AI/CoreAI/TotemAI.h
index e1d1618037f..a0e796ed7e0 100644
--- a/src/server/game/AI/CoreAI/TotemAI.h
+++ b/src/server/game/AI/CoreAI/TotemAI.h
@@ -25,7 +25,7 @@
class Creature;
class Totem;
-class TotemAI : public CreatureAI
+class TC_GAME_API TotemAI : public CreatureAI
{
public:
diff --git a/src/server/game/AI/CoreAI/UnitAI.cpp b/src/server/game/AI/CoreAI/UnitAI.cpp
index a3a5e7f7663..844bd45ffeb 100644
--- a/src/server/game/AI/CoreAI/UnitAI.cpp
+++ b/src/server/game/AI/CoreAI/UnitAI.cpp
@@ -259,36 +259,6 @@ void UnitAI::FillAISpellInfo()
}
}
-//Enable PlayerAI when charmed
-void PlayerAI::OnCharmed(bool apply)
-{
- me->IsAIEnabled = apply;
-}
-
-void SimpleCharmedAI::UpdateAI(const uint32 /*diff*/)
-{
- Creature* charmer = me->GetCharmer()->ToCreature();
-
- //kill self if charm aura has infinite duration
- if (charmer->IsInEvadeMode())
- {
- Unit::AuraEffectList const& auras = me->GetAuraEffectsByType(SPELL_AURA_MOD_CHARM);
- for (Unit::AuraEffectList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter)
- if ((*iter)->GetCasterGUID() == charmer->GetGUID() && (*iter)->GetBase()->IsPermanent())
- {
- charmer->Kill(me);
- return;
- }
- }
-
- if (!charmer->IsInCombat())
- me->GetMotionMaster()->MoveFollow(charmer, PET_FOLLOW_DIST, me->GetFollowAngle());
-
- Unit* target = me->GetVictim();
- if (!target || !charmer->IsValidAttackTarget(target))
- AttackStart(charmer->SelectNearestTargetInAttackDistance());
-}
-
SpellTargetSelector::SpellTargetSelector(Unit* caster, uint32 spellId) :
_caster(caster), _spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(sSpellMgr->GetSpellInfo(spellId), caster))
{
@@ -340,5 +310,8 @@ bool NonTankTargetSelector::operator()(Unit const* target) const
if (_playerOnly && target->GetTypeId() != TYPEID_PLAYER)
return false;
+ if (HostileReference* currentVictim = _source->getThreatManager().getCurrentVictim())
+ return target->GetGUID() != currentVictim->getUnitGuid();
+
return target != _source->GetVictim();
}
diff --git a/src/server/game/AI/CoreAI/UnitAI.h b/src/server/game/AI/CoreAI/UnitAI.h
index 5dc5946b226..344ccc06249 100644
--- a/src/server/game/AI/CoreAI/UnitAI.h
+++ b/src/server/game/AI/CoreAI/UnitAI.h
@@ -40,7 +40,7 @@ enum SelectAggroTarget
};
// default predicate function to select target based on distance, player and/or aura criteria
-struct DefaultTargetSelector : public std::unary_function<Unit*, bool>
+struct TC_GAME_API DefaultTargetSelector : public std::unary_function<Unit*, bool>
{
const Unit* me;
float m_dist;
@@ -90,7 +90,7 @@ struct DefaultTargetSelector : public std::unary_function<Unit*, bool>
// Target selector for spell casts checking range, auras and attributes
/// @todo Add more checks from Spell::CheckCast
-struct SpellTargetSelector : public std::unary_function<Unit*, bool>
+struct TC_GAME_API SpellTargetSelector : public std::unary_function<Unit*, bool>
{
public:
SpellTargetSelector(Unit* caster, uint32 spellId);
@@ -104,18 +104,18 @@ struct SpellTargetSelector : public std::unary_function<Unit*, bool>
// Very simple target selector, will just skip main target
// NOTE: When passing to UnitAI::SelectTarget remember to use 0 as position for random selection
// because tank will not be in the temporary list
-struct NonTankTargetSelector : public std::unary_function<Unit*, bool>
+struct TC_GAME_API NonTankTargetSelector : public std::unary_function<Unit*, bool>
{
public:
- NonTankTargetSelector(Creature* source, bool playerOnly = true) : _source(source), _playerOnly(playerOnly) { }
+ NonTankTargetSelector(Unit* source, bool playerOnly = true) : _source(source), _playerOnly(playerOnly) { }
bool operator()(Unit const* target) const;
private:
- Creature const* _source;
+ Unit* _source;
bool _playerOnly;
};
-class UnitAI
+class TC_GAME_API UnitAI
{
protected:
Unit* const me;
@@ -268,21 +268,4 @@ class UnitAI
UnitAI& operator=(UnitAI const& right) = delete;
};
-class PlayerAI : public UnitAI
-{
- protected:
- Player* const me;
- public:
- explicit PlayerAI(Player* player) : UnitAI((Unit*)player), me(player) { }
-
- void OnCharmed(bool apply) override;
-};
-
-class SimpleCharmedAI : public PlayerAI
-{
- public:
- void UpdateAI(uint32 diff) override;
- SimpleCharmedAI(Player* player): PlayerAI(player) { }
-};
-
#endif
diff --git a/src/server/game/AI/CreatureAI.cpp b/src/server/game/AI/CreatureAI.cpp
index 352ae635878..5b76b583d24 100644
--- a/src/server/game/AI/CreatureAI.cpp
+++ b/src/server/game/AI/CreatureAI.cpp
@@ -283,7 +283,7 @@ bool CreatureAI::_EnterEvadeMode(EvadeReason /*why*/)
int32 CreatureAI::VisualizeBoundary(uint32 duration, Unit* owner, bool fill) const
{
typedef std::pair<int32, int32> coordinate;
-
+
if (!owner)
return -1;
@@ -293,7 +293,7 @@ int32 CreatureAI::VisualizeBoundary(uint32 duration, Unit* owner, bool fill) con
std::queue<coordinate> Q;
std::unordered_set<coordinate> alreadyChecked;
std::unordered_set<coordinate> outOfBounds;
-
+
Position startPosition = owner->GetPosition();
if (!CheckBoundary(&startPosition)) // fall back to creature position
{
diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h
index 239fda577a7..f175050e107 100644
--- a/src/server/game/AI/CreatureAI.h
+++ b/src/server/game/AI/CreatureAI.h
@@ -28,6 +28,7 @@ class WorldObject;
class Unit;
class Creature;
class Player;
+class PlayerAI;
class SpellInfo;
#define TIME_INTERVAL_LOOK 5000
@@ -65,7 +66,7 @@ enum SCEquip
};
typedef std::set<AreaBoundary const*> CreatureBoundary;
-class CreatureAI : public UnitAI
+class TC_GAME_API CreatureAI : public UnitAI
{
protected:
Creature* const me;
@@ -136,8 +137,8 @@ class CreatureAI : public UnitAI
virtual void AttackedBy(Unit* /*attacker*/) { }
virtual bool IsEscorted() const { return false; }
- // Called when creature is spawned or respawned (for reseting variables)
- virtual void JustRespawned() { Reset(); }
+ // Called when creature is spawned or respawned
+ virtual void JustRespawned() { }
// Called at waypoint reached or point movement finished
virtual void MovementInform(uint32 /*type*/, uint32 /*id*/) { }
@@ -186,6 +187,11 @@ class CreatureAI : public UnitAI
virtual bool CanSeeAlways(WorldObject const* /*obj*/) { return false; }
+ // Called when a player is charmed by the creature
+ // If a PlayerAI* is returned, that AI is placed on the player instead of the default charm AI
+ // Object destruction is handled by Unit::RemoveCharmedBy
+ virtual PlayerAI* GetAIForCharmedPlayer(Player* /*who*/) { return nullptr; }
+
// intended for encounter design/debugging. do not use for other purposes. expensive.
int32 VisualizeBoundary(uint32 duration, Unit* owner=nullptr, bool fill=false) const;
virtual bool CheckInRoom();
diff --git a/src/server/game/AI/CreatureAISelector.h b/src/server/game/AI/CreatureAISelector.h
index 7c7bc705ade..0e3be1a8604 100644
--- a/src/server/game/AI/CreatureAISelector.h
+++ b/src/server/game/AI/CreatureAISelector.h
@@ -27,9 +27,9 @@ class GameObject;
namespace FactorySelector
{
- CreatureAI* selectAI(Creature*);
- MovementGenerator* selectMovementGenerator(Creature*);
- GameObjectAI* SelectGameObjectAI(GameObject*);
+ TC_GAME_API CreatureAI* selectAI(Creature*);
+ TC_GAME_API MovementGenerator* selectMovementGenerator(Creature*);
+ TC_GAME_API GameObjectAI* SelectGameObjectAI(GameObject*);
}
#endif
diff --git a/src/server/game/AI/PlayerAI/PlayerAI.cpp b/src/server/game/AI/PlayerAI/PlayerAI.cpp
new file mode 100644
index 00000000000..680ecfb9414
--- /dev/null
+++ b/src/server/game/AI/PlayerAI/PlayerAI.cpp
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2016-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "PlayerAI.h"
+#include "SpellAuras.h"
+#include "SpellAuraEffects.h"
+
+enum Spells
+{
+ /* Generic */
+ SPELL_AUTO_SHOT = 75,
+ SPELL_SHOOT = 3018,
+ SPELL_THROW = 2764,
+ SPELL_SHOOT_WAND = 5019,
+
+ /* Paladin */
+ PASSIVE_ILLUMINATION = 20215,
+
+ /* Priest */
+ SPELL_SOUL_WARDING = 63574,
+ SPELL_SPIRIT_REDEMPTION = 20711,
+ SPELL_SHADOWFORM = 15473,
+
+ /* Shaman */
+ SPELL_TIDAL_FORCE = 582,
+ SPELL_MANA_TIDE_TOTEM = 590,
+ SPELL_SHA_NATURE_SWIFT = 591,
+ SPELL_STORMSTRIKE = 17364,
+
+ /* Druid */
+ SPELL_MOONKIN_FORM = 24858,
+ SPELL_SWIFTMEND = 18562,
+ SPELL_DRU_NATURE_SWIFT = 17116,
+ SPELL_TREE_OF_LIFE = 33891
+};
+
+bool PlayerAI::IsPlayerHealer(Player const* who)
+{
+ switch (who->getClass())
+ {
+ case CLASS_WARRIOR:
+ case CLASS_HUNTER:
+ case CLASS_ROGUE:
+ case CLASS_DEATH_KNIGHT:
+ case CLASS_MAGE:
+ case CLASS_WARLOCK:
+ default:
+ return false;
+ case CLASS_PALADIN:
+ return who->HasSpell(PASSIVE_ILLUMINATION);
+ case CLASS_PRIEST:
+ return who->HasSpell(SPELL_SOUL_WARDING) || who->HasSpell(SPELL_SPIRIT_REDEMPTION);
+ case CLASS_SHAMAN:
+ return who->HasSpell(SPELL_MANA_TIDE_TOTEM) || who->HasSpell(SPELL_SHA_NATURE_SWIFT) || who->HasSpell(SPELL_TIDAL_FORCE);
+ case CLASS_DRUID:
+ return who->HasSpell(SPELL_SWIFTMEND) || who->HasSpell(SPELL_DRU_NATURE_SWIFT) || who->HasSpell(SPELL_TREE_OF_LIFE);
+ }
+}
+
+bool PlayerAI::IsPlayerRangedAttacker(Player const* who)
+{
+ switch (who->getClass())
+ {
+ case CLASS_WARRIOR:
+ case CLASS_PALADIN:
+ case CLASS_ROGUE:
+ case CLASS_DEATH_KNIGHT:
+ default:
+ return false;
+ case CLASS_MAGE:
+ case CLASS_WARLOCK:
+ return true;
+ case CLASS_HUNTER:
+ {
+ // check if we have a ranged weapon equipped
+ Item const* rangedSlot = who->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED);
+ if (ItemTemplate const* rangedTemplate = rangedSlot ? rangedSlot->GetTemplate() : nullptr)
+ if ((1 << rangedTemplate->SubClass) & ITEM_SUBCLASS_MASK_WEAPON_RANGED)
+ return true;
+ return false;
+ }
+ case CLASS_PRIEST:
+ return who->HasSpell(SPELL_SHADOWFORM);
+ case CLASS_SHAMAN:
+ return !who->HasSpell(SPELL_STORMSTRIKE);
+ case CLASS_DRUID:
+ return who->HasSpell(SPELL_MOONKIN_FORM);
+ }
+}
+
+void PlayerAI::DoRangedAttackIfReady()
+{
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ if (!me->isAttackReady(RANGED_ATTACK))
+ return;
+
+ Unit* victim = me->GetVictim();
+ if (!victim)
+ return;
+
+ uint32 rangedAttackSpell = 0;
+
+ Item const* rangedItem = me->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED);
+ if (ItemTemplate const* rangedTemplate = rangedItem ? rangedItem->GetTemplate() : nullptr)
+ {
+ switch (rangedTemplate->SubClass)
+ {
+ case ITEM_SUBCLASS_WEAPON_BOW:
+ case ITEM_SUBCLASS_WEAPON_GUN:
+ case ITEM_SUBCLASS_WEAPON_CROSSBOW:
+ rangedAttackSpell = SPELL_SHOOT;
+ break;
+ case ITEM_SUBCLASS_WEAPON_THROWN:
+ rangedAttackSpell = SPELL_THROW;
+ break;
+ case ITEM_SUBCLASS_WEAPON_WAND:
+ rangedAttackSpell = SPELL_SHOOT_WAND;
+ break;
+ }
+ }
+
+ if (!rangedAttackSpell)
+ return;
+
+ me->CastSpell(victim, rangedAttackSpell, TRIGGERED_CAST_DIRECTLY);
+ me->resetAttackTimer(RANGED_ATTACK);
+}
+
+void PlayerAI::DoAutoAttackIfReady()
+{
+ if (IsRangedAttacker())
+ DoRangedAttackIfReady();
+ else
+ DoMeleeAttackIfReady();
+}
+
+struct UncontrolledTargetSelectPredicate : public std::unary_function<Unit*, bool>
+{
+ bool operator()(Unit const* target) const
+ {
+ return !target->HasBreakableByDamageCrowdControlAura();
+ }
+};
+Unit* SimpleCharmedPlayerAI::SelectAttackTarget() const
+{
+ if (Unit* charmer = me->GetCharmer())
+ return charmer->IsAIEnabled ? charmer->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0, UncontrolledTargetSelectPredicate()) : charmer->GetVictim();
+ return nullptr;
+}
+
+void SimpleCharmedPlayerAI::UpdateAI(const uint32 /*diff*/)
+{
+ Creature* charmer = me->GetCharmer() ? me->GetCharmer()->ToCreature() : nullptr;
+ if (!charmer)
+ return;
+
+ //kill self if charm aura has infinite duration
+ if (charmer->IsInEvadeMode())
+ {
+ Player::AuraEffectList const& auras = me->GetAuraEffectsByType(SPELL_AURA_MOD_CHARM);
+ for (Player::AuraEffectList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter)
+ if ((*iter)->GetCasterGUID() == charmer->GetGUID() && (*iter)->GetBase()->IsPermanent())
+ {
+ me->Kill(me);
+ return;
+ }
+ }
+
+ if (charmer->IsInCombat())
+ {
+ Unit* target = me->GetVictim();
+ if (!target || !charmer->IsValidAttackTarget(target) || target->HasBreakableByDamageCrowdControlAura())
+ {
+ target = SelectAttackTarget();
+ if (!target)
+ return;
+
+ if (IsRangedAttacker())
+ AttackStartCaster(target, 28.0f);
+ else
+ AttackStart(target);
+ }
+ DoAutoAttackIfReady();
+ }
+ else
+ {
+ me->AttackStop();
+ me->CastStop();
+ me->StopMoving();
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MoveFollow(charmer, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
+ }
+}
+
+void SimpleCharmedPlayerAI::OnCharmed(bool apply)
+{
+ if (apply)
+ {
+ me->CastStop();
+ me->AttackStop();
+ }
+ else
+ {
+ me->CastStop();
+ me->AttackStop();
+ // @todo only voluntary movement (don't cancel stuff like death grip or charge mid-animation)
+ me->GetMotionMaster()->Clear();
+ me->StopMoving();
+ }
+}
diff --git a/src/server/game/AI/PlayerAI/PlayerAI.h b/src/server/game/AI/PlayerAI/PlayerAI.h
new file mode 100644
index 00000000000..b717816f9a3
--- /dev/null
+++ b/src/server/game/AI/PlayerAI/PlayerAI.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2016-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TRINITY_PLAYERAI_H
+#define TRINITY_PLAYERAI_H
+
+#include "UnitAI.h"
+#include "Player.h"
+#include "Creature.h"
+
+class TC_GAME_API PlayerAI : public UnitAI
+{
+ public:
+ explicit PlayerAI(Player* player) : UnitAI(static_cast<Unit*>(player)), me(player), _isSelfHealer(PlayerAI::IsPlayerHealer(player)), _isSelfRangedAttacker(PlayerAI::IsPlayerRangedAttacker(player)) { }
+
+ void OnCharmed(bool /*apply*/) override { } // charm AI application for players is handled by Unit::SetCharmedBy / Unit::RemoveCharmedBy
+
+ // helper functions to determine player info
+ static bool IsPlayerHealer(Player const* who);
+ bool IsHealer(Player const* who = nullptr) const { return (!who || who == me) ? _isSelfHealer : IsPlayerHealer(who); }
+ static bool IsPlayerRangedAttacker(Player const* who);
+ bool IsRangedAttacker(Player const* who = nullptr) const { return (!who || who == me) ? _isSelfRangedAttacker : IsPlayerRangedAttacker(who); }
+
+ protected:
+ Player* const me;
+ void SetIsRangedAttacker(bool state) { _isSelfRangedAttacker = state; } // this allows overriding of the default ranged attacker detection
+
+ virtual Unit* SelectAttackTarget() const { return me->GetCharmer() ? me->GetCharmer()->GetVictim() : nullptr; }
+ void DoRangedAttackIfReady();
+ void DoAutoAttackIfReady();
+
+ private:
+ bool _isSelfHealer;
+ bool _isSelfRangedAttacker;
+};
+
+class SimpleCharmedPlayerAI : public PlayerAI
+{
+ public:
+ SimpleCharmedPlayerAI(Player* player) : PlayerAI(player) { }
+ void UpdateAI(uint32 diff) override;
+ void OnCharmed(bool apply) override;
+ Unit* SelectAttackTarget() const override;
+};
+
+#endif
diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
index 2fc87347364..6f04a852b61 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
@@ -566,7 +566,7 @@ void BossAI::_DespawnAtEvade(uint32 delayToRespawn)
me->SetCorpseDelay(corpseDelay);
me->SetRespawnDelay(respawnDelay);
- if(instance)
+ if (instance)
instance->SetBossState(_bossId, FAIL);
}
@@ -628,27 +628,27 @@ void WorldBossAI::UpdateAI(uint32 diff)
}
// SD2 grid searchers.
-Creature* GetClosestCreatureWithEntry(WorldObject* source, uint32 entry, float maxSearchRange, bool alive /*= true*/)
+TC_GAME_API Creature* GetClosestCreatureWithEntry(WorldObject* source, uint32 entry, float maxSearchRange, bool alive /*= true*/)
{
return source->FindNearestCreature(entry, maxSearchRange, alive);
}
-GameObject* GetClosestGameObjectWithEntry(WorldObject* source, uint32 entry, float maxSearchRange)
+TC_GAME_API GameObject* GetClosestGameObjectWithEntry(WorldObject* source, uint32 entry, float maxSearchRange)
{
return source->FindNearestGameObject(entry, maxSearchRange);
}
-void GetCreatureListWithEntryInGrid(std::list<Creature*>& list, WorldObject* source, uint32 entry, float maxSearchRange)
+TC_GAME_API void GetCreatureListWithEntryInGrid(std::list<Creature*>& list, WorldObject* source, uint32 entry, float maxSearchRange)
{
source->GetCreatureListWithEntryInGrid(list, entry, maxSearchRange);
}
-void GetGameObjectListWithEntryInGrid(std::list<GameObject*>& list, WorldObject* source, uint32 entry, float maxSearchRange)
+TC_GAME_API void GetGameObjectListWithEntryInGrid(std::list<GameObject*>& list, WorldObject* source, uint32 entry, float maxSearchRange)
{
source->GetGameObjectListWithEntryInGrid(list, entry, maxSearchRange);
}
-void GetPlayerListInGrid(std::list<Player*>& list, WorldObject* source, float maxSearchRange)
+TC_GAME_API void GetPlayerListInGrid(std::list<Player*>& list, WorldObject* source, float maxSearchRange)
{
source->GetPlayerListInGrid(list, maxSearchRange);
}
diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h
index 5452a033a17..42befa26a23 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h
+++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h
@@ -38,7 +38,7 @@ T* EnsureAI(U* ai)
class InstanceScript;
-class SummonList
+class TC_GAME_API SummonList
{
public:
typedef GuidList StorageType;
@@ -123,7 +123,7 @@ private:
StorageType storage_;
};
-class EntryCheckPredicate
+class TC_GAME_API EntryCheckPredicate
{
public:
EntryCheckPredicate(uint32 entry) : _entry(entry) { }
@@ -133,13 +133,13 @@ class EntryCheckPredicate
uint32 _entry;
};
-class DummyEntryCheckPredicate
+class TC_GAME_API DummyEntryCheckPredicate
{
public:
bool operator()(ObjectGuid) { return true; }
};
-struct ScriptedAI : public CreatureAI
+struct TC_GAME_API ScriptedAI : public CreatureAI
{
explicit ScriptedAI(Creature* creature);
virtual ~ScriptedAI() { }
@@ -334,7 +334,7 @@ struct ScriptedAI : public CreatureAI
bool _isHeroic;
};
-class BossAI : public ScriptedAI
+class TC_GAME_API BossAI : public ScriptedAI
{
public:
BossAI(Creature* creature, uint32 bossId);
@@ -379,7 +379,7 @@ class BossAI : public ScriptedAI
uint32 const _bossId;
};
-class WorldBossAI : public ScriptedAI
+class TC_GAME_API WorldBossAI : public ScriptedAI
{
public:
WorldBossAI(Creature* creature);
@@ -410,10 +410,10 @@ class WorldBossAI : public ScriptedAI
};
// SD2 grid searchers.
-Creature* GetClosestCreatureWithEntry(WorldObject* source, uint32 entry, float maxSearchRange, bool alive = true);
-GameObject* GetClosestGameObjectWithEntry(WorldObject* source, uint32 entry, float maxSearchRange);
-void GetCreatureListWithEntryInGrid(std::list<Creature*>& list, WorldObject* source, uint32 entry, float maxSearchRange);
-void GetGameObjectListWithEntryInGrid(std::list<GameObject*>& list, WorldObject* source, uint32 entry, float maxSearchRange);
-void GetPlayerListInGrid(std::list<Player*>& list, WorldObject* source, float maxSearchRange);
+TC_GAME_API Creature* GetClosestCreatureWithEntry(WorldObject* source, uint32 entry, float maxSearchRange, bool alive = true);
+TC_GAME_API GameObject* GetClosestGameObjectWithEntry(WorldObject* source, uint32 entry, float maxSearchRange);
+TC_GAME_API void GetCreatureListWithEntryInGrid(std::list<Creature*>& list, WorldObject* source, uint32 entry, float maxSearchRange);
+TC_GAME_API void GetGameObjectListWithEntryInGrid(std::list<GameObject*>& list, WorldObject* source, uint32 entry, float maxSearchRange);
+TC_GAME_API void GetPlayerListInGrid(std::list<Player*>& list, WorldObject* source, float maxSearchRange);
#endif // SCRIPTEDCREATURE_H_
diff --git a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp
index 68cb8d346d0..fa80634e0f0 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp
@@ -105,7 +105,7 @@ bool npc_escortAI::AssistPlayerInCombat(Unit* who)
void npc_escortAI::MoveInLineOfSight(Unit* who)
{
- if (!me->HasUnitState(UNIT_STATE_STUNNED) && who->isTargetableForAttack() && who->isInAccessiblePlaceFor(me))
+ if (me->HasReactState(REACT_AGGRESSIVE) && !me->HasUnitState(UNIT_STATE_STUNNED) && who->isTargetableForAttack() && who->isInAccessiblePlaceFor(me))
{
if (HasEscortState(STATE_ESCORT_ESCORTING) && AssistPlayerInCombat(who))
return;
diff --git a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h
index 673f3e671a0..37a1464d812 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h
+++ b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h
@@ -49,7 +49,7 @@ enum eEscortState
STATE_ESCORT_PAUSED = 0x004 //will not proceed with waypoints before state is removed
};
-struct npc_escortAI : public ScriptedAI
+struct TC_GAME_API npc_escortAI : public ScriptedAI
{
public:
explicit npc_escortAI(Creature* creature);
diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
index dc9f6d2681e..778edf8cab5 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
@@ -102,7 +102,7 @@ bool FollowerAI::AssistPlayerInCombat(Unit* who)
void FollowerAI::MoveInLineOfSight(Unit* who)
{
- if (!me->HasUnitState(UNIT_STATE_STUNNED) && who->isTargetableForAttack() && who->isInAccessiblePlaceFor(me))
+ if (me->HasReactState(REACT_AGGRESSIVE) && !me->HasUnitState(UNIT_STATE_STUNNED) && who->isTargetableForAttack() && who->isInAccessiblePlaceFor(me))
{
if (HasFollowState(STATE_FOLLOW_INPROGRESS) && AssistPlayerInCombat(who))
return;
diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h
index d1c976b45c8..e17fb7c8507 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h
+++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h
@@ -32,7 +32,7 @@ enum eFollowState
STATE_FOLLOW_POSTEVENT = 0x020 //can be set at complete and allow post event to run
};
-class FollowerAI : public ScriptedAI
+class TC_GAME_API FollowerAI : public ScriptedAI
{
public:
explicit FollowerAI(Creature* creature);
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp
index eca327e770e..361bb1a5b1d 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.cpp
+++ b/src/server/game/AI/SmartScripts/SmartAI.cpp
@@ -466,6 +466,9 @@ bool SmartAI::CanAIAttack(const Unit* /*who*/) const
bool SmartAI::AssistPlayerInCombat(Unit* who)
{
+ if (me->HasReactState(REACT_PASSIVE))
+ return false;
+
if (!who || !who->GetVictim())
return false;
diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h
index 02c057247f6..aa7c9ace0b3 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.h
+++ b/src/server/game/AI/SmartScripts/SmartAI.h
@@ -42,7 +42,7 @@ enum SmartEscortVars
SMART_MAX_AID_DIST = SMART_ESCORT_MAX_PLAYER_DIST / 2
};
-class SmartAI : public CreatureAI
+class TC_GAME_API SmartAI : public CreatureAI
{
public:
~SmartAI(){ }
@@ -230,7 +230,7 @@ class SmartAI : public CreatureAI
bool mJustReset;
};
-class SmartGameObjectAI : public GameObjectAI
+class TC_GAME_API SmartGameObjectAI : public GameObjectAI
{
public:
SmartGameObjectAI(GameObject* g) : GameObjectAI(g) { }
@@ -257,4 +257,8 @@ class SmartGameObjectAI : public GameObjectAI
private:
SmartScript mScript;
};
+
+/// Registers scripts required by the SAI scripting system
+void AddSC_SmartScripts();
+
#endif
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index c08d1508774..859282891fb 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -2330,6 +2330,21 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
break;
}
}
+ case SMART_ACTION_SET_CORPSE_DELAY:
+ {
+ ObjectList* targets = GetTargets(e, unit);
+ if (!targets)
+ break;
+
+ for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ {
+ if (IsCreature(*itr))
+ (*itr)->ToCreature()->SetCorpseDelay(e.action.corpseDelay.timer);
+ }
+
+ delete targets;
+ break;
+ }
default:
TC_LOG_ERROR("sql.sql", "SmartScript::ProcessAction: Entry %d SourceType %u, Event %u, Unhandled Action type %u", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
break;
diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h
index e8b89a813b5..a28f2234860 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.h
+++ b/src/server/game/AI/SmartScripts/SmartScript.h
@@ -28,7 +28,7 @@
#include "SmartScriptMgr.h"
//#include "SmartAI.h"
-class SmartScript
+class TC_GAME_API SmartScript
{
public:
SmartScript();
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
index ef3357fa6ed..ba1738a523b 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
@@ -27,6 +27,12 @@
#include "SmartScriptMgr.h"
+SmartWaypointMgr* SmartWaypointMgr::instance()
+{
+ static SmartWaypointMgr instance;
+ return &instance;
+}
+
void SmartWaypointMgr::LoadFromDB()
{
uint32 oldMSTime = getMSTime();
@@ -98,6 +104,12 @@ SmartWaypointMgr::~SmartWaypointMgr()
}
}
+SmartAIMgr* SmartAIMgr::instance()
+{
+ static SmartAIMgr instance;
+ return &instance;
+}
+
void SmartAIMgr::LoadSmartAIFromDB()
{
LoadHelperStores();
@@ -1214,6 +1226,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
case SMART_ACTION_REMOVE_GO_FLAG:
case SMART_ACTION_SUMMON_CREATURE_GROUP:
case SMART_ACTION_RISE_UP:
+ case SMART_ACTION_SET_CORPSE_DELAY:
break;
default:
TC_LOG_ERROR("sql.sql", "SmartAIMgr: Not handled action_type(%u), event_type(%u), Entry %d SourceType %u Event %u, skipped.", e.GetActionType(), e.GetEventType(), e.entryOrGuid, e.GetScriptType(), e.event_id);
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
index c0ea648462d..3105f087bf7 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
@@ -551,8 +551,9 @@ enum SMART_ACTION
SMART_ACTION_START_CLOSEST_WAYPOINT = 113, // wp1, wp2, wp3, wp4, wp5, wp6, wp7
SMART_ACTION_RISE_UP = 114, // distance
SMART_ACTION_RANDOM_SOUND = 115, // soundId1, soundId2, soundId3, soundId4, soundId5, onlySelf
+ SMART_ACTION_SET_CORPSE_DELAY = 116, // timer
- SMART_ACTION_END = 116
+ SMART_ACTION_END = 117
};
struct SmartAction
@@ -1034,6 +1035,11 @@ struct SmartAction
uint32 onlySelf;
} randomSound;
+ struct
+ {
+ uint32 timer;
+ } corpseDelay;
+
//! Note for any new future actions
//! All parameters must have type uint32
@@ -1434,18 +1440,14 @@ public:
};
typedef std::unordered_map<uint32, ObjectGuidList*> ObjectListMap;
-class SmartWaypointMgr
+class TC_GAME_API SmartWaypointMgr
{
private:
SmartWaypointMgr() { }
~SmartWaypointMgr();
public:
- static SmartWaypointMgr* instance()
- {
- static SmartWaypointMgr instance;
- return &instance;
- }
+ static SmartWaypointMgr* instance();
void LoadFromDB();
@@ -1470,18 +1472,14 @@ typedef std::unordered_map<int32, SmartAIEventList> SmartAIEventMap;
typedef std::map<uint32 /*entry*/, std::pair<uint32 /*spellId*/, SpellEffIndex /*effIndex*/> > CacheSpellContainer;
typedef std::pair<CacheSpellContainer::const_iterator, CacheSpellContainer::const_iterator> CacheSpellContainerBounds;
-class SmartAIMgr
+class TC_GAME_API SmartAIMgr
{
private:
SmartAIMgr() { }
~SmartAIMgr() { }
public:
- static SmartAIMgr* instance()
- {
- static SmartAIMgr instance;
- return &instance;
- }
+ static SmartAIMgr* instance();
void LoadSmartAIFromDB();
diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp
index 737e9f37195..1b93d072fb6 100644
--- a/src/server/game/Accounts/AccountMgr.cpp
+++ b/src/server/game/Accounts/AccountMgr.cpp
@@ -33,17 +33,23 @@ AccountMgr::~AccountMgr()
ClearRBAC();
}
-AccountOpResult AccountMgr::CreateAccount(std::string username, std::string password, std::string email = "")
+AccountMgr* AccountMgr::instance()
+{
+ static AccountMgr instance;
+ return &instance;
+}
+
+AccountOpResult AccountMgr::CreateAccount(std::string username, std::string password, std::string email /*= ""*/)
{
if (utf8length(username) > MAX_ACCOUNT_STR)
- return AOR_NAME_TOO_LONG; // username's too long
+ return AccountOpResult::AOR_NAME_TOO_LONG; // username's too long
- normalizeString(username);
- normalizeString(password);
- normalizeString(email);
+ Utf8ToUpperOnlyLatin(username);
+ Utf8ToUpperOnlyLatin(password);
+ Utf8ToUpperOnlyLatin(email);
if (GetId(username))
- return AOR_NAME_ALREADY_EXIST; // username does already exist
+ return AccountOpResult::AOR_NAME_ALREADY_EXIST; // username does already exist
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_ACCOUNT);
@@ -57,7 +63,7 @@ AccountOpResult AccountMgr::CreateAccount(std::string username, std::string pass
stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_REALM_CHARACTERS_INIT);
LoginDatabase.Execute(stmt);
- return AOR_OK; // everything's fine
+ return AccountOpResult::AOR_OK; // everything's fine
}
AccountOpResult AccountMgr::DeleteAccount(uint32 accountId)
@@ -68,7 +74,7 @@ AccountOpResult AccountMgr::DeleteAccount(uint32 accountId)
PreparedQueryResult result = LoginDatabase.Query(stmt);
if (!result)
- return AOR_NAME_NOT_EXIST;
+ return AccountOpResult::AOR_NAME_NOT_EXIST;
// Obtain accounts characters
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARS_BY_ACCOUNT_ID);
@@ -128,7 +134,7 @@ AccountOpResult AccountMgr::DeleteAccount(uint32 accountId)
LoginDatabase.CommitTransaction(trans);
- return AOR_OK;
+ return AccountOpResult::AOR_OK;
}
AccountOpResult AccountMgr::ChangeUsername(uint32 accountId, std::string newUsername, std::string newPassword)
@@ -139,16 +145,16 @@ AccountOpResult AccountMgr::ChangeUsername(uint32 accountId, std::string newUser
PreparedQueryResult result = LoginDatabase.Query(stmt);
if (!result)
- return AOR_NAME_NOT_EXIST;
+ return AccountOpResult::AOR_NAME_NOT_EXIST;
if (utf8length(newUsername) > MAX_ACCOUNT_STR)
- return AOR_NAME_TOO_LONG;
+ return AccountOpResult::AOR_NAME_TOO_LONG;
- if (utf8length(newPassword) > MAX_ACCOUNT_STR)
- return AOR_PASS_TOO_LONG;
+ if (utf8length(newPassword) > MAX_PASS_STR)
+ return AccountOpResult::AOR_PASS_TOO_LONG;
- normalizeString(newUsername);
- normalizeString(newPassword);
+ Utf8ToUpperOnlyLatin(newUsername);
+ Utf8ToUpperOnlyLatin(newPassword);
stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_USERNAME);
@@ -158,7 +164,7 @@ AccountOpResult AccountMgr::ChangeUsername(uint32 accountId, std::string newUser
LoginDatabase.Execute(stmt);
- return AOR_OK;
+ return AccountOpResult::AOR_OK;
}
AccountOpResult AccountMgr::ChangePassword(uint32 accountId, std::string newPassword)
@@ -168,17 +174,17 @@ AccountOpResult AccountMgr::ChangePassword(uint32 accountId, std::string newPass
if (!GetName(accountId, username))
{
sScriptMgr->OnFailedPasswordChange(accountId);
- return AOR_NAME_NOT_EXIST; // account doesn't exist
+ return AccountOpResult::AOR_NAME_NOT_EXIST; // account doesn't exist
}
- if (utf8length(newPassword) > MAX_ACCOUNT_STR)
+ if (utf8length(newPassword) > MAX_PASS_STR)
{
sScriptMgr->OnFailedPasswordChange(accountId);
- return AOR_PASS_TOO_LONG;
+ return AccountOpResult::AOR_PASS_TOO_LONG;
}
- normalizeString(username);
- normalizeString(newPassword);
+ Utf8ToUpperOnlyLatin(username);
+ Utf8ToUpperOnlyLatin(newPassword);
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_PASSWORD);
@@ -196,7 +202,7 @@ AccountOpResult AccountMgr::ChangePassword(uint32 accountId, std::string newPass
LoginDatabase.Execute(stmt);
sScriptMgr->OnPasswordChange(accountId);
- return AOR_OK;
+ return AccountOpResult::AOR_OK;
}
AccountOpResult AccountMgr::ChangeEmail(uint32 accountId, std::string newEmail)
@@ -206,17 +212,17 @@ AccountOpResult AccountMgr::ChangeEmail(uint32 accountId, std::string newEmail)
if (!GetName(accountId, username))
{
sScriptMgr->OnFailedEmailChange(accountId);
- return AOR_NAME_NOT_EXIST; // account doesn't exist
+ return AccountOpResult::AOR_NAME_NOT_EXIST; // account doesn't exist
}
if (utf8length(newEmail) > MAX_EMAIL_STR)
{
sScriptMgr->OnFailedEmailChange(accountId);
- return AOR_EMAIL_TOO_LONG;
+ return AccountOpResult::AOR_EMAIL_TOO_LONG;
}
- normalizeString(username);
- normalizeString(newEmail);
+ Utf8ToUpperOnlyLatin(username);
+ Utf8ToUpperOnlyLatin(newEmail);
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_EMAIL);
@@ -226,7 +232,7 @@ AccountOpResult AccountMgr::ChangeEmail(uint32 accountId, std::string newEmail)
LoginDatabase.Execute(stmt);
sScriptMgr->OnEmailChange(accountId);
- return AOR_OK;
+ return AccountOpResult::AOR_OK;
}
AccountOpResult AccountMgr::ChangeRegEmail(uint32 accountId, std::string newEmail)
@@ -236,17 +242,17 @@ AccountOpResult AccountMgr::ChangeRegEmail(uint32 accountId, std::string newEmai
if (!GetName(accountId, username))
{
sScriptMgr->OnFailedEmailChange(accountId);
- return AOR_NAME_NOT_EXIST; // account doesn't exist
+ return AccountOpResult::AOR_NAME_NOT_EXIST; // account doesn't exist
}
if (utf8length(newEmail) > MAX_EMAIL_STR)
{
sScriptMgr->OnFailedEmailChange(accountId);
- return AOR_EMAIL_TOO_LONG;
+ return AccountOpResult::AOR_EMAIL_TOO_LONG;
}
- normalizeString(username);
- normalizeString(newEmail);
+ Utf8ToUpperOnlyLatin(username);
+ Utf8ToUpperOnlyLatin(newEmail);
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_REG_EMAIL);
@@ -256,7 +262,7 @@ AccountOpResult AccountMgr::ChangeRegEmail(uint32 accountId, std::string newEmai
LoginDatabase.Execute(stmt);
sScriptMgr->OnEmailChange(accountId);
- return AOR_OK;
+ return AccountOpResult::AOR_OK;
}
uint32 AccountMgr::GetId(std::string const& username)
@@ -324,8 +330,8 @@ bool AccountMgr::CheckPassword(uint32 accountId, std::string password)
if (!GetName(accountId, username))
return false;
- normalizeString(username);
- normalizeString(password);
+ Utf8ToUpperOnlyLatin(username);
+ Utf8ToUpperOnlyLatin(password);
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_CHECK_PASSWORD);
stmt->setUInt32(0, accountId);
@@ -343,8 +349,8 @@ bool AccountMgr::CheckEmail(uint32 accountId, std::string newEmail)
if (!GetEmail(accountId, oldEmail))
return false;
- normalizeString(oldEmail);
- normalizeString(newEmail);
+ Utf8ToUpperOnlyLatin(oldEmail);
+ Utf8ToUpperOnlyLatin(newEmail);
if (strcmp(oldEmail.c_str(), newEmail.c_str()) == 0)
return true;
@@ -362,19 +368,6 @@ uint32 AccountMgr::GetCharactersCount(uint32 accountId)
return (result) ? (*result)[0].GetUInt64() : 0;
}
-bool AccountMgr::normalizeString(std::string& utf8String)
-{
- wchar_t buffer[MAX_ACCOUNT_STR+1];
-
- size_t maxLength = MAX_ACCOUNT_STR;
- if (!Utf8toWStr(utf8String, buffer, maxLength))
- return false;
-
- std::transform(&buffer[0], buffer+maxLength, &buffer[0], wcharToUpperOnlyLatin);
-
- return WStrToUtf8(buffer, maxLength, utf8String);
-}
-
std::string AccountMgr::CalculateShaPassHash(std::string const& name, std::string const& password)
{
SHA1Hash sha;
@@ -462,7 +455,7 @@ void AccountMgr::LoadRBAC()
while (result->NextRow());
TC_LOG_DEBUG("rbac", "AccountMgr::LoadRBAC: Loading default permissions");
- result = LoginDatabase.PQuery("SELECT secId, permissionId FROM rbac_default_permissions WHERE (realmId = %u OR realmId = -1) ORDER BY secId ASC", realmID);
+ result = LoginDatabase.PQuery("SELECT secId, permissionId FROM rbac_default_permissions WHERE (realmId = %u OR realmId = -1) ORDER BY secId ASC", realm.Id.Realm);
if (!result)
{
TC_LOG_INFO("server.loading", ">> Loaded 0 default permission definitions. DB table `rbac_default_permissions` is empty.");
diff --git a/src/server/game/Accounts/AccountMgr.h b/src/server/game/Accounts/AccountMgr.h
index 40ccba1f8e5..f3bb1abe64e 100644
--- a/src/server/game/Accounts/AccountMgr.h
+++ b/src/server/game/Accounts/AccountMgr.h
@@ -21,7 +21,7 @@
#include "RBAC.h"
-enum AccountOpResult
+enum class AccountOpResult : uint8
{
AOR_OK,
AOR_NAME_TOO_LONG,
@@ -39,6 +39,7 @@ enum PasswordChangeSecurity
PW_RBAC
};
+#define MAX_PASS_STR 16
#define MAX_ACCOUNT_STR 16
#define MAX_EMAIL_STR 64
@@ -48,20 +49,16 @@ typedef std::map<uint32, rbac::RBACPermission*> RBACPermissionsContainer;
typedef std::map<uint8, rbac::RBACPermissionContainer> RBACDefaultPermissionsContainer;
}
-class AccountMgr
+class TC_GAME_API AccountMgr
{
private:
AccountMgr();
~AccountMgr();
public:
- static AccountMgr* instance()
- {
- static AccountMgr instance;
- return &instance;
- }
+ static AccountMgr* instance();
- AccountOpResult CreateAccount(std::string username, std::string password, std::string email);
+ AccountOpResult CreateAccount(std::string username, std::string password, std::string email = "");
static AccountOpResult DeleteAccount(uint32 accountId);
static AccountOpResult ChangeUsername(uint32 accountId, std::string newUsername, std::string newPassword);
static AccountOpResult ChangePassword(uint32 accountId, std::string newPassword);
@@ -78,7 +75,6 @@ class AccountMgr
static uint32 GetCharactersCount(uint32 accountId);
static std::string CalculateShaPassHash(std::string const& name, std::string const& password);
- static bool normalizeString(std::string& utf8String);
static bool IsPlayerAccount(uint32 gmlevel);
static bool IsAdminAccount(uint32 gmlevel);
static bool IsConsoleAccount(uint32 gmlevel);
diff --git a/src/server/game/Accounts/RBAC.cpp b/src/server/game/Accounts/RBAC.cpp
index a8720b66df4..34d7687452c 100644
--- a/src/server/game/Accounts/RBAC.cpp
+++ b/src/server/game/Accounts/RBAC.cpp
@@ -236,10 +236,10 @@ void RBACData::AddPermissions(RBACPermissionContainer const& permsFrom, RBACPerm
permsTo.insert(*itr);
}
-void RBACData::RemovePermissions(RBACPermissionContainer const& permsFrom, RBACPermissionContainer& permsTo)
+void RBACData::RemovePermissions(RBACPermissionContainer& permsFrom, RBACPermissionContainer const& permsToRemove)
{
- for (RBACPermissionContainer::const_iterator itr = permsFrom.begin(); itr != permsFrom.end(); ++itr)
- permsTo.erase(*itr);
+ for (RBACPermissionContainer::const_iterator itr = permsToRemove.begin(); itr != permsToRemove.end(); ++itr)
+ permsFrom.erase(*itr);
}
void RBACData::ExpandPermissions(RBACPermissionContainer& permissions)
diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h
index 4ebd3ae7042..5f883175157 100644
--- a/src/server/game/Accounts/RBAC.h
+++ b/src/server/game/Accounts/RBAC.h
@@ -670,8 +670,8 @@ enum RBACPermissions
RBAC_PERM_COMMAND_WP_UNLOAD = 772,
RBAC_PERM_COMMAND_WP_RELOAD = 773,
RBAC_PERM_COMMAND_WP_SHOW = 774,
- RBAC_PERM_COMMAND_MODIFY_CURRENCY = 775, // only 4.3.4
- RBAC_PERM_COMMAND_DEBUG_PHASE = 776, // only 4.3.4
+ RBAC_PERM_COMMAND_MODIFY_CURRENCY = 775, // only 6.x
+ RBAC_PERM_COMMAND_DEBUG_PHASE = 776, // only 6.x
RBAC_PERM_COMMAND_MAILBOX = 777,
RBAC_PERM_COMMAND_AHBOT = 778,
RBAC_PERM_COMMAND_AHBOT_ITEMS = 779,
@@ -714,7 +714,7 @@ enum RBACCommandResult
typedef std::set<uint32> RBACPermissionContainer;
-class RBACPermission
+class TC_GAME_API RBACPermission
{
public:
RBACPermission(uint32 id = 0, std::string const& name = ""):
@@ -749,7 +749,7 @@ class RBACPermission
* - Granted permissions: through linked permissions and directly assigned
* - Denied permissions: through linked permissions and directly assigned
*/
-class RBACData
+class TC_GAME_API RBACData
{
public:
RBACData(uint32 id, std::string const& name, int32 realmId, uint8 secLevel = 255):
@@ -938,8 +938,8 @@ class RBACData
/// Adds a list of permissions to another list
void AddPermissions(RBACPermissionContainer const& permsFrom, RBACPermissionContainer& permsTo);
- /// Removes a list of permissions to another list
- void RemovePermissions(RBACPermissionContainer const& permsFrom, RBACPermissionContainer& permsTo);
+ /// Removes a list of permissions from another list
+ void RemovePermissions(RBACPermissionContainer& permsFrom, RBACPermissionContainer const& permsToRemove);
/**
* @name ExpandPermissions
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp
index ac8e0298a44..ebc814405bf 100644
--- a/src/server/game/Achievements/AchievementMgr.cpp
+++ b/src/server/game/Achievements/AchievementMgr.cpp
@@ -46,7 +46,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
{
if (dataType >= MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE)
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` for criteria (Entry: %u) has wrong data type (%u), ignored.", criteria->ID, dataType);
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` for criteria (Entry: %u) contains a wrong data type (%u), ignored.", criteria->ID, dataType);
return false;
}
@@ -81,7 +81,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
default:
if (dataType != ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT)
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` has data for non-supported criteria type (Entry: %u Type: %u), ignored.", criteria->ID, criteria->requiredType);
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` contains data for a non-supported criteria type (Entry: %u Type: %u), ignored.", criteria->ID, criteria->requiredType);
return false;
}
break;
@@ -96,7 +96,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_CREATURE:
if (!creature.id || !sObjectMgr->GetCreatureTemplate(creature.id))
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_CREATURE (%u) has non-existing creature id in value1 (%u), ignored.",
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_CREATURE (%u) contains a non-existing creature id in value1 (%u), ignored.",
criteria->ID, criteria->requiredType, dataType, creature.id);
return false;
}
@@ -104,13 +104,13 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE:
if (classRace.class_id && ((1 << (classRace.class_id-1)) & CLASSMASK_ALL_PLAYABLE) == 0)
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE (%u) has non-existing class in value1 (%u), ignored.",
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE (%u) contains a non-existing class in value1 (%u), ignored.",
criteria->ID, criteria->requiredType, dataType, classRace.class_id);
return false;
}
if (classRace.race_id && ((1 << (classRace.race_id-1)) & RACEMASK_ALL_PLAYABLE) == 0)
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE (%u) has non-existing race in value2 (%u), ignored.",
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE (%u) contains a non-existing race in value2 (%u), ignored.",
criteria->ID, criteria->requiredType, dataType, classRace.race_id);
return false;
}
@@ -118,7 +118,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_LESS_HEALTH:
if (health.percent < 1 || health.percent > 100)
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_LESS_HEALTH (%u) has wrong percent value in value1 (%u), ignored.",
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_LESS_HEALTH (%u) contains a wrong percent value in value1 (%u), ignored.",
criteria->ID, criteria->requiredType, dataType, health.percent);
return false;
}
@@ -126,7 +126,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD:
if (player_dead.own_team_flag > 1)
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD (%u) has wrong boolean value1 (%u).",
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD (%u) contains a wrong boolean value1 (%u).",
criteria->ID, criteria->requiredType, dataType, player_dead.own_team_flag);
return false;
}
@@ -137,19 +137,19 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(aura.spell_id);
if (!spellEntry)
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type %s (%u) has wrong spell id in value1 (%u), ignored.",
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type %s (%u) contains a wrong spell id in value1 (%u), ignored.",
criteria->ID, criteria->requiredType, (dataType == ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA?"ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA":"ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"), dataType, aura.spell_id);
return false;
}
if (aura.effect_idx >= 3)
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type %s (%u) has wrong spell effect index in value2 (%u), ignored.",
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type %s (%u) contains a wrong spell effect index in value2 (%u), ignored.",
criteria->ID, criteria->requiredType, (dataType == ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA?"ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA":"ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"), dataType, aura.effect_idx);
return false;
}
if (!spellEntry->Effects[aura.effect_idx].ApplyAuraName)
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type %s (%u) has non-aura spell effect (ID: %u Effect: %u), ignores.",
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type %s (%u) contains a non-aura spell effect (ID: %u Effect: %u), ignored.",
criteria->ID, criteria->requiredType, (dataType == ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA?"ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA":"ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"), dataType, aura.spell_id, aura.effect_idx);
return false;
}
@@ -158,7 +158,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA:
if (!sAreaTableStore.LookupEntry(area.id))
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA (%u) has wrong area id in value1 (%u), ignored.",
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA (%u) contains a wrong area id in value1 (%u), ignored.",
criteria->ID, criteria->requiredType, dataType, area.id);
return false;
}
@@ -166,7 +166,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
case ACHIEVEMENT_CRITERIA_DATA_TYPE_VALUE:
if (value.compType >= COMP_TYPE_MAX)
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_VALUE (%u) has wrong ComparisionType in value2 (%u), ignored.",
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_VALUE (%u) contains a wrong ComparisionType in value2 (%u), ignored.",
criteria->ID, criteria->requiredType, dataType, value.compType);
return false;
}
@@ -174,7 +174,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_LEVEL:
if (level.minlevel > STRONG_MAX_LEVEL)
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_LEVEL (%u) has wrong minlevel in value1 (%u), ignored.",
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_LEVEL (%u) contains a wrong minlevel in value1 (%u), ignored.",
criteria->ID, criteria->requiredType, dataType, level.minlevel);
return false;
}
@@ -182,7 +182,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_GENDER:
if (gender.gender > GENDER_NONE)
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_GENDER (%u) has wrong gender in value1 (%u), ignored.",
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_GENDER (%u) contains a wrong gender value in value1 (%u), ignored.",
criteria->ID, criteria->requiredType, dataType, gender.gender);
return false;
}
@@ -190,7 +190,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
case ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT:
if (!ScriptId)
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT (%u) does not have ScriptName set, ignored.",
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT (%u) does not have a ScriptName set, ignored.",
criteria->ID, criteria->requiredType, dataType);
return false;
}
@@ -198,7 +198,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY:
if (difficulty.difficulty >= MAX_DIFFICULTY)
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY (%u) has wrong difficulty in value1 (%u), ignored.",
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY (%u) contains a wrong difficulty value in value1 (%u), ignored.",
criteria->ID, criteria->requiredType, dataType, difficulty.difficulty);
return false;
}
@@ -206,7 +206,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT:
if (map_players.maxcount <= 0)
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT (%u) has wrong max players count in value1 (%u), ignored.",
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT (%u) contains a wrong max players count in value1 (%u), ignored.",
criteria->ID, criteria->requiredType, dataType, map_players.maxcount);
return false;
}
@@ -214,7 +214,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM:
if (team.team != ALLIANCE && team.team != HORDE)
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM (%u) has unknown team in value1 (%u), ignored.",
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM (%u) contains an unknown team value in value1 (%u), ignored.",
criteria->ID, criteria->requiredType, dataType, team.team);
return false;
}
@@ -222,7 +222,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_DRUNK:
if (drunk.state >= MAX_DRUNKEN)
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_DRUNK (%u) has unknown drunken state in value1 (%u), ignored.",
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_DRUNK (%u) contains an unknown drunken state value in value1 (%u), ignored.",
criteria->ID, criteria->requiredType, dataType, drunk.state);
return false;
}
@@ -230,7 +230,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
case ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY:
if (!sHolidaysStore.LookupEntry(holiday.id))
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY (%u) has unknown holiday in value1 (%u), ignored.",
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY (%u) contains an unknown holiday entry in value1 (%u), ignored.",
criteria->ID, criteria->requiredType, dataType, holiday.id);
return false;
}
@@ -240,7 +240,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM:
if (equipped_item.item_quality >= MAX_ITEM_QUALITY)
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM (%u) has unknown quality state in value1 (%u), ignored.",
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM (%u) contains an unknown quality state value in value1 (%u), ignored.",
criteria->ID, criteria->requiredType, dataType, equipped_item.item_quality);
return false;
}
@@ -248,7 +248,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID:
if (!sMapStore.LookupEntry(map_id.mapId))
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID (%u) has unknown map id in value1 (%u), ignored.",
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID (%u) contains an unknown map id in value1 (%u), ignored.",
criteria->ID, criteria->requiredType, dataType, map_id.mapId);
return false;
}
@@ -256,19 +256,19 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE:
if (!classRace.class_id && !classRace.race_id)
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE (%u) must not have 0 in either value field, ignored.",
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE (%u) should not have 0 in either value field. Ignored.",
criteria->ID, criteria->requiredType, dataType);
return false;
}
if (classRace.class_id && ((1 << (classRace.class_id-1)) & CLASSMASK_ALL_PLAYABLE) == 0)
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE (%u) has non-existing class in value1 (%u), ignored.",
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE (%u) contains a non-existing class entry in value1 (%u), ignored.",
criteria->ID, criteria->requiredType, dataType, classRace.class_id);
return false;
}
if (classRace.race_id && ((1 << (classRace.race_id-1)) & RACEMASK_ALL_PLAYABLE) == 0)
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE (%u) has non-existing race in value2 (%u), ignored.",
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE (%u) contains a non-existing race entry in value2 (%u), ignored.",
criteria->ID, criteria->requiredType, dataType, classRace.race_id);
return false;
}
@@ -276,13 +276,13 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_KNOWN_TITLE:
if (!sCharTitlesStore.LookupEntry(known_title.title_id))
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_KNOWN_TITLE (%u) have unknown title_id in value1 (%u), ignore.",
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_KNOWN_TITLE (%u) contains an unknown title_id in value1 (%u), ignore.",
criteria->ID, criteria->requiredType, dataType, known_title.title_id);
return false;
}
return true;
default:
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) has data for non-supported data type (%u), ignored.", criteria->ID, criteria->requiredType, dataType);
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) contains data of a non-supported data type (%u), ignored.", criteria->ID, criteria->requiredType, dataType);
return false;
}
}
@@ -377,14 +377,14 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un
Map* map = source->GetMap();
if (!map->IsDungeon())
{
- TC_LOG_ERROR("achievement", "Achievement system call ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT (%u) for achievement criteria %u for non-dungeon/non-raid map %u",
+ TC_LOG_ERROR("achievement", "Achievement system call ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT (%u) for achievement criteria %u in a non-dungeon/non-raid map %u",
dataType, criteria_id, map->GetId());
return false;
}
InstanceScript* instance = map->ToInstanceMap()->GetInstanceScript();
if (!instance)
{
- TC_LOG_ERROR("achievement", "Achievement system call ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT (%u) for achievement criteria %u for map %u but map does not have a instance script",
+ TC_LOG_ERROR("achievement", "Achievement system call ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT (%u) for achievement criteria %u in map %u, but the map does not have an instance script.",
dataType, criteria_id, map->GetId());
return false;
}
@@ -601,8 +601,8 @@ void AchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, PreparedQ
AchievementCriteriaEntry const* criteria = sAchievementMgr->GetAchievementCriteria(id);
if (!criteria)
{
- // we will remove not existed criteria for all characters
- TC_LOG_ERROR("achievement", "Non-existing achievement criteria %u data removed from table `character_achievement_progress`.", id);
+ // Removing non-existing criteria data for all characters
+ TC_LOG_ERROR("achievement", "Non-existing achievement criteria %u data has been removed from the table `character_achievement_progress`.", id);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA);
@@ -1066,7 +1066,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
break;
}
- // std case: not exist in DBC, not triggered in code as result
+ // std case: does not exist in DBC, not triggered in code as result
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALTH:
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_SPELLPOWER:
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_ARMOR:
@@ -1404,7 +1404,7 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry,
if (entry->timeLimit)
{
- // has to exist else we wouldn't be here
+ // has to exist, otherwise we wouldn't be here
timedCompleted = IsCompletedCriteria(entry, sAchievementMgr->GetAchievement(entry->referredAchievement));
// Client expects this in packet
timeElapsed = entry->timeLimit - (timedIter->second/IN_MILLISECONDS);
@@ -1655,14 +1655,14 @@ bool AchievementMgr::CanUpdateCriteria(AchievementCriteriaEntry const* criteria,
if (!RequirementsSatisfied(criteria, achievement, miscValue1, miscValue2, unit))
{
- TC_LOG_TRACE("achievement", "CanUpdateCriteria: (Id: %u Type %s) Requirements not satisfied",
+ TC_LOG_TRACE("achievement", "CanUpdateCriteria: (Id: %u Type %s) Requirements have not been satisfied",
criteria->ID, AchievementGlobalMgr::GetCriteriaTypeString(criteria->requiredType));
return false;
}
if (!ConditionsSatisfied(criteria))
{
- TC_LOG_TRACE("achievement", "CanUpdateCriteria: (Id: %u Type %s) Conditions not satisfied",
+ TC_LOG_TRACE("achievement", "CanUpdateCriteria: (Id: %u Type %s) Conditions have not been satisfied",
criteria->ID, AchievementGlobalMgr::GetCriteriaTypeString(criteria->requiredType));
return false;
}
@@ -2246,6 +2246,12 @@ char const* AchievementGlobalMgr::GetCriteriaTypeString(AchievementCriteriaTypes
return "MISSING_TYPE";
}
+AchievementGlobalMgr* AchievementGlobalMgr::instance()
+{
+ static AchievementGlobalMgr instance;
+ return &instance;
+}
+
//==========================================================
void AchievementGlobalMgr::LoadAchievementCriteriaList()
{
@@ -2273,7 +2279,7 @@ void AchievementGlobalMgr::LoadAchievementCriteriaList()
++loaded;
}
- TC_LOG_INFO("server.loading", ">> Loaded %u achievement criteria in %u ms", loaded, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u achievement criteria in %u ms.", loaded, GetMSTimeDiffToNow(oldMSTime));
}
void AchievementGlobalMgr::LoadAchievementReferenceList()
@@ -2302,7 +2308,7 @@ void AchievementGlobalMgr::LoadAchievementReferenceList()
if (AchievementEntry const* achievement = sAchievementMgr->GetAchievement(4539))
const_cast<AchievementEntry*>(achievement)->mapID = 631; // Correct map requirement (currently has Ulduar)
- TC_LOG_INFO("server.loading", ">> Loaded %u achievement references in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u achievement references in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
void AchievementGlobalMgr::LoadAchievementCriteriaData()
@@ -2330,7 +2336,7 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData()
if (!criteria)
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` has data for non-existing criteria (Entry: %u), ignore.", criteria_id);
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` contains data for non-existing criteria (Entry: %u). Ignored.", criteria_id);
continue;
}
@@ -2340,7 +2346,7 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData()
if (scriptName.length()) // not empty
{
if (dataType != ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT)
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` has ScriptName set for non-scripted data type (Entry: %u, type %u), useless data.", criteria_id, dataType);
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` contains a ScriptName for non-scripted data type (Entry: %u, type %u), useless data.", criteria_id, dataType);
else
scriptId = sObjectMgr->GetScriptId(scriptName);
}
@@ -2396,7 +2402,7 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData()
if (!achievement)
continue;
- // exist many achievements with this criteria, use at this moment hardcoded check to skil simple case
+ // There are many achievements with these criteria, use hardcoded check at this moment to pick a simple case
if (achievement->ID == 1282)
break;
@@ -2433,7 +2439,7 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData()
}
if (!GetCriteriaDataSet(criteria) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_ACHIEVEMENT_CRITERIA, entryId, NULL))
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` does not have expected data for criteria (Entry: %u Type: %u) for achievement %u.", criteria->ID, criteria->requiredType, criteria->referredAchievement);
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` does not contain expected data for criteria (Entry: %u Type: %u) for achievement %u.", criteria->ID, criteria->requiredType, criteria->referredAchievement);
}
TC_LOG_INFO("server.loading", ">> Loaded %u additional achievement criteria data in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
@@ -2459,8 +2465,8 @@ void AchievementGlobalMgr::LoadCompletedAchievements()
const AchievementEntry* achievement = sAchievementMgr->GetAchievement(achievementId);
if (!achievement)
{
- // Remove non existent achievements from all characters
- TC_LOG_ERROR("achievement", "Non-existing achievement %u data removed from table `character_achievement`.", achievementId);
+ // Remove non-existing achievements from all characters
+ TC_LOG_ERROR("achievement", "Non-existing achievement %u data has been removed from the table `character_achievement`.", achievementId);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_ACHIEVMENT);
stmt->setUInt16(0, uint16(achievementId));
@@ -2473,7 +2479,7 @@ void AchievementGlobalMgr::LoadCompletedAchievements()
}
while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %lu realm first completed achievements in %u ms", (unsigned long)m_allCompletedAchievements.size(), GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %lu realm first completed achievements in %u ms.", (unsigned long)m_allCompletedAchievements.size(), GetMSTimeDiffToNow(oldMSTime));
}
void AchievementGlobalMgr::LoadRewards()
@@ -2500,7 +2506,7 @@ void AchievementGlobalMgr::LoadRewards()
AchievementEntry const* achievement = GetAchievement(entry);
if (!achievement)
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_reward` has wrong achievement (Entry: %u), ignored.", entry);
+ TC_LOG_ERROR("sql.sql", "Table `achievement_reward` contains a wrong achievement entry (Entry: %u), ignored.", entry);
continue;
}
@@ -2516,19 +2522,19 @@ void AchievementGlobalMgr::LoadRewards()
// must be title or mail at least
if (!reward.titleId[0] && !reward.titleId[1] && !reward.sender)
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) does not have title or item reward data, ignored.", entry);
+ TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) does not contain title or item reward data. Ignored.", entry);
continue;
}
if (achievement->requiredFaction == ACHIEVEMENT_FACTION_ANY && (!reward.titleId[0] ^ !reward.titleId[1]))
- TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) has title (A: %u H: %u) for only one team.", entry, reward.titleId[0], reward.titleId[1]);
+ TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) contains the title (A: %u H: %u) for only one team.", entry, reward.titleId[0], reward.titleId[1]);
if (reward.titleId[0])
{
CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(reward.titleId[0]);
if (!titleEntry)
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) has invalid title id (%u) in `title_A`, set to 0", entry, reward.titleId[0]);
+ TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) contains an invalid title id (%u) in `title_A`, set to 0", entry, reward.titleId[0]);
reward.titleId[0] = 0;
}
}
@@ -2538,7 +2544,7 @@ void AchievementGlobalMgr::LoadRewards()
CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(reward.titleId[1]);
if (!titleEntry)
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) has invalid title id (%u) in `title_H`, set to 0", entry, reward.titleId[1]);
+ TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) contains an invalid title id (%u) in `title_H`, set to 0", entry, reward.titleId[1]);
reward.titleId[1] = 0;
}
}
@@ -2548,41 +2554,41 @@ void AchievementGlobalMgr::LoadRewards()
{
if (!sObjectMgr->GetCreatureTemplate(reward.sender))
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) has invalid creature entry %u as sender, mail reward skipped.", entry, reward.sender);
+ TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) contains an invalid creature entry %u as sender, mail reward skipped.", entry, reward.sender);
reward.sender = 0;
}
}
else
{
if (reward.itemId)
- TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) does not have sender data but has item reward, item will not be rewarded.", entry);
+ TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) does not have sender data, but contains an item reward. Item will not be rewarded.", entry);
if (!reward.subject.empty())
- TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) does not have sender data but has mail subject.", entry);
+ TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) does not have sender data, but contains a mail subject.", entry);
if (!reward.text.empty())
- TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) does not have sender data but has mail text.", entry);
+ TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) does not have sender data, but contains mail text.", entry);
if (reward.mailTemplate)
- TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) does not have sender data but has mailTemplate.", entry);
+ TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) does not have sender data, but has a mailTemplate.", entry);
}
if (reward.mailTemplate)
{
if (!sMailTemplateStore.LookupEntry(reward.mailTemplate))
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) has invalid mailTemplate (%u).", entry, reward.mailTemplate);
+ TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) is using an invalid mailTemplate (%u).", entry, reward.mailTemplate);
reward.mailTemplate = 0;
}
else if (!reward.subject.empty() || !reward.text.empty())
- TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) has mailTemplate (%u) and mail subject/text.", entry, reward.mailTemplate);
+ TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) is using mailTemplate (%u) and mail subject/text.", entry, reward.mailTemplate);
}
if (reward.itemId)
{
if (!sObjectMgr->GetItemTemplate(reward.itemId))
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) has invalid item id %u, reward mail will not contain item.", entry, reward.itemId);
+ TC_LOG_ERROR("sql.sql", "Table `achievement_reward` (Entry: %u) contains an invalid item id %u, reward mail will not contain the rewarded item.", entry, reward.itemId);
reward.itemId = 0;
}
}
@@ -2592,7 +2598,7 @@ void AchievementGlobalMgr::LoadRewards()
}
while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u achievement rewards in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u achievement rewards in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
void AchievementGlobalMgr::LoadRewardLocales()
@@ -2607,7 +2613,7 @@ void AchievementGlobalMgr::LoadRewardLocales()
if (!result)
{
- TC_LOG_INFO("server.loading", ">> Loaded 0 achievement reward locale strings. DB table `locales_achievement_reward` is empty");
+ TC_LOG_INFO("server.loading", ">> Loaded 0 achievement reward locale strings. DB table `locales_achievement_reward` is empty.");
return;
}
@@ -2619,7 +2625,7 @@ void AchievementGlobalMgr::LoadRewardLocales()
if (m_achievementRewards.find(entry) == m_achievementRewards.end())
{
- TC_LOG_ERROR("sql.sql", "Table `locales_achievement_reward` (Entry: %u) has locale strings for non-existing achievement reward.", entry);
+ TC_LOG_ERROR("sql.sql", "Table `locales_achievement_reward` (Entry: %u) contains locale strings for a non-existing achievement reward.", entry);
continue;
}
@@ -2634,7 +2640,7 @@ void AchievementGlobalMgr::LoadRewardLocales()
}
while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u achievement reward locale strings in %u ms", uint32(m_achievementRewardLocales.size()), GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u achievement reward locale strings in %u ms.", uint32(m_achievementRewardLocales.size()), GetMSTimeDiffToNow(oldMSTime));
}
AchievementEntry const* AchievementGlobalMgr::GetAchievement(uint32 achievementId) const
diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h
index cc3fd55bc3a..c4ac5f0e808 100644
--- a/src/server/game/Achievements/AchievementMgr.h
+++ b/src/server/game/Achievements/AchievementMgr.h
@@ -212,7 +212,7 @@ struct AchievementCriteriaData
bool Meets(uint32 criteria_id, Player const* source, Unit const* target, uint32 miscValue1 = 0) const;
};
-struct AchievementCriteriaDataSet
+struct TC_GAME_API AchievementCriteriaDataSet
{
AchievementCriteriaDataSet() : criteria_id(0) { }
typedef std::vector<AchievementCriteriaData> Storage;
@@ -262,7 +262,7 @@ enum ProgressType
PROGRESS_HIGHEST
};
-class AchievementMgr
+class TC_GAME_API AchievementMgr
{
public:
AchievementMgr(Player* player);
@@ -306,7 +306,7 @@ class AchievementMgr
TimedAchievementMap m_timedAchievements; // Criteria id/time left in MS
};
-class AchievementGlobalMgr
+class TC_GAME_API AchievementGlobalMgr
{
AchievementGlobalMgr() { }
~AchievementGlobalMgr() { }
@@ -315,11 +315,7 @@ class AchievementGlobalMgr
static char const* GetCriteriaTypeString(AchievementCriteriaTypes type);
static char const* GetCriteriaTypeString(uint32 type);
- static AchievementGlobalMgr* instance()
- {
- static AchievementGlobalMgr instance;
- return &instance;
- }
+ static AchievementGlobalMgr* instance();
AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type) const
{
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
index 035d9af4369..d9f5388e3ce 100644
--- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
@@ -44,6 +44,12 @@ AuctionHouseMgr::~AuctionHouseMgr()
delete itr->second;
}
+AuctionHouseMgr* AuctionHouseMgr::instance()
+{
+ static AuctionHouseMgr instance;
+ return &instance;
+}
+
AuctionHouseObject* AuctionHouseMgr::GetAuctionsMap(uint32 factionTemplateId)
{
if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
@@ -130,7 +136,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction&
else
{
bidderAccId = sObjectMgr->GetPlayerAccountIdByGUID(bidderGuid);
- logGmTrade = AccountMgr::HasPermission(bidderAccId, rbac::RBAC_PERM_LOG_GM_TRADE, realmID);
+ logGmTrade = AccountMgr::HasPermission(bidderAccId, rbac::RBAC_PERM_LOG_GM_TRADE, realm.Id.Realm);
if (logGmTrade && !sObjectMgr->GetPlayerNameByGUID(bidderGuid, bidderName))
bidderName = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN);
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.h b/src/server/game/AuctionHouse/AuctionHouseMgr.h
index fe4b9ed07de..42322929a30 100644
--- a/src/server/game/AuctionHouse/AuctionHouseMgr.h
+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.h
@@ -70,7 +70,7 @@ enum AuctionHouses
AUCTIONHOUSE_NEUTRAL = 7
};
-struct AuctionEntry
+struct TC_GAME_API AuctionEntry
{
uint32 Id;
uint8 houseId;
@@ -101,7 +101,7 @@ struct AuctionEntry
};
//this class is used as auctionhouse instance
-class AuctionHouseObject
+class TC_GAME_API AuctionHouseObject
{
public:
~AuctionHouseObject()
@@ -146,18 +146,14 @@ class AuctionHouseObject
};
-class AuctionHouseMgr
+class TC_GAME_API AuctionHouseMgr
{
private:
AuctionHouseMgr();
~AuctionHouseMgr();
public:
- static AuctionHouseMgr* instance()
- {
- static AuctionHouseMgr instance;
- return &instance;
- }
+ static AuctionHouseMgr* instance();
typedef std::unordered_map<ObjectGuid::LowType, Item*> ItemMap;
typedef std::vector<AuctionEntry*> PlayerAuctions;
diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBot.cpp b/src/server/game/AuctionHouseBot/AuctionHouseBot.cpp
index e1ba9a64191..74f0aaf428a 100644
--- a/src/server/game/AuctionHouseBot/AuctionHouseBot.cpp
+++ b/src/server/game/AuctionHouseBot/AuctionHouseBot.cpp
@@ -24,6 +24,12 @@
#include "AuctionHouseBotBuyer.h"
#include "AuctionHouseBotSeller.h"
+AuctionBotConfig* AuctionBotConfig::instance()
+{
+ static AuctionBotConfig instance;
+ return &instance;
+}
+
bool AuctionBotConfig::Initialize()
{
GetConfigFromFile();
@@ -426,6 +432,12 @@ void AuctionHouseBot::Rebuild(bool all)
}
}
+AuctionHouseBot* AuctionHouseBot::instance()
+{
+ static AuctionHouseBot instance;
+ return &instance;
+}
+
void AuctionHouseBot::Update()
{
// nothing do...
diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBot.h b/src/server/game/AuctionHouseBot/AuctionHouseBot.h
index 87f76a17dcc..1a438e01cdb 100644
--- a/src/server/game/AuctionHouseBot/AuctionHouseBot.h
+++ b/src/server/game/AuctionHouseBot/AuctionHouseBot.h
@@ -196,7 +196,7 @@ enum AuctionBotConfigFloatValues
};
// All basic config data used by other AHBot classes for self-configure.
-class AuctionBotConfig
+class TC_GAME_API AuctionBotConfig
{
private:
AuctionBotConfig(): _itemsPerCycleBoost(1000), _itemsPerCycleNormal(20) {}
@@ -205,11 +205,7 @@ private:
AuctionBotConfig& operator=(const AuctionBotConfig&);
public:
- static AuctionBotConfig* instance()
- {
- static AuctionBotConfig instance;
- return &instance;
- }
+ static AuctionBotConfig* instance();
bool Initialize();
const std::string& GetAHBotIncludes() const { return _AHBotIncludes; }
@@ -274,7 +270,7 @@ typedef AuctionHouseBotStatusInfoPerType AuctionHouseBotStatusInfo[MAX_AUCTION_H
// This class handle both Selling and Buying method
// (holder of AuctionBotBuyer and AuctionBotSeller objects)
-class AuctionHouseBot
+class TC_GAME_API AuctionHouseBot
{
private:
AuctionHouseBot();
@@ -283,11 +279,7 @@ private:
AuctionHouseBot& operator=(const AuctionHouseBot&);
public:
- static AuctionHouseBot* instance()
- {
- static AuctionHouseBot instance;
- return &instance;
- }
+ static AuctionHouseBot* instance();
void Update();
void Initialize();
diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.h b/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.h
index e1b6b425c48..979f73c0099 100644
--- a/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.h
+++ b/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.h
@@ -67,7 +67,7 @@ private:
// This class handle all Buyer method
// (holder of AuctionBotConfig for each auction house type)
-class AuctionBotBuyer : public AuctionBotAgent
+class TC_GAME_API AuctionBotBuyer : public AuctionBotAgent
{
public:
AuctionBotBuyer();
diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h
index dd82b0f3dda..563c2cda04a 100644
--- a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h
+++ b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h
@@ -115,7 +115,7 @@ private:
// This class handle all Selling method
// (holder of AHB_Seller_Config data for each auction house type)
-class AuctionBotSeller : public AuctionBotAgent
+class TC_GAME_API AuctionBotSeller : public AuctionBotAgent
{
public:
typedef std::vector<uint32> ItemPool;
diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp
index 34326d09e2f..e69d0f3085c 100644
--- a/src/server/game/Battlefield/Battlefield.cpp
+++ b/src/server/game/Battlefield/Battlefield.cpp
@@ -285,7 +285,7 @@ void Battlefield::InitStalker(uint32 entry, Position const& pos)
if (Creature* creature = SpawnCreature(entry, pos, TEAM_NEUTRAL))
StalkerGuid = creature->GetGUID();
else
- TC_LOG_ERROR("bg.battlefield", "Battlefield::InitStalker: could not spawn Stalker (Creature entry %u), zone messeges will be un-available", entry);
+ TC_LOG_ERROR("bg.battlefield", "Battlefield::InitStalker: Could not spawn Stalker (Creature entry %u), zone messages will be unavailable!", entry);
}
void Battlefield::KickAfkPlayers()
@@ -544,10 +544,10 @@ BfGraveyard* Battlefield::GetGraveyardById(uint32 id) const
if (BfGraveyard* graveyard = m_GraveyardList.at(id))
return graveyard;
else
- TC_LOG_ERROR("bg.battlefield", "Battlefield::GetGraveyardById Id:%u not existed", id);
+ TC_LOG_ERROR("bg.battlefield", "Battlefield::GetGraveyardById Id:%u does not exist.", id);
}
else
- TC_LOG_ERROR("bg.battlefield", "Battlefield::GetGraveyardById Id:%u cant be found", id);
+ TC_LOG_ERROR("bg.battlefield", "Battlefield::GetGraveyardById Id:%u could not be found.", id);
return NULL;
}
@@ -765,7 +765,7 @@ Creature* Battlefield::SpawnCreature(uint32 entry, float x, float y, float z, fl
Map* map = sMapMgr->CreateBaseMap(m_MapId);
if (!map)
{
- TC_LOG_ERROR("bg.battlefield", "Battlefield::SpawnCreature: Can't create creature entry: %u map not found", entry);
+ TC_LOG_ERROR("bg.battlefield", "Battlefield::SpawnCreature: Can't create creature entry: %u, map not found.", entry);
return nullptr;
}
@@ -782,7 +782,7 @@ Creature* Battlefield::SpawnCreature(uint32 entry, float x, float y, float z, fl
CreatureTemplate const* cinfo = sObjectMgr->GetCreatureTemplate(entry);
if (!cinfo)
{
- TC_LOG_ERROR("bg.battlefield", "Battlefield::SpawnCreature: entry %u does not exist.", entry);
+ TC_LOG_ERROR("bg.battlefield", "Battlefield::SpawnCreature: Entry %u does not exist.", entry);
return nullptr;
}
@@ -805,8 +805,8 @@ GameObject* Battlefield::SpawnGameObject(uint32 entry, float x, float y, float z
GameObject* go = new GameObject;
if (!go->Create(map->GenerateLowGuid<HighGuid::GameObject>(), entry, map, PHASEMASK_NORMAL, x, y, z, o, 0, 0, 0, 0, 100, GO_STATE_READY))
{
- TC_LOG_ERROR("bg.battlefield", "Battlefield::SpawnGameObject: Gameobject template %u not found in database! Battlefield not created!", entry);
- TC_LOG_ERROR("bg.battlefield", "Battlefield::SpawnGameObject: Cannot create gameobject template %u! Battlefield not created!", entry);
+ TC_LOG_ERROR("bg.battlefield", "Battlefield::SpawnGameObject: Gameobject template %u could not be found in the database! Battlefield has not been created!", entry);
+ TC_LOG_ERROR("bg.battlefield", "Battlefield::SpawnGameObject: Could not create gameobject template %u! Battlefield has not been created!", entry);
delete go;
return NULL;
}
@@ -907,7 +907,7 @@ bool BfCapturePoint::SetCapturePointData(GameObject* capturePoint)
GameObjectTemplate const* goinfo = capturePoint->GetGOInfo();
if (goinfo->type != GAMEOBJECT_TYPE_CAPTURE_POINT)
{
- TC_LOG_ERROR("misc", "OutdoorPvP: GO %u is not capture point!", capturePoint->GetEntry());
+ TC_LOG_ERROR("misc", "OutdoorPvP: GO %u is not a capture point!", capturePoint->GetEntry());
return false;
}
diff --git a/src/server/game/Battlefield/Battlefield.h b/src/server/game/Battlefield/Battlefield.h
index ade3e8c9699..6968e31c7bd 100644
--- a/src/server/game/Battlefield/Battlefield.h
+++ b/src/server/game/Battlefield/Battlefield.h
@@ -67,7 +67,7 @@ class BfGraveyard;
typedef std::vector<BfGraveyard*> GraveyardVect;
typedef std::map<ObjectGuid, time_t> PlayerTimerMap;
-class BfCapturePoint
+class TC_GAME_API BfCapturePoint
{
public:
BfCapturePoint(Battlefield* bf);
@@ -135,7 +135,7 @@ class BfCapturePoint
ObjectGuid m_capturePointGUID;
};
-class BfGraveyard
+class TC_GAME_API BfGraveyard
{
public:
BfGraveyard(Battlefield* Bf);
@@ -182,7 +182,7 @@ class BfGraveyard
Battlefield* m_Bf;
};
-class Battlefield : public ZoneScript
+class TC_GAME_API Battlefield : public ZoneScript
{
friend class BattlefieldMgr;
diff --git a/src/server/game/Battlefield/BattlefieldMgr.cpp b/src/server/game/Battlefield/BattlefieldMgr.cpp
index e4c10d64682..1df87fe1d6f 100644
--- a/src/server/game/Battlefield/BattlefieldMgr.cpp
+++ b/src/server/game/Battlefield/BattlefieldMgr.cpp
@@ -32,6 +32,12 @@ BattlefieldMgr::~BattlefieldMgr()
_battlefieldMap.clear();
}
+BattlefieldMgr* BattlefieldMgr::instance()
+{
+ static BattlefieldMgr instance;
+ return &instance;
+}
+
void BattlefieldMgr::InitBattlefield()
{
Battlefield* wg = new BattlefieldWG();
diff --git a/src/server/game/Battlefield/BattlefieldMgr.h b/src/server/game/Battlefield/BattlefieldMgr.h
index fabb33ae359..2f2af12927e 100644
--- a/src/server/game/Battlefield/BattlefieldMgr.h
+++ b/src/server/game/Battlefield/BattlefieldMgr.h
@@ -24,14 +24,10 @@ class Player;
class ZoneScript;
// class to handle player enter / leave / areatrigger / GO use events
-class BattlefieldMgr
+class TC_GAME_API BattlefieldMgr
{
public:
- static BattlefieldMgr* instance()
- {
- static BattlefieldMgr instance;
- return &instance;
- }
+ static BattlefieldMgr* instance();
// create battlefield events
void InitBattlefield();
diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.h b/src/server/game/Battlefield/Zones/BattlefieldWG.h
index e5cc392cef3..52789d38d8e 100644
--- a/src/server/game/Battlefield/Zones/BattlefieldWG.h
+++ b/src/server/game/Battlefield/Zones/BattlefieldWG.h
@@ -266,7 +266,7 @@ class WintergraspCapturePoint : public BfCapturePoint
* WinterGrasp Battlefield *
* ######################### */
-class BattlefieldWG : public Battlefield
+class TC_GAME_API BattlefieldWG : public Battlefield
{
public:
~BattlefieldWG();
@@ -1098,7 +1098,7 @@ StaticWintergraspWorkshopInfo const WorkshopData[WG_MAX_WORKSHOP] =
// ********************************************************************
// Structure for different buildings that can be destroyed during battle
-struct BfWGGameObjectBuilding
+struct TC_GAME_API BfWGGameObjectBuilding
{
private:
// WG object
@@ -1150,7 +1150,7 @@ public:
};
// Structure for the 6 workshop
-struct WintergraspWorkshop
+struct TC_GAME_API WintergraspWorkshop
{
private:
BattlefieldWG* _wg; // Pointer to wintergrasp
diff --git a/src/server/game/Battlegrounds/Arena.h b/src/server/game/Battlegrounds/Arena.h
index 863f1fc8c6f..1fe99f1f414 100644
--- a/src/server/game/Battlegrounds/Arena.h
+++ b/src/server/game/Battlegrounds/Arena.h
@@ -36,7 +36,7 @@ enum ArenaWorldStates
ARENA_WORLD_STATE_ALIVE_PLAYERS_GOLD = 3601
};
-class Arena : public Battleground
+class TC_GAME_API Arena : public Battleground
{
protected:
Arena();
diff --git a/src/server/game/Battlegrounds/ArenaScore.h b/src/server/game/Battlegrounds/ArenaScore.h
index c2d9d18c00b..9427a108565 100644
--- a/src/server/game/Battlegrounds/ArenaScore.h
+++ b/src/server/game/Battlegrounds/ArenaScore.h
@@ -21,7 +21,7 @@
#include "BattlegroundScore.h"
#include "SharedDefines.h"
-struct ArenaScore : public BattlegroundScore
+struct TC_GAME_API ArenaScore : public BattlegroundScore
{
friend class Arena;
@@ -56,7 +56,7 @@ struct ArenaScore : public BattlegroundScore
uint8 TeamId; // BattlegroundTeamId
};
-struct ArenaTeamScore
+struct TC_GAME_API ArenaTeamScore
{
friend class Arena;
friend class Battleground;
diff --git a/src/server/game/Battlegrounds/ArenaTeam.h b/src/server/game/Battlegrounds/ArenaTeam.h
index f27c3761bde..7e9f490bff9 100644
--- a/src/server/game/Battlegrounds/ArenaTeam.h
+++ b/src/server/game/Battlegrounds/ArenaTeam.h
@@ -85,7 +85,7 @@ enum ArenaTeamTypes
ARENA_TEAM_5v5 = 5
};
-struct ArenaTeamMember
+struct TC_GAME_API ArenaTeamMember
{
ObjectGuid Guid;
std::string Name;
@@ -113,7 +113,7 @@ struct ArenaTeamStats
#define MAX_ARENA_SLOT 3 // 0..2 slots
-class ArenaTeam
+class TC_GAME_API ArenaTeam
{
public:
ArenaTeam();
diff --git a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp
index b838131fd03..5dd0b6f29c3 100644
--- a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp
+++ b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp
@@ -35,6 +35,12 @@ ArenaTeamMgr::~ArenaTeamMgr()
delete itr->second;
}
+ArenaTeamMgr* ArenaTeamMgr::instance()
+{
+ static ArenaTeamMgr instance;
+ return &instance;
+}
+
// Arena teams collection
ArenaTeam* ArenaTeamMgr::GetArenaTeamById(uint32 arenaTeamId) const
{
diff --git a/src/server/game/Battlegrounds/ArenaTeamMgr.h b/src/server/game/Battlegrounds/ArenaTeamMgr.h
index 432a4ff598f..7f6800bd71b 100644
--- a/src/server/game/Battlegrounds/ArenaTeamMgr.h
+++ b/src/server/game/Battlegrounds/ArenaTeamMgr.h
@@ -20,18 +20,14 @@
#include "ArenaTeam.h"
-class ArenaTeamMgr
+class TC_GAME_API ArenaTeamMgr
{
private:
ArenaTeamMgr();
~ArenaTeamMgr();
public:
- static ArenaTeamMgr* instance()
- {
- static ArenaTeamMgr instance;
- return &instance;
- }
+ static ArenaTeamMgr* instance();
typedef std::unordered_map<uint32, ArenaTeam*> ArenaTeamContainer;
diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h
index 03f138a5a8b..bb6ae360536 100644
--- a/src/server/game/Battlegrounds/Battleground.h
+++ b/src/server/game/Battlegrounds/Battleground.h
@@ -221,7 +221,7 @@ This class is used to:
3. some certain cases, same for all battlegrounds
4. It has properties same for all battlegrounds
*/
-class Battleground
+class TC_GAME_API Battleground
{
public:
Battleground();
diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
index 062d4702d43..683547ef3fc 100644
--- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp
+++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
@@ -76,6 +76,12 @@ void BattlegroundMgr::DeleteAllBattlegrounds()
bgDataStore.clear();
}
+BattlegroundMgr* BattlegroundMgr::instance()
+{
+ static BattlegroundMgr instance;
+ return &instance;
+}
+
// used to update running battlegrounds, and delete finished ones
void BattlegroundMgr::Update(uint32 diff)
{
@@ -536,7 +542,7 @@ void BattlegroundMgr::LoadBattlegroundTemplates()
BattlemasterListEntry const* bl = sBattlemasterListStore.LookupEntry(bgTypeId);
if (!bl)
{
- TC_LOG_ERROR("bg.battleground", "Battleground ID %u not found in BattlemasterList.dbc. Battleground not created.", bgTypeId);
+ TC_LOG_ERROR("bg.battleground", "Battleground ID %u could not be found in BattlemasterList.dbc. The battleground was not created.", bgTypeId);
continue;
}
@@ -554,14 +560,14 @@ void BattlegroundMgr::LoadBattlegroundTemplates()
if (bgTemplate.MaxPlayersPerTeam == 0 || bgTemplate.MinPlayersPerTeam > bgTemplate.MaxPlayersPerTeam)
{
- TC_LOG_ERROR("sql.sql", "Table `battleground_template` for id %u has bad values for MinPlayersPerTeam (%u) and MaxPlayersPerTeam(%u)",
+ TC_LOG_ERROR("sql.sql", "Table `battleground_template` for id %u contains bad values for MinPlayersPerTeam (%u) and MaxPlayersPerTeam(%u).",
bgTemplate.Id, bgTemplate.MinPlayersPerTeam, bgTemplate.MaxPlayersPerTeam);
continue;
}
if (bgTemplate.MinLevel == 0 || bgTemplate.MaxLevel == 0 || bgTemplate.MinLevel > bgTemplate.MaxLevel)
{
- TC_LOG_ERROR("sql.sql", "Table `battleground_template` for id %u has bad values for MinLevel (%u) and MaxLevel (%u)",
+ TC_LOG_ERROR("sql.sql", "Table `battleground_template` for id %u contains bad values for MinLevel (%u) and MaxLevel (%u).",
bgTemplate.Id, bgTemplate.MinLevel, bgTemplate.MaxLevel);
continue;
}
@@ -575,7 +581,7 @@ void BattlegroundMgr::LoadBattlegroundTemplates()
}
else
{
- TC_LOG_ERROR("sql.sql", "Table `battleground_template` for id %u has non-existed WorldSafeLocs.dbc id %u in field `AllianceStartLoc`. BG not created.", bgTemplate.Id, startId);
+ TC_LOG_ERROR("sql.sql", "Table `battleground_template` for id %u contains a non-existing WorldSafeLocs.dbc id %u in field `AllianceStartLoc`. BG not created.", bgTemplate.Id, startId);
continue;
}
@@ -586,7 +592,7 @@ void BattlegroundMgr::LoadBattlegroundTemplates()
}
else
{
- TC_LOG_ERROR("sql.sql", "Table `battleground_template` for id %u has non-existed WorldSafeLocs.dbc id %u in field `HordeStartLoc`. BG not created.", bgTemplate.Id, startId);
+ TC_LOG_ERROR("sql.sql", "Table `battleground_template` for id %u contains a non-existing WorldSafeLocs.dbc id %u in field `HordeStartLoc`. BG not created.", bgTemplate.Id, startId);
continue;
}
}
@@ -788,7 +794,7 @@ BattlegroundTypeId BattlegroundMgr::BGTemplateId(BattlegroundQueueTypeId bgQueue
case BATTLEGROUND_QUEUE_5v5:
return BATTLEGROUND_AA;
default:
- return BattlegroundTypeId(0); // used for unknown template (it existed and do nothing)
+ return BattlegroundTypeId(0); // used for unknown template (it exists and does nothing)
}
}
@@ -892,7 +898,7 @@ void BattlegroundMgr::LoadBattleMastersEntry()
uint32 bgTypeId = fields[1].GetUInt32();
if (!sBattlemasterListStore.LookupEntry(bgTypeId))
{
- TC_LOG_ERROR("sql.sql", "Table `battlemaster_entry` contain entry %u for not existed battleground type %u, ignored.", entry, bgTypeId);
+ TC_LOG_ERROR("sql.sql", "Table `battlemaster_entry` contains entry %u for a non-existing battleground type %u, ignored.", entry, bgTypeId);
continue;
}
@@ -912,7 +918,7 @@ void BattlegroundMgr::CheckBattleMasters()
{
if ((itr->second.npcflag & UNIT_NPC_FLAG_BATTLEMASTER) && mBattleMastersMap.find(itr->second.Entry) == mBattleMastersMap.end())
{
- TC_LOG_ERROR("sql.sql", "CreatureTemplate (Entry: %u) has UNIT_NPC_FLAG_BATTLEMASTER but no data in `battlemaster_entry` table. Removing flag!", itr->second.Entry);
+ TC_LOG_ERROR("sql.sql", "Creature_Template Entry: %u has UNIT_NPC_FLAG_BATTLEMASTER, but no data in the `battlemaster_entry` table. Removing flag.", itr->second.Entry);
const_cast<CreatureTemplate*>(&itr->second)->npcflag &= ~UNIT_NPC_FLAG_BATTLEMASTER;
}
}
diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.h b/src/server/game/Battlegrounds/BattlegroundMgr.h
index 595745e53fb..dbba964d4b3 100644
--- a/src/server/game/Battlegrounds/BattlegroundMgr.h
+++ b/src/server/game/Battlegrounds/BattlegroundMgr.h
@@ -55,18 +55,14 @@ struct BattlegroundTemplate
bool IsArena() const { return BattlemasterEntry->type == MAP_ARENA; }
};
-class BattlegroundMgr
+class TC_GAME_API BattlegroundMgr
{
private:
BattlegroundMgr();
~BattlegroundMgr();
public:
- static BattlegroundMgr* instance()
- {
- static BattlegroundMgr instance;
- return &instance;
- }
+ static BattlegroundMgr* instance();
void Update(uint32 diff);
diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.h b/src/server/game/Battlegrounds/BattlegroundQueue.h
index 31f108053d9..f56ccb9bdbf 100644
--- a/src/server/game/Battlegrounds/BattlegroundQueue.h
+++ b/src/server/game/Battlegrounds/BattlegroundQueue.h
@@ -72,7 +72,7 @@ enum BattlegroundQueueInvitationType
};
class Battleground;
-class BattlegroundQueue
+class TC_GAME_API BattlegroundQueue
{
public:
BattlegroundQueue();
@@ -142,7 +142,7 @@ class BattlegroundQueue
This class is used to invite player to BG again, when minute lasts from his first invitation
it is capable to solve all possibilities
*/
-class BGQueueInviteEvent : public BasicEvent
+class TC_GAME_API BGQueueInviteEvent : public BasicEvent
{
public:
BGQueueInviteEvent(ObjectGuid pl_guid, uint32 BgInstanceGUID, BattlegroundTypeId BgTypeId, uint8 arenaType, uint32 removeTime) :
@@ -165,7 +165,7 @@ class BGQueueInviteEvent : public BasicEvent
We must store removeInvite time in case player left queue and joined and is invited again
We must store bgQueueTypeId, because battleground can be deleted already, when player entered it
*/
-class BGQueueRemoveEvent : public BasicEvent
+class TC_GAME_API BGQueueRemoveEvent : public BasicEvent
{
public:
BGQueueRemoveEvent(ObjectGuid pl_guid, uint32 bgInstanceGUID, BattlegroundTypeId BgTypeId, BattlegroundQueueTypeId bgQueueTypeId, uint32 removeTime)
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
index 626bcacbf27..e52106a8efe 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
@@ -171,7 +171,7 @@ void BattlegroundEY::CheckSomeoneJoinedPoint()
Player* player = ObjectAccessor::FindPlayer(m_PlayersNearPoint[EY_POINTS_MAX][j]);
if (!player)
{
- TC_LOG_ERROR("bg.battleground", "BattlegroundEY:CheckSomeoneJoinedPoint: Player (%s) not found!", m_PlayersNearPoint[EY_POINTS_MAX][j].ToString().c_str());
+ TC_LOG_ERROR("bg.battleground", "BattlegroundEY:CheckSomeoneJoinedPoint: Player (%s) could not be found!", m_PlayersNearPoint[EY_POINTS_MAX][j].ToString().c_str());
++j;
continue;
}
@@ -212,8 +212,8 @@ void BattlegroundEY::CheckSomeoneLeftPoint()
Player* player = ObjectAccessor::FindPlayer(m_PlayersNearPoint[i][j]);
if (!player)
{
- TC_LOG_ERROR("bg.battleground", "BattlegroundEY:CheckSomeoneLeftPoint Player (%s) not found!", m_PlayersNearPoint[i][j].ToString().c_str());
- //move not existed player to "free space" - this will cause many error showing in log, but it is a very important bug
+ TC_LOG_ERROR("bg.battleground", "BattlegroundEY:CheckSomeoneLeftPoint Player (%s) could not be found!", m_PlayersNearPoint[i][j].ToString().c_str());
+ //move non-existing players to "free space" - this will cause many errors showing in log, but it is a very important bug
m_PlayersNearPoint[EY_POINTS_MAX].push_back(m_PlayersNearPoint[i][j]);
m_PlayersNearPoint[i].erase(m_PlayersNearPoint[i].begin() + j);
continue;
@@ -498,7 +498,7 @@ bool BattlegroundEY::SetupBattleground()
|| !AddObject(BG_EY_OBJECT_TOWER_CAP_MAGE_TOWER, BG_OBJECT_HU_TOWER_CAP_EY_ENTRY, 2282.121582f, 1760.006958f, 1189.707153f, 1.919862f, 0, 0, 0.819152f, 0.573576f, RESPAWN_ONE_DAY)
)
{
- TC_LOG_ERROR("sql.sql", "BatteGroundEY: Failed to spawn some object Battleground not created!");
+ TC_LOG_ERROR("sql.sql", "BatteGroundEY: Failed to spawn some objects. The battleground was not created.");
return false;
}
@@ -515,21 +515,21 @@ bool BattlegroundEY::SetupBattleground()
|| !AddObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REAVER + i * 3 + 1, Buff_Entries[1], at->x, at->y, at->z, 0.907571f, 0, 0, 0.438371f, 0.898794f, RESPAWN_ONE_DAY)
|| !AddObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REAVER + i * 3 + 2, Buff_Entries[2], at->x, at->y, at->z, 0.907571f, 0, 0, 0.438371f, 0.898794f, RESPAWN_ONE_DAY)
)
- TC_LOG_ERROR("bg.battleground", "BattlegroundEY: Cannot spawn buff");
+ TC_LOG_ERROR("bg.battleground", "BattlegroundEY: Could not spawn Speedbuff Fel Reaver.");
}
WorldSafeLocsEntry const* sg = NULL;
sg = sWorldSafeLocsStore.LookupEntry(EY_GRAVEYARD_MAIN_ALLIANCE);
if (!sg || !AddSpiritGuide(EY_SPIRIT_MAIN_ALLIANCE, sg->x, sg->y, sg->z, 3.124139f, TEAM_ALLIANCE))
{
- TC_LOG_ERROR("sql.sql", "BatteGroundEY: Failed to spawn spirit guide! Battleground not created!");
+ TC_LOG_ERROR("sql.sql", "BatteGroundEY: Failed to spawn spirit guide. The battleground was not created.");
return false;
}
sg = sWorldSafeLocsStore.LookupEntry(EY_GRAVEYARD_MAIN_HORDE);
if (!sg || !AddSpiritGuide(EY_SPIRIT_MAIN_HORDE, sg->x, sg->y, sg->z, 3.193953f, TEAM_HORDE))
{
- TC_LOG_ERROR("sql.sql", "BatteGroundEY: Failed to spawn spirit guide! Battleground not created!");
+ TC_LOG_ERROR("sql.sql", "BatteGroundEY: Failed to spawn spirit guide. The battleground was not created.");
return false;
}
@@ -595,7 +595,7 @@ void BattlegroundEY::RespawnFlagAfterDrop()
if (obj)
obj->Delete();
else
- TC_LOG_ERROR("bg.battleground", "BattlegroundEY: Unknown dropped flag (%s)", GetDroppedFlagGUID().ToString().c_str());
+ TC_LOG_ERROR("bg.battleground", "BattlegroundEY: Unknown dropped flag (%s).", GetDroppedFlagGUID().ToString().c_str());
SetDroppedFlagGUID(ObjectGuid::Empty);
}
@@ -767,7 +767,7 @@ void BattlegroundEY::EventTeamCapturedPoint(Player* player, uint32 Point)
WorldSafeLocsEntry const* sg = NULL;
sg = sWorldSafeLocsStore.LookupEntry(m_CapturingPointTypes[Point].GraveYardId);
if (!sg || !AddSpiritGuide(Point, sg->x, sg->y, sg->z, 3.124139f, GetTeamIndexByTeamId(Team)))
- TC_LOG_ERROR("bg.battleground", "BatteGroundEY: Failed to spawn spirit guide! point: %u, team: %u, graveyard_id: %u",
+ TC_LOG_ERROR("bg.battleground", "BatteGroundEY: Failed to spawn spirit guide. point: %u, team: %u, graveyard_id: %u",
Point, Team, m_CapturingPointTypes[Point].GraveYardId);
// SpawnBGCreature(Point, RESPAWN_IMMEDIATELY);
@@ -917,7 +917,7 @@ WorldSafeLocsEntry const* BattlegroundEY::GetClosestGraveYard(Player* player)
if (!entry)
{
- TC_LOG_ERROR("bg.battleground", "BattlegroundEY: Not found the main team graveyard. Graveyard system isn't working!");
+ TC_LOG_ERROR("bg.battleground", "BattlegroundEY: The main team graveyard could not be found. The graveyard system will not be operational!");
return NULL;
}
@@ -934,7 +934,7 @@ WorldSafeLocsEntry const* BattlegroundEY::GetClosestGraveYard(Player* player)
{
entry = sWorldSafeLocsStore.LookupEntry(m_CapturingPointTypes[i].GraveYardId);
if (!entry)
- TC_LOG_ERROR("bg.battleground", "BattlegroundEY: Not found graveyard: %u", m_CapturingPointTypes[i].GraveYardId);
+ TC_LOG_ERROR("bg.battleground", "BattlegroundEY: Graveyard %u could not be found.", m_CapturingPointTypes[i].GraveYardId);
else
{
distance = (entry->x - plr_x)*(entry->x - plr_x) + (entry->y - plr_y)*(entry->y - plr_y) + (entry->z - plr_z)*(entry->z - plr_z);
diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt
index aae5b4874d8..df0d2b7cc2a 100644
--- a/src/server/game/CMakeLists.txt
+++ b/src/server/game/CMakeLists.txt
@@ -8,206 +8,63 @@
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-file(GLOB_RECURSE sources_Accounts Accounts/*.cpp Accounts/*.h)
-file(GLOB_RECURSE sources_Achievements Achievements/*.cpp Achievements/*.h)
-file(GLOB_RECURSE sources_Addons Addons/*.cpp Addons/*.h)
-file(GLOB_RECURSE sources_AI AI/*.cpp AI/*.h)
-file(GLOB_RECURSE sources_AuctionHouse AuctionHouse/*.cpp AuctionHouse/*.h)
-file(GLOB_RECURSE sources_AuctionHouseBot AuctionHouseBot/*.cpp AuctionHouseBot/*.h)
-file(GLOB_RECURSE sources_Battlefield Battlefield/*.cpp Battlefield/*.h)
-file(GLOB_RECURSE sources_Battlegrounds Battlegrounds/*.cpp Battlegrounds/*.h)
-file(GLOB_RECURSE sources_Calendar Calendar/*.cpp Calendar/*.h)
-file(GLOB_RECURSE sources_Chat Chat/*.cpp Chat/*.h)
-file(GLOB_RECURSE sources_Combat Combat/*.cpp Combat/*.h)
-file(GLOB_RECURSE sources_Conditions Conditions/*.cpp Conditions/*.h)
-file(GLOB_RECURSE sources_DataStores DataStores/*.cpp DataStores/*.h)
-file(GLOB_RECURSE sources_DungeonFinding DungeonFinding/*.cpp DungeonFinding/*.h)
-file(GLOB_RECURSE sources_Entities Entities/*.cpp Entities/*.h)
-file(GLOB_RECURSE sources_Events Events/*.cpp Events/*.h)
-file(GLOB_RECURSE sources_Globals Globals/*.cpp Globals/*.h)
-file(GLOB_RECURSE sources_Grids Grids/*.cpp Grids/*.h)
-file(GLOB_RECURSE sources_Groups Groups/*.cpp Groups/*.h)
-file(GLOB_RECURSE sources_Guilds Guilds/*.cpp Guilds/*.h)
-file(GLOB_RECURSE sources_Handlers Handlers/*.cpp Handlers/*.h)
-file(GLOB_RECURSE sources_Instances Instances/*.cpp Instances/*.h)
-file(GLOB_RECURSE sources_Loot Loot/*.cpp Loot/*.h)
-file(GLOB_RECURSE sources_Mails Mails/*.cpp Mails/*.h)
-file(GLOB_RECURSE sources_Maps Maps/*.cpp Maps/*.h)
-file(GLOB_RECURSE sources_Miscellaneous Miscellaneous/*.cpp Miscellaneous/*.h)
-file(GLOB_RECURSE sources_Movement Movement/*.cpp Movement/*.h)
-file(GLOB_RECURSE sources_OutdoorPvP OutdoorPvP/*.cpp OutdoorPvP/*.h)
-file(GLOB_RECURSE sources_Pools Pools/*.cpp Pools/*.h)
-file(GLOB_RECURSE sources_Quests Quests/*.cpp Quests/*.h)
-file(GLOB_RECURSE sources_Reputation Reputation/*.cpp Reputation/*.h)
-file(GLOB_RECURSE sources_Scripting Scripting/*.cpp Scripting/*.h)
-file(GLOB_RECURSE sources_Server Server/*.cpp Server/*.h)
-file(GLOB_RECURSE sources_Skills Skills/*.cpp Skills/*.h)
-file(GLOB_RECURSE sources_Spells Spells/*.cpp Spells/*.h)
-file(GLOB_RECURSE sources_Texts Texts/*.cpp Texts/*.h)
-file(GLOB_RECURSE sources_Tools Tools/*.cpp Tools/*.h)
-file(GLOB_RECURSE sources_Tickets Tickets/*.cpp Tickets/*.h)
-file(GLOB_RECURSE sources_Warden Warden/*.cpp Warden/*.h)
-file(GLOB_RECURSE sources_Weather Weather/*.cpp Weather/*.h)
-file(GLOB_RECURSE sources_World World/*.cpp World/*.h)
-
-# Create game-libary
+CollectSourceFiles(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ PRIVATE_SOURCES
+ # Exclude
+ ${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders)
if (USE_COREPCH)
- set(game_STAT_PCH_HDR PrecompiledHeaders/gamePCH.h)
- set(game_STAT_PCH_SRC PrecompiledHeaders/gamePCH.cpp)
+ set(PRIVATE_PCH_HEADER PrecompiledHeaders/gamePCH.h)
+ set(PRIVATE_PCH_SOURCE PrecompiledHeaders/gamePCH.cpp)
endif ()
-set(game_STAT_SRCS
- ${game_STAT_SRCS}
- ${sources_Accounts}
- ${sources_Achievements}
- ${sources_Addons}
- ${sources_AI}
- ${sources_AuctionHouse}
- ${sources_AuctionHouseBot}
- ${sources_Battlefield}
- ${sources_Battlegrounds}
- ${sources_Calendar}
- ${sources_Chat}
- ${sources_Combat}
- ${sources_Conditions}
- ${sources_DataStores}
- ${sources_DungeonFinding}
- ${sources_Entities}
- ${sources_Events}
- ${sources_Globals}
- ${sources_Grids}
- ${sources_Groups}
- ${sources_Guilds}
- ${sources_Handlers}
- ${sources_Instances}
- ${sources_Loot}
- ${sources_Mails}
- ${sources_Maps}
- ${sources_Miscellaneous}
- ${sources_Movement}
- ${sources_OutdoorPvP}
- ${sources_Pools}
- ${sources_Quests}
- ${sources_Reputation}
- ${sources_Scripting}
- ${sources_Server}
- ${sources_Skills}
- ${sources_Spells}
- ${sources_Texts}
- ${sources_Tools}
- ${sources_Tickets}
- ${sources_Warden}
- ${sources_Weather}
- ${sources_World}
-)
+GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
-include_directories(
- ${CMAKE_CURRENT_SOURCE_DIR}/Accounts
- ${CMAKE_CURRENT_SOURCE_DIR}/Achievements
- ${CMAKE_CURRENT_SOURCE_DIR}/Addons
- ${CMAKE_CURRENT_SOURCE_DIR}/AI
- ${CMAKE_CURRENT_SOURCE_DIR}/AI/CoreAI
- ${CMAKE_CURRENT_SOURCE_DIR}/AI/ScriptedAI
- ${CMAKE_CURRENT_SOURCE_DIR}/AI/SmartScripts
- ${CMAKE_CURRENT_SOURCE_DIR}/AuctionHouse
- ${CMAKE_CURRENT_SOURCE_DIR}/AuctionHouseBot
- ${CMAKE_CURRENT_SOURCE_DIR}/Battlefield
- ${CMAKE_CURRENT_SOURCE_DIR}/Battlefield/Zones
- ${CMAKE_CURRENT_SOURCE_DIR}/Battlegrounds
- ${CMAKE_CURRENT_SOURCE_DIR}/Battlegrounds/Zones
- ${CMAKE_CURRENT_SOURCE_DIR}/Calendar
- ${CMAKE_CURRENT_SOURCE_DIR}/Chat
- ${CMAKE_CURRENT_SOURCE_DIR}/Chat/Channels
- ${CMAKE_CURRENT_SOURCE_DIR}/Combat
- ${CMAKE_CURRENT_SOURCE_DIR}/Conditions
- ${CMAKE_CURRENT_SOURCE_DIR}/DataStores
- ${CMAKE_CURRENT_SOURCE_DIR}/DungeonFinding
- ${CMAKE_CURRENT_SOURCE_DIR}/Entities/Corpse
- ${CMAKE_CURRENT_SOURCE_DIR}/Entities/Creature
- ${CMAKE_CURRENT_SOURCE_DIR}/Entities/DynamicObject
- ${CMAKE_CURRENT_SOURCE_DIR}/Entities/GameObject
- ${CMAKE_CURRENT_SOURCE_DIR}/Entities/Item
- ${CMAKE_CURRENT_SOURCE_DIR}/Entities/Item/Container
- ${CMAKE_CURRENT_SOURCE_DIR}/Entities/Object
- ${CMAKE_CURRENT_SOURCE_DIR}/Entities/Object/Updates
- ${CMAKE_CURRENT_SOURCE_DIR}/Entities/Pet
- ${CMAKE_CURRENT_SOURCE_DIR}/Entities/Player
- ${CMAKE_CURRENT_SOURCE_DIR}/Entities/Totem
- ${CMAKE_CURRENT_SOURCE_DIR}/Entities/Transport
- ${CMAKE_CURRENT_SOURCE_DIR}/Entities/Unit
- ${CMAKE_CURRENT_SOURCE_DIR}/Entities/Vehicle
- ${CMAKE_CURRENT_SOURCE_DIR}/Events
- ${CMAKE_CURRENT_SOURCE_DIR}/Globals
- ${CMAKE_CURRENT_SOURCE_DIR}/Grids
- ${CMAKE_CURRENT_SOURCE_DIR}/Grids/Cells
- ${CMAKE_CURRENT_SOURCE_DIR}/Grids/Notifiers
- ${CMAKE_CURRENT_SOURCE_DIR}/Groups
- ${CMAKE_CURRENT_SOURCE_DIR}/Guilds
- ${CMAKE_CURRENT_SOURCE_DIR}/Handlers
- ${CMAKE_CURRENT_SOURCE_DIR}/Instances
- ${CMAKE_CURRENT_SOURCE_DIR}/Loot
- ${CMAKE_CURRENT_SOURCE_DIR}/Mails
- ${CMAKE_CURRENT_SOURCE_DIR}/Maps
- ${CMAKE_CURRENT_SOURCE_DIR}/Miscellaneous
- ${CMAKE_CURRENT_SOURCE_DIR}/Movement
- ${CMAKE_CURRENT_SOURCE_DIR}/Movement/MovementGenerators
- ${CMAKE_CURRENT_SOURCE_DIR}/Movement/Spline
- ${CMAKE_CURRENT_SOURCE_DIR}/Movement/Waypoints
- ${CMAKE_CURRENT_SOURCE_DIR}/OutdoorPvP
- ${CMAKE_CURRENT_SOURCE_DIR}/Pools
- ${CMAKE_CURRENT_SOURCE_DIR}/Quests
- ${CMAKE_CURRENT_SOURCE_DIR}/Reputation
- ${CMAKE_CURRENT_SOURCE_DIR}/Scripting
- ${CMAKE_CURRENT_SOURCE_DIR}/Server
- ${CMAKE_CURRENT_SOURCE_DIR}/Server/Protocol
- ${CMAKE_CURRENT_SOURCE_DIR}/Skills
- ${CMAKE_CURRENT_SOURCE_DIR}/Spells
- ${CMAKE_CURRENT_SOURCE_DIR}/Spells/Auras
- ${CMAKE_CURRENT_SOURCE_DIR}/Texts
- ${CMAKE_CURRENT_SOURCE_DIR}/Tickets
- ${CMAKE_CURRENT_SOURCE_DIR}/Tools
- ${CMAKE_CURRENT_SOURCE_DIR}/Warden
- ${CMAKE_CURRENT_SOURCE_DIR}/Warden/Modules
- ${CMAKE_CURRENT_SOURCE_DIR}/Weather
- ${CMAKE_CURRENT_SOURCE_DIR}/World
- ${CMAKE_SOURCE_DIR}/dep/cppformat
- ${CMAKE_SOURCE_DIR}/dep/g3dlite/include
- ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour/Include
- ${CMAKE_SOURCE_DIR}/dep/zlib
- ${CMAKE_SOURCE_DIR}/src/common
- ${CMAKE_SOURCE_DIR}/src/common/Collision
- ${CMAKE_SOURCE_DIR}/src/common/Collision/Management
- ${CMAKE_SOURCE_DIR}/src/common/Collision/Maps
- ${CMAKE_SOURCE_DIR}/src/common/Collision/Models
- ${CMAKE_SOURCE_DIR}/src/common/Configuration
- ${CMAKE_SOURCE_DIR}/src/common/Cryptography
- ${CMAKE_SOURCE_DIR}/src/common/Cryptography/Authentication
- ${CMAKE_SOURCE_DIR}/src/common/Debugging
- ${CMAKE_SOURCE_DIR}/src/common/Logging
- ${CMAKE_SOURCE_DIR}/src/common/Threading
- ${CMAKE_SOURCE_DIR}/src/common/Utilities
- ${CMAKE_SOURCE_DIR}/src/server/database
- ${CMAKE_SOURCE_DIR}/src/server/database/Database
- ${CMAKE_SOURCE_DIR}/src/server/shared
- ${CMAKE_SOURCE_DIR}/src/server/shared/DataStores
- ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic
- ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference
- ${CMAKE_SOURCE_DIR}/src/server/shared/Networking
- ${CMAKE_SOURCE_DIR}/src/server/shared/Packets
- ${MYSQL_INCLUDE_DIR}
- ${OPENSSL_INCLUDE_DIR}
- ${VALGRIND_INCLUDE_DIR}
+add_definitions(-DTRINITY_API_EXPORT_GAME)
+
+add_library(game
+ ${PRIVATE_SOURCES}
+ ${PRIVATE_PCH_SOURCE}
)
-GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
+CollectIncludeDirectories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ PUBLIC_INCLUDES
+ # Exclude
+ ${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders)
-add_library(game STATIC
- ${game_STAT_SRCS}
- ${game_STAT_PCH_SRC}
-)
+target_include_directories(game
+ PUBLIC
+ ${PUBLIC_INCLUDES}
+ PRIVATE
+ ${CMAKE_CURRENT_BINARY_DIR})
+
+target_link_libraries(game
+ PUBLIC
+ shared
+ Detour
+ PRIVATE
+ efsw)
+
+set_target_properties(game
+ PROPERTIES
+ FOLDER
+ "server")
+
+if( BUILD_SHARED_LIBS )
+ if( UNIX )
+ install(TARGETS game
+ LIBRARY
+ DESTINATION lib)
+ elseif( WIN32 )
+ install(TARGETS game
+ RUNTIME
+ DESTINATION "${CMAKE_INSTALL_PREFIX}")
+ endif()
+endif()
# Generate precompiled header
if (USE_COREPCH)
- add_cxx_pch(game ${game_STAT_PCH_HDR} ${game_STAT_PCH_SRC})
+ add_cxx_pch(game ${PRIVATE_PCH_HEADER} ${PRIVATE_PCH_SOURCE})
endif ()
diff --git a/src/server/game/Calendar/CalendarMgr.cpp b/src/server/game/Calendar/CalendarMgr.cpp
index 9d50b290c5e..b27aac7876a 100644
--- a/src/server/game/Calendar/CalendarMgr.cpp
+++ b/src/server/game/Calendar/CalendarMgr.cpp
@@ -45,6 +45,12 @@ CalendarMgr::~CalendarMgr()
delete *itr2;
}
+CalendarMgr* CalendarMgr::instance()
+{
+ static CalendarMgr instance;
+ return &instance;
+}
+
void CalendarMgr::LoadFromDB()
{
uint32 count = 0;
diff --git a/src/server/game/Calendar/CalendarMgr.h b/src/server/game/Calendar/CalendarMgr.h
index 59303a18324..c282e3e202c 100644
--- a/src/server/game/Calendar/CalendarMgr.h
+++ b/src/server/game/Calendar/CalendarMgr.h
@@ -126,7 +126,7 @@ enum CalendarError
#define CALENDAR_MAX_GUILD_EVENTS 100
#define CALENDAR_MAX_INVITES 100
-struct CalendarInvite
+struct TC_GAME_API CalendarInvite
{
public:
CalendarInvite(CalendarInvite const& calendarInvite, uint64 inviteId, uint64 eventId)
@@ -186,7 +186,7 @@ struct CalendarInvite
std::string _text;
};
-struct CalendarEvent
+struct TC_GAME_API CalendarEvent
{
public:
CalendarEvent(CalendarEvent const& calendarEvent, uint64 eventId)
@@ -266,7 +266,7 @@ typedef std::vector<CalendarInvite*> CalendarInviteStore;
typedef std::set<CalendarEvent*> CalendarEventStore;
typedef std::map<uint64 /* eventId */, CalendarInviteStore > CalendarEventInviteStore;
-class CalendarMgr
+class TC_GAME_API CalendarMgr
{
private:
CalendarMgr();
@@ -281,11 +281,7 @@ class CalendarMgr
uint64 _maxInviteId;
public:
- static CalendarMgr* instance()
- {
- static CalendarMgr instance;
- return &instance;
- }
+ static CalendarMgr* instance();
void LoadFromDB();
diff --git a/src/server/game/Chat/Channels/Channel.h b/src/server/game/Chat/Channels/Channel.h
index 26bc6989d07..319105d2a8d 100644
--- a/src/server/game/Chat/Channels/Channel.h
+++ b/src/server/game/Chat/Channels/Channel.h
@@ -118,7 +118,7 @@ enum ChannelMemberFlags
// 0x80
};
-class Channel
+class TC_GAME_API Channel
{
struct PlayerInfo
{
diff --git a/src/server/game/Chat/Channels/ChannelMgr.h b/src/server/game/Chat/Channels/ChannelMgr.h
index 2cd4edc4fb1..abe45690997 100644
--- a/src/server/game/Chat/Channels/ChannelMgr.h
+++ b/src/server/game/Chat/Channels/ChannelMgr.h
@@ -28,7 +28,7 @@
#define MAX_CHANNEL_PASS_STR 31
-class ChannelMgr
+class TC_GAME_API ChannelMgr
{
typedef std::map<std::wstring, Channel*> ChannelMap;
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
index 8fe0810f3b9..f0e98ee8c1f 100644
--- a/src/server/game/Chat/Chat.cpp
+++ b/src/server/game/Chat/Chat.cpp
@@ -108,7 +108,7 @@ bool ChatHandler::HasLowerSecurityAccount(WorldSession* target, uint32 target_ac
if (target)
target_sec = target->GetSecurity();
else if (target_account)
- target_sec = AccountMgr::GetSecurity(target_account, realmID);
+ target_sec = AccountMgr::GetSecurity(target_account, realm.Id.Realm);
else
return true; // caller must report error for (target == NULL && target_account == 0)
@@ -360,7 +360,7 @@ bool ChatHandler::SetDataForCommandInTable(std::vector<ChatCommand>& table, char
// expected subcommand by full name DB content
else if (*text)
{
- TC_LOG_ERROR("sql.sql", "Table `command` have unexpected subcommand '%s' in command '%s', skip.", text, fullcommand.c_str());
+ TC_LOG_ERROR("sql.sql", "Table `command` contains an unexpected subcommand '%s' in command '%s', skipped.", text, fullcommand.c_str());
return false;
}
@@ -376,9 +376,9 @@ bool ChatHandler::SetDataForCommandInTable(std::vector<ChatCommand>& table, char
if (!cmd.empty())
{
if (&table == &getCommandTable())
- TC_LOG_ERROR("sql.sql", "Table `command` have not existed command '%s', skip.", cmd.c_str());
+ TC_LOG_ERROR("sql.sql", "Table `command` contains a non-existing command '%s', skipped.", cmd.c_str());
else
- TC_LOG_ERROR("sql.sql", "Table `command` have not existed subcommand '%s' in command '%s', skip.", cmd.c_str(), fullcommand.c_str());
+ TC_LOG_ERROR("sql.sql", "Table `command` contains a non-existing subcommand '%s' in command '%s', skipped.", cmd.c_str(), fullcommand.c_str());
}
return false;
@@ -486,7 +486,7 @@ bool ChatHandler::ShowHelpForSubCommands(std::vector<ChatCommand> const& table,
std::string list;
for (uint32 i = 0; i < table.size(); ++i)
{
- // must be available (ignore handler existence for show command with possible available subcommands)
+ // must be available (ignore handler existence to show command with possible available subcommands)
if (!isAvailable(table[i]))
continue;
@@ -525,7 +525,7 @@ bool ChatHandler::ShowHelpForCommand(std::vector<ChatCommand> const& table, cons
{
for (uint32 i = 0; i < table.size(); ++i)
{
- // must be available (ignore handler existence for show command with possible available subcommands)
+ // must be available (ignore handler existence to show command with possible available subcommands)
if (!isAvailable(table[i]))
continue;
@@ -555,7 +555,7 @@ bool ChatHandler::ShowHelpForCommand(std::vector<ChatCommand> const& table, cons
{
for (uint32 i = 0; i < table.size(); ++i)
{
- // must be available (ignore handler existence for show command with possible available subcommands)
+ // must be available (ignore handler existence to show command with possible available subcommands)
if (!isAvailable(table[i]))
continue;
@@ -1100,7 +1100,7 @@ bool ChatHandler::extractPlayerTarget(char* args, Player** player, ObjectGuid* p
*player_name = pl ? pl->GetName() : "";
}
- // some from req. data must be provided (note: name is empty if player not exist)
+ // some from req. data must be provided (note: name is empty if player does not exist)
if ((!player || !*player) && (!player_guid || !*player_guid) && (!player_name || player_name->empty()))
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h
index 7ce0792cdf9..a061ff63b00 100644
--- a/src/server/game/Chat/Chat.h
+++ b/src/server/game/Chat/Chat.h
@@ -36,7 +36,7 @@ class WorldObject;
struct GameTele;
-class ChatCommand
+class TC_GAME_API ChatCommand
{
typedef bool(*pHandler)(ChatHandler*, char const*);
@@ -52,7 +52,7 @@ class ChatCommand
std::vector<ChatCommand> ChildCommands;
};
-class ChatHandler
+class TC_GAME_API ChatHandler
{
public:
WorldSession* GetSession() { return m_session; }
@@ -161,7 +161,7 @@ class ChatHandler
bool sentErrorMessage;
};
-class CliHandler : public ChatHandler
+class TC_GAME_API CliHandler : public ChatHandler
{
public:
typedef void Print(void*, char const*);
diff --git a/src/server/game/Chat/ChatLink.h b/src/server/game/Chat/ChatLink.h
index 4adb61bbbf1..0d413ce49df 100644
--- a/src/server/game/Chat/ChatLink.h
+++ b/src/server/game/Chat/ChatLink.h
@@ -34,7 +34,7 @@ class Quest;
///////////////////////////////////////////////////////////////////////////////////////////////////
// ChatLink - abstract base class for various links
-class ChatLink
+class TC_GAME_API ChatLink
{
public:
ChatLink() : _color(0), _startPos(0), _endPos(0) { }
@@ -54,7 +54,7 @@ protected:
};
// ItemChatLink - link to item
-class ItemChatLink : public ChatLink
+class TC_GAME_API ItemChatLink : public ChatLink
{
public:
ItemChatLink() : ChatLink(), _item(NULL), _suffix(NULL), _property(NULL)
@@ -74,7 +74,7 @@ protected:
};
// QuestChatLink - link to quest
-class QuestChatLink : public ChatLink
+class TC_GAME_API QuestChatLink : public ChatLink
{
public:
QuestChatLink() : ChatLink(), _quest(nullptr), _questLevel(0) { }
@@ -87,7 +87,7 @@ protected:
};
// SpellChatLink - link to quest
-class SpellChatLink : public ChatLink
+class TC_GAME_API SpellChatLink : public ChatLink
{
public:
SpellChatLink() : ChatLink(), _spell(nullptr) { }
@@ -99,7 +99,7 @@ protected:
};
// AchievementChatLink - link to quest
-class AchievementChatLink : public ChatLink
+class TC_GAME_API AchievementChatLink : public ChatLink
{
public:
AchievementChatLink() : ChatLink(), _guid(0), _achievement(NULL)
@@ -116,7 +116,7 @@ protected:
};
// TradeChatLink - link to trade info
-class TradeChatLink : public SpellChatLink
+class TC_GAME_API TradeChatLink : public SpellChatLink
{
public:
TradeChatLink() : SpellChatLink(), _minSkillLevel(0), _maxSkillLevel(0), _guid(0) { }
@@ -129,7 +129,7 @@ private:
};
// TalentChatLink - link to talent
-class TalentChatLink : public SpellChatLink
+class TC_GAME_API TalentChatLink : public SpellChatLink
{
public:
TalentChatLink() : SpellChatLink(), _talentId(0), _rankId(0) { }
@@ -141,7 +141,7 @@ private:
};
// EnchantmentChatLink - link to enchantment
-class EnchantmentChatLink : public SpellChatLink
+class TC_GAME_API EnchantmentChatLink : public SpellChatLink
{
public:
EnchantmentChatLink() : SpellChatLink() { }
@@ -149,7 +149,7 @@ public:
};
// GlyphChatLink - link to glyph
-class GlyphChatLink : public SpellChatLink
+class TC_GAME_API GlyphChatLink : public SpellChatLink
{
public:
GlyphChatLink() : SpellChatLink(), _slotId(0), _glyph(NULL) { }
@@ -159,7 +159,7 @@ private:
GlyphPropertiesEntry const* _glyph;
};
-class LinkExtractor
+class TC_GAME_API LinkExtractor
{
public:
explicit LinkExtractor(const char* msg);
diff --git a/src/server/game/Combat/HostileRefManager.h b/src/server/game/Combat/HostileRefManager.h
index 96152ed46f7..855f9e3d272 100644
--- a/src/server/game/Combat/HostileRefManager.h
+++ b/src/server/game/Combat/HostileRefManager.h
@@ -29,7 +29,7 @@ class SpellInfo;
//=================================================
-class HostileRefManager : public RefManager<Unit, ThreatManager>
+class TC_GAME_API HostileRefManager : public RefManager<Unit, ThreatManager>
{
private:
Unit* iOwner;
diff --git a/src/server/game/Combat/ThreatManager.cpp b/src/server/game/Combat/ThreatManager.cpp
index 588e7b1a93b..9767d69e2aa 100644
--- a/src/server/game/Combat/ThreatManager.cpp
+++ b/src/server/game/Combat/ThreatManager.cpp
@@ -335,7 +335,7 @@ HostileReference* ThreatContainer::selectNextVictim(Creature* attacker, HostileR
{
// current victim is a second choice target, so don't compare threat with it below
if (currentRef == currentVictim)
- currentVictim = NULL;
+ currentVictim = nullptr;
++iter;
continue;
}
@@ -437,12 +437,15 @@ void ThreatManager::_addThreat(Unit* victim, float threat)
if (!ref) // there was no ref => create a new one
{
+ bool isFirst = iThreatContainer.empty();
// threat has to be 0 here
HostileReference* hostileRef = new HostileReference(victim, this, 0);
iThreatContainer.addReference(hostileRef);
hostileRef->addThreat(threat); // now we add the real threat
if (victim->GetTypeId() == TYPEID_PLAYER && victim->ToPlayer()->IsGameMaster())
hostileRef->setOnlineOfflineState(false); // GM is always offline
+ else if (isFirst)
+ setCurrentVictim(hostileRef);
}
}
diff --git a/src/server/game/Combat/ThreatManager.h b/src/server/game/Combat/ThreatManager.h
index 7d20e99c128..a68d803304d 100644
--- a/src/server/game/Combat/ThreatManager.h
+++ b/src/server/game/Combat/ThreatManager.h
@@ -39,14 +39,14 @@ class SpellInfo;
//==============================================================
// Class to calculate the real threat based
-struct ThreatCalcHelper
+struct TC_GAME_API ThreatCalcHelper
{
static float calcThreat(Unit* hatedUnit, Unit* hatingUnit, float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* threatSpell = NULL);
static bool isValidProcess(Unit* hatedUnit, Unit* hatingUnit, SpellInfo const* threatSpell = NULL);
};
//==============================================================
-class HostileReference : public Reference<Unit, ThreatManager>
+class TC_GAME_API HostileReference : public Reference<Unit, ThreatManager>
{
public:
HostileReference(Unit* refUnit, ThreatManager* threatManager, float threat);
@@ -141,7 +141,7 @@ class HostileReference : public Reference<Unit, ThreatManager>
//==============================================================
class ThreatManager;
-class ThreatContainer
+class TC_GAME_API ThreatContainer
{
friend class ThreatManager;
@@ -169,7 +169,7 @@ class ThreatContainer
HostileReference* getMostHated() const
{
- return iThreatList.empty() ? NULL : iThreatList.front();
+ return iThreatList.empty() ? nullptr : iThreatList.front();
}
HostileReference* getReferenceByTarget(Unit* victim) const;
@@ -198,7 +198,7 @@ class ThreatContainer
//=================================================
-class ThreatManager
+class TC_GAME_API ThreatManager
{
public:
friend class HostileReference;
diff --git a/src/server/game/Combat/UnitEvents.h b/src/server/game/Combat/UnitEvents.h
index e501cdaa4a2..f50edcf3c7d 100644
--- a/src/server/game/Combat/UnitEvents.h
+++ b/src/server/game/Combat/UnitEvents.h
@@ -81,7 +81,7 @@ class UnitBaseEvent
//==============================================================
-class ThreatRefStatusChangeEvent : public UnitBaseEvent
+class TC_GAME_API ThreatRefStatusChangeEvent : public UnitBaseEvent
{
private:
HostileReference* iHostileReference;
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp
index 4215a3a5d02..50e3e64ea2c 100644
--- a/src/server/game/Conditions/ConditionMgr.cpp
+++ b/src/server/game/Conditions/ConditionMgr.cpp
@@ -55,7 +55,8 @@ char const* const ConditionMgr::StaticSourceTypeData[CONDITION_SOURCE_TYPE_MAX]
"SmartScript",
"Npc Vendor",
"Spell Proc",
- "Phase Def"
+ "Terrain Swap",
+ "Phase"
};
ConditionMgr::ConditionTypeInfo const ConditionMgr::StaticConditionTypeData[CONDITION_MAX] =
@@ -100,7 +101,9 @@ ConditionMgr::ConditionTypeInfo const ConditionMgr::StaticConditionTypeData[COND
{ "Health Value", true, true, false },
{ "Health Pct", true, true, false },
{ "Realm Achievement", true, false, false },
- { "In Water", false, false, false }
+ { "In Water", false, false, false },
+ { "Terrain Swap", false, false, false },
+ { "Sit/stand state", true, true, false }
};
// Checks if object meets the condition
@@ -432,6 +435,19 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) const
condMeets = unit->IsInWater();
break;
}
+ case CONDITION_STAND_STATE:
+ {
+ if (Unit* unit = object->ToUnit())
+ {
+ if (ConditionValue1 == 0)
+ condMeets = (unit->getStandState() == ConditionValue2);
+ else if (ConditionValue2 == 0)
+ condMeets = unit->IsStandState();
+ else if (ConditionValue2 == 1)
+ condMeets = unit->IsSitState();
+ }
+ break;
+ }
default:
condMeets = false;
break;
@@ -602,6 +618,9 @@ uint32 Condition::GetSearcherTypeMaskForCondition() const
case CONDITION_IN_WATER:
mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER;
break;
+ case CONDITION_STAND_STATE:
+ mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER;
+ break;
default:
ASSERT(false && "Condition::GetSearcherTypeMaskForCondition - missing condition handling!");
break;
@@ -909,6 +928,12 @@ bool ConditionMgr::IsObjectMeetingVendorItemConditions(uint32 creatureId, uint32
return true;
}
+ConditionMgr* ConditionMgr::instance()
+{
+ static ConditionMgr instance;
+ return &instance;
+}
+
void ConditionMgr::LoadConditions(bool isReload)
{
uint32 oldMSTime = getMSTime();
@@ -1633,9 +1658,14 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) const
}
break;
}
- case CONDITION_SOURCE_TYPE_PHASE_DEFINITION:
+ case CONDITION_SOURCE_TYPE_TERRAIN_SWAP:
{
- TC_LOG_ERROR("sql.sql", "CONDITION_SOURCE_TYPE_PHASE_DEFINITION:: is only for 4.3.4 branch, skipped");
+ TC_LOG_ERROR("sql.sql", "CONDITION_SOURCE_TYPE_TERRAIN_SWAP: is only for 6.x branch, skipped");
+ return false;
+ }
+ case CONDITION_SOURCE_TYPE_PHASE:
+ {
+ TC_LOG_ERROR("sql.sql", "CONDITION_SOURCE_TYPE_PHASE: is only for 6.x branch, skipped");
return false;
}
case CONDITION_SOURCE_TYPE_GOSSIP_MENU:
@@ -1653,7 +1683,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) const
{
if (cond->ConditionType == CONDITION_NONE || cond->ConditionType >= CONDITION_MAX)
{
- TC_LOG_ERROR("sql.sql", "%s Invalid ConditionType in `condition` table, ignoring.", cond->ToString().c_str());
+ TC_LOG_ERROR("sql.sql", "%s Invalid ConditionType in `condition` table, ignoring.", cond->ToString(true).c_str());
return false;
}
@@ -2090,6 +2120,31 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) const
}
case CONDITION_IN_WATER:
break;
+ case CONDITION_TERRAIN_SWAP:
+ TC_LOG_ERROR("sql.sql", "%s is not valid for this branch, skipped.", cond->ToString(true).c_str());
+ return false;
+ case CONDITION_STAND_STATE:
+ {
+ bool valid = false;
+ switch (cond->ConditionValue1)
+ {
+ case 0:
+ valid = cond->ConditionValue2 <= UNIT_STAND_STATE_SUBMERGED;
+ break;
+ case 1:
+ valid = cond->ConditionValue2 <= 1;
+ break;
+ default:
+ valid = false;
+ break;
+ }
+ if (!valid)
+ {
+ TC_LOG_ERROR("sql.sql", "%s has non-existing stand state (%u,%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1, cond->ConditionValue2);
+ return false;
+ }
+ break;
+ }
default:
break;
}
diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h
index 35096ae18ff..83e714781c3 100644
--- a/src/server/game/Conditions/ConditionMgr.h
+++ b/src/server/game/Conditions/ConditionMgr.h
@@ -71,7 +71,9 @@ enum ConditionTypes
CONDITION_HP_PCT = 38, // hpPct ComparisonType 0 true if unit's hp matches given pct
CONDITION_REALM_ACHIEVEMENT = 39, // achievement_id 0 0 true if realm achievement is complete
CONDITION_IN_WATER = 40, // 0 0 0 true if unit in water
- CONDITION_MAX = 41 // MAX
+ CONDITION_TERRAIN_SWAP = 41, // only for 6.x
+ CONDITION_STAND_STATE = 42, // stateType state 0 true if unit matches specified sitstate (0,x: has exactly state x; 1,0: any standing state; 1,1: any sitting state;)
+ CONDITION_MAX = 43 // MAX
};
/*! Documentation on implementing a new ConditionSourceType:
@@ -128,8 +130,9 @@ enum ConditionSourceType
CONDITION_SOURCE_TYPE_SMART_EVENT = 22,
CONDITION_SOURCE_TYPE_NPC_VENDOR = 23,
CONDITION_SOURCE_TYPE_SPELL_PROC = 24,
- CONDITION_SOURCE_TYPE_PHASE_DEFINITION = 25, // only 4.3.4
- CONDITION_SOURCE_TYPE_MAX = 26 // MAX
+ CONDITION_SOURCE_TYPE_TERRAIN_SWAP = 25, // only 6.x
+ CONDITION_SOURCE_TYPE_PHASE = 26, // only 6.x
+ CONDITION_SOURCE_TYPE_MAX = 27 // MAX
};
enum RelationType
@@ -156,7 +159,7 @@ enum MaxConditionTargets
MAX_CONDITION_TARGETS = 3
};
-struct ConditionSourceInfo
+struct TC_GAME_API ConditionSourceInfo
{
WorldObject* mConditionTargets[MAX_CONDITION_TARGETS]; // an array of targets available for conditions
Condition const* mLastFailedCondition;
@@ -169,7 +172,7 @@ struct ConditionSourceInfo
}
};
-struct Condition
+struct TC_GAME_API Condition
{
ConditionSourceType SourceType; //SourceTypeOrReferenceId
uint32 SourceGroup;
@@ -221,18 +224,14 @@ typedef std::unordered_map<uint32, ConditionsByEntryMap> ConditionEntriesByCreat
typedef std::unordered_map<std::pair<int32, uint32 /*SAI source_type*/>, ConditionsByEntryMap> SmartEventConditionContainer;
typedef std::unordered_map<uint32, ConditionContainer> ConditionReferenceContainer;//only used for references
-class ConditionMgr
+class TC_GAME_API ConditionMgr
{
private:
ConditionMgr();
~ConditionMgr();
public:
- static ConditionMgr* instance()
- {
- static ConditionMgr instance;
- return &instance;
- }
+ static ConditionMgr* instance();
void LoadConditions(bool isReload = false);
bool isConditionTypeValid(Condition* cond) const;
diff --git a/src/server/game/Conditions/DisableMgr.h b/src/server/game/Conditions/DisableMgr.h
index e74b7a9c319..cae1e0329e8 100644
--- a/src/server/game/Conditions/DisableMgr.h
+++ b/src/server/game/Conditions/DisableMgr.h
@@ -57,11 +57,11 @@ enum MMapDisableTypes
namespace DisableMgr
{
- void LoadDisables();
- bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags = 0);
- void CheckQuestDisables();
- bool IsVMAPDisabledFor(uint32 entry, uint8 flags);
- bool IsPathfindingEnabled(uint32 mapId);
+ TC_GAME_API void LoadDisables();
+ TC_GAME_API bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags = 0);
+ TC_GAME_API void CheckQuestDisables();
+ TC_GAME_API bool IsVMAPDisabledFor(uint32 entry, uint8 flags);
+ TC_GAME_API bool IsPathfindingEnabled(uint32 mapId);
}
#endif //TRINITY_DISABLEMGR_H
diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h
index 56ee1f618dd..beb0bb514cc 100644
--- a/src/server/game/DataStores/DBCStores.h
+++ b/src/server/game/DataStores/DBCStores.h
@@ -27,18 +27,18 @@
#include <list>
typedef std::list<uint32> SimpleFactionsList;
-SimpleFactionsList const* GetFactionTeamList(uint32 faction);
+TC_GAME_API SimpleFactionsList const* GetFactionTeamList(uint32 faction);
-char* GetPetName(uint32 petfamily, uint32 dbclang);
-uint32 GetTalentSpellCost(uint32 spellId);
-TalentSpellPos const* GetTalentSpellPos(uint32 spellId);
+TC_GAME_API char* GetPetName(uint32 petfamily, uint32 dbclang);
+TC_GAME_API uint32 GetTalentSpellCost(uint32 spellId);
+TC_GAME_API TalentSpellPos const* GetTalentSpellPos(uint32 spellId);
-char const* GetRaceName(uint8 race, uint8 locale);
-char const* GetClassName(uint8 class_, uint8 locale);
+TC_GAME_API char const* GetRaceName(uint8 race, uint8 locale);
+TC_GAME_API char const* GetClassName(uint8 class_, uint8 locale);
-WMOAreaTableEntry const* GetWMOAreaTableEntryByTripple(int32 rootid, int32 adtid, int32 groupid);
+TC_GAME_API WMOAreaTableEntry const* GetWMOAreaTableEntryByTripple(int32 rootid, int32 adtid, int32 groupid);
-uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId);
+TC_GAME_API uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId);
enum ContentLevels
{
@@ -46,154 +46,154 @@ enum ContentLevels
CONTENT_61_70,
CONTENT_71_80
};
-ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId);
+TC_GAME_API ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId);
-bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId);
+TC_GAME_API bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId);
-void Zone2MapCoordinates(float &x, float &y, uint32 zone);
-void Map2ZoneCoordinates(float &x, float &y, uint32 zone);
+TC_GAME_API void Zone2MapCoordinates(float &x, float &y, uint32 zone);
+TC_GAME_API void Map2ZoneCoordinates(float &x, float &y, uint32 zone);
typedef std::map<uint32/*pair32(map, diff)*/, MapDifficulty> MapDifficultyMap;
-MapDifficulty const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty);
-MapDifficulty const* GetDownscaledMapDifficultyData(uint32 mapId, Difficulty &difficulty);
+TC_GAME_API MapDifficulty const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty);
+TC_GAME_API MapDifficulty const* GetDownscaledMapDifficultyData(uint32 mapId, Difficulty &difficulty);
-uint32 const* /*[MAX_TALENT_TABS]*/ GetTalentTabPages(uint8 cls);
+TC_GAME_API uint32 const* /*[MAX_TALENT_TABS]*/ GetTalentTabPages(uint8 cls);
-uint32 GetLiquidFlags(uint32 liquidType);
+TC_GAME_API uint32 GetLiquidFlags(uint32 liquidType);
-PvPDifficultyEntry const* GetBattlegroundBracketByLevel(uint32 mapid, uint32 level);
-PvPDifficultyEntry const* GetBattlegroundBracketById(uint32 mapid, BattlegroundBracketId id);
+TC_GAME_API PvPDifficultyEntry const* GetBattlegroundBracketByLevel(uint32 mapid, uint32 level);
+TC_GAME_API PvPDifficultyEntry const* GetBattlegroundBracketById(uint32 mapid, BattlegroundBracketId id);
-CharStartOutfitEntry const* GetCharStartOutfitEntry(uint8 race, uint8 class_, uint8 gender);
-CharSectionsEntry const* GetCharSectionEntry(uint8 race, CharSectionType genType, uint8 gender, uint8 type, uint8 color);
+TC_GAME_API CharStartOutfitEntry const* GetCharStartOutfitEntry(uint8 race, uint8 class_, uint8 gender);
+TC_GAME_API CharSectionsEntry const* GetCharSectionEntry(uint8 race, CharSectionType genType, uint8 gender, uint8 type, uint8 color);
-LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty difficulty);
+TC_GAME_API LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty difficulty);
-uint32 GetDefaultMapLight(uint32 mapId);
+TC_GAME_API uint32 GetDefaultMapLight(uint32 mapId);
typedef std::unordered_multimap<uint32, SkillRaceClassInfoEntry const*> SkillRaceClassInfoMap;
typedef std::pair<SkillRaceClassInfoMap::iterator, SkillRaceClassInfoMap::iterator> SkillRaceClassInfoBounds;
-SkillRaceClassInfoEntry const* GetSkillRaceClassInfo(uint32 skill, uint8 race, uint8 class_);
-
-ResponseCodes ValidateName(std::string const& name, LocaleConstant locale);
-
-EmotesTextSoundEntry const* FindTextSoundEmoteFor(uint32 emote, uint32 race, uint32 gender);
-
-extern DBCStorage <AchievementEntry> sAchievementStore;
-extern DBCStorage <AchievementCriteriaEntry> sAchievementCriteriaStore;
-extern DBCStorage <AreaTableEntry> sAreaTableStore;
-extern DBCStorage <AreaGroupEntry> sAreaGroupStore;
-extern DBCStorage <AreaPOIEntry> sAreaPOIStore;
-extern DBCStorage <AreaTriggerEntry> sAreaTriggerStore;
-extern DBCStorage <AuctionHouseEntry> sAuctionHouseStore;
-extern DBCStorage <BankBagSlotPricesEntry> sBankBagSlotPricesStore;
-extern DBCStorage <BannedAddOnsEntry> sBannedAddOnsStore;
-extern DBCStorage <BarberShopStyleEntry> sBarberShopStyleStore;
-extern DBCStorage <BattlemasterListEntry> sBattlemasterListStore;
-extern DBCStorage <ChatChannelsEntry> sChatChannelsStore;
-extern DBCStorage <CharStartOutfitEntry> sCharStartOutfitStore;
-extern DBCStorage <CharSectionsEntry> sCharSectionsStore;
-extern DBCStorage <CharTitlesEntry> sCharTitlesStore;
-extern DBCStorage <ChrClassesEntry> sChrClassesStore;
-extern DBCStorage <ChrRacesEntry> sChrRacesStore;
-extern DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore;
-extern DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore;
-extern DBCStorage <CreatureDisplayInfoExtraEntry> sCreatureDisplayInfoExtraStore;
-extern DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore;
-extern DBCStorage <CreatureModelDataEntry> sCreatureModelDataStore;
-extern DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore;
-extern DBCStorage <CreatureTypeEntry> sCreatureTypeStore;
-extern DBCStorage <CurrencyTypesEntry> sCurrencyTypesStore;
-extern DBCStorage <DestructibleModelDataEntry> sDestructibleModelDataStore;
-extern DBCStorage <DungeonEncounterEntry> sDungeonEncounterStore;
-extern DBCStorage <DurabilityCostsEntry> sDurabilityCostsStore;
-extern DBCStorage <DurabilityQualityEntry> sDurabilityQualityStore;
-extern DBCStorage <EmotesEntry> sEmotesStore;
-extern DBCStorage <EmotesTextEntry> sEmotesTextStore;
-extern DBCStorage <EmotesTextSoundEntry> sEmotesTextSoundStore;
-extern DBCStorage <FactionEntry> sFactionStore;
-extern DBCStorage <FactionTemplateEntry> sFactionTemplateStore;
-extern DBCStorage <GameObjectDisplayInfoEntry> sGameObjectDisplayInfoStore;
-extern DBCStorage <GemPropertiesEntry> sGemPropertiesStore;
-extern DBCStorage <GlyphPropertiesEntry> sGlyphPropertiesStore;
-extern DBCStorage <GlyphSlotEntry> sGlyphSlotStore;
-
-extern DBCStorage <GtBarberShopCostBaseEntry> sGtBarberShopCostBaseStore;
-extern DBCStorage <GtCombatRatingsEntry> sGtCombatRatingsStore;
-extern DBCStorage <GtChanceToMeleeCritBaseEntry> sGtChanceToMeleeCritBaseStore;
-extern DBCStorage <GtChanceToMeleeCritEntry> sGtChanceToMeleeCritStore;
-extern DBCStorage <GtChanceToSpellCritBaseEntry> sGtChanceToSpellCritBaseStore;
-extern DBCStorage <GtChanceToSpellCritEntry> sGtChanceToSpellCritStore;
-extern DBCStorage <GtNPCManaCostScalerEntry> sGtNPCManaCostScalerStore;
-extern DBCStorage <GtOCTClassCombatRatingScalarEntry> sGtOCTClassCombatRatingScalarStore;
-extern DBCStorage <GtOCTRegenHPEntry> sGtOCTRegenHPStore;
-//extern DBCStorage <GtOCTRegenMPEntry> sGtOCTRegenMPStore; -- not used currently
-extern DBCStorage <GtRegenHPPerSptEntry> sGtRegenHPPerSptStore;
-extern DBCStorage <GtRegenMPPerSptEntry> sGtRegenMPPerSptStore;
-extern DBCStorage <HolidaysEntry> sHolidaysStore;
-extern DBCStorage <ItemEntry> sItemStore;
-extern DBCStorage <ItemBagFamilyEntry> sItemBagFamilyStore;
-//extern DBCStorage <ItemDisplayInfoEntry> sItemDisplayInfoStore; -- not used currently
-extern DBCStorage <ItemExtendedCostEntry> sItemExtendedCostStore;
-extern DBCStorage <ItemLimitCategoryEntry> sItemLimitCategoryStore;
-extern DBCStorage <ItemRandomPropertiesEntry> sItemRandomPropertiesStore;
-extern DBCStorage <ItemRandomSuffixEntry> sItemRandomSuffixStore;
-extern DBCStorage <ItemSetEntry> sItemSetStore;
-extern DBCStorage <LFGDungeonEntry> sLFGDungeonStore;
-extern DBCStorage <LiquidTypeEntry> sLiquidTypeStore;
-extern DBCStorage <LockEntry> sLockStore;
-extern DBCStorage <MailTemplateEntry> sMailTemplateStore;
-extern DBCStorage <MapEntry> sMapStore;
-//extern DBCStorage <MapDifficultyEntry> sMapDifficultyStore; -- use GetMapDifficultyData insteed
-extern MapDifficultyMap sMapDifficultyMap;
-extern DBCStorage <MovieEntry> sMovieStore;
-extern DBCStorage <OverrideSpellDataEntry> sOverrideSpellDataStore;
-extern DBCStorage <PowerDisplayEntry> sPowerDisplayStore;
-extern DBCStorage <QuestSortEntry> sQuestSortStore;
-extern DBCStorage <QuestXPEntry> sQuestXPStore;
-extern DBCStorage <QuestFactionRewEntry> sQuestFactionRewardStore;
-extern DBCStorage <RandomPropertiesPointsEntry> sRandomPropertiesPointsStore;
-extern DBCStorage <ScalingStatDistributionEntry> sScalingStatDistributionStore;
-extern DBCStorage <ScalingStatValuesEntry> sScalingStatValuesStore;
-extern DBCStorage <SkillLineEntry> sSkillLineStore;
-extern DBCStorage <SkillLineAbilityEntry> sSkillLineAbilityStore;
-extern DBCStorage <SkillTiersEntry> sSkillTiersStore;
-extern DBCStorage <SoundEntriesEntry> sSoundEntriesStore;
-extern DBCStorage <SpellCastTimesEntry> sSpellCastTimesStore;
-extern DBCStorage <SpellCategoryEntry> sSpellCategoryStore;
-extern DBCStorage <SpellDifficultyEntry> sSpellDifficultyStore;
-extern DBCStorage <SpellDurationEntry> sSpellDurationStore;
-extern DBCStorage <SpellFocusObjectEntry> sSpellFocusObjectStore;
-extern DBCStorage <SpellItemEnchantmentEntry> sSpellItemEnchantmentStore;
-extern DBCStorage <SpellItemEnchantmentConditionEntry> sSpellItemEnchantmentConditionStore;
-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;
-extern DBCStorage <TaxiPathEntry> sTaxiPathStore;
-extern TaxiMask sTaxiNodesMask;
-extern TaxiMask sOldContinentsNodesMask;
-extern TaxiMask sHordeTaxiNodesMask;
-extern TaxiMask sAllianceTaxiNodesMask;
-extern TaxiMask sDeathKnightTaxiNodesMask;
-extern TaxiPathSetBySource sTaxiPathSetBySource;
-extern TaxiPathNodesByPath sTaxiPathNodesByPath;
-extern DBCStorage <TeamContributionPointsEntry> sTeamContributionPointsStore;
-extern DBCStorage <TotemCategoryEntry> sTotemCategoryStore;
-extern DBCStorage <VehicleEntry> sVehicleStore;
-extern DBCStorage <VehicleSeatEntry> sVehicleSeatStore;
-extern DBCStorage <WMOAreaTableEntry> sWMOAreaTableStore;
-//extern DBCStorage <WorldMapAreaEntry> sWorldMapAreaStore; -- use Zone2MapCoordinates and Map2ZoneCoordinates
-extern DBCStorage <WorldMapOverlayEntry> sWorldMapOverlayStore;
-extern DBCStorage <WorldSafeLocsEntry> sWorldSafeLocsStore;
-
-void LoadDBCStores(const std::string& dataPath);
+TC_GAME_API SkillRaceClassInfoEntry const* GetSkillRaceClassInfo(uint32 skill, uint8 race, uint8 class_);
+
+TC_GAME_API ResponseCodes ValidateName(std::string const& name, LocaleConstant locale);
+
+TC_GAME_API EmotesTextSoundEntry const* FindTextSoundEmoteFor(uint32 emote, uint32 race, uint32 gender);
+
+TC_GAME_API extern DBCStorage <AchievementEntry> sAchievementStore;
+TC_GAME_API extern DBCStorage <AchievementCriteriaEntry> sAchievementCriteriaStore;
+TC_GAME_API extern DBCStorage <AreaTableEntry> sAreaTableStore;
+TC_GAME_API extern DBCStorage <AreaGroupEntry> sAreaGroupStore;
+TC_GAME_API extern DBCStorage <AreaPOIEntry> sAreaPOIStore;
+TC_GAME_API extern DBCStorage <AreaTriggerEntry> sAreaTriggerStore;
+TC_GAME_API extern DBCStorage <AuctionHouseEntry> sAuctionHouseStore;
+TC_GAME_API extern DBCStorage <BankBagSlotPricesEntry> sBankBagSlotPricesStore;
+TC_GAME_API extern DBCStorage <BannedAddOnsEntry> sBannedAddOnsStore;
+TC_GAME_API extern DBCStorage <BarberShopStyleEntry> sBarberShopStyleStore;
+TC_GAME_API extern DBCStorage <BattlemasterListEntry> sBattlemasterListStore;
+TC_GAME_API extern DBCStorage <ChatChannelsEntry> sChatChannelsStore;
+TC_GAME_API extern DBCStorage <CharStartOutfitEntry> sCharStartOutfitStore;
+TC_GAME_API extern DBCStorage <CharSectionsEntry> sCharSectionsStore;
+TC_GAME_API extern DBCStorage <CharTitlesEntry> sCharTitlesStore;
+TC_GAME_API extern DBCStorage <ChrClassesEntry> sChrClassesStore;
+TC_GAME_API extern DBCStorage <ChrRacesEntry> sChrRacesStore;
+TC_GAME_API extern DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore;
+TC_GAME_API extern DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore;
+TC_GAME_API extern DBCStorage <CreatureDisplayInfoExtraEntry> sCreatureDisplayInfoExtraStore;
+TC_GAME_API extern DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore;
+TC_GAME_API extern DBCStorage <CreatureModelDataEntry> sCreatureModelDataStore;
+TC_GAME_API extern DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore;
+TC_GAME_API extern DBCStorage <CreatureTypeEntry> sCreatureTypeStore;
+TC_GAME_API extern DBCStorage <CurrencyTypesEntry> sCurrencyTypesStore;
+TC_GAME_API extern DBCStorage <DestructibleModelDataEntry> sDestructibleModelDataStore;
+TC_GAME_API extern DBCStorage <DungeonEncounterEntry> sDungeonEncounterStore;
+TC_GAME_API extern DBCStorage <DurabilityCostsEntry> sDurabilityCostsStore;
+TC_GAME_API extern DBCStorage <DurabilityQualityEntry> sDurabilityQualityStore;
+TC_GAME_API extern DBCStorage <EmotesEntry> sEmotesStore;
+TC_GAME_API extern DBCStorage <EmotesTextEntry> sEmotesTextStore;
+TC_GAME_API extern DBCStorage <EmotesTextSoundEntry> sEmotesTextSoundStore;
+TC_GAME_API extern DBCStorage <FactionEntry> sFactionStore;
+TC_GAME_API extern DBCStorage <FactionTemplateEntry> sFactionTemplateStore;
+TC_GAME_API extern DBCStorage <GameObjectDisplayInfoEntry> sGameObjectDisplayInfoStore;
+TC_GAME_API extern DBCStorage <GemPropertiesEntry> sGemPropertiesStore;
+TC_GAME_API extern DBCStorage <GlyphPropertiesEntry> sGlyphPropertiesStore;
+TC_GAME_API extern DBCStorage <GlyphSlotEntry> sGlyphSlotStore;
+
+TC_GAME_API extern DBCStorage <GtBarberShopCostBaseEntry> sGtBarberShopCostBaseStore;
+TC_GAME_API extern DBCStorage <GtCombatRatingsEntry> sGtCombatRatingsStore;
+TC_GAME_API extern DBCStorage <GtChanceToMeleeCritBaseEntry> sGtChanceToMeleeCritBaseStore;
+TC_GAME_API extern DBCStorage <GtChanceToMeleeCritEntry> sGtChanceToMeleeCritStore;
+TC_GAME_API extern DBCStorage <GtChanceToSpellCritBaseEntry> sGtChanceToSpellCritBaseStore;
+TC_GAME_API extern DBCStorage <GtChanceToSpellCritEntry> sGtChanceToSpellCritStore;
+TC_GAME_API extern DBCStorage <GtNPCManaCostScalerEntry> sGtNPCManaCostScalerStore;
+TC_GAME_API extern DBCStorage <GtOCTClassCombatRatingScalarEntry> sGtOCTClassCombatRatingScalarStore;
+TC_GAME_API extern DBCStorage <GtOCTRegenHPEntry> sGtOCTRegenHPStore;
+//TC_GAME_API extern DBCStorage <GtOCTRegenMPEntry> sGtOCTRegenMPStore; -- not used currently
+TC_GAME_API extern DBCStorage <GtRegenHPPerSptEntry> sGtRegenHPPerSptStore;
+TC_GAME_API extern DBCStorage <GtRegenMPPerSptEntry> sGtRegenMPPerSptStore;
+TC_GAME_API extern DBCStorage <HolidaysEntry> sHolidaysStore;
+TC_GAME_API extern DBCStorage <ItemEntry> sItemStore;
+TC_GAME_API extern DBCStorage <ItemBagFamilyEntry> sItemBagFamilyStore;
+//TC_GAME_API extern DBCStorage <ItemDisplayInfoEntry> sItemDisplayInfoStore; -- not used currently
+TC_GAME_API extern DBCStorage <ItemExtendedCostEntry> sItemExtendedCostStore;
+TC_GAME_API extern DBCStorage <ItemLimitCategoryEntry> sItemLimitCategoryStore;
+TC_GAME_API extern DBCStorage <ItemRandomPropertiesEntry> sItemRandomPropertiesStore;
+TC_GAME_API extern DBCStorage <ItemRandomSuffixEntry> sItemRandomSuffixStore;
+TC_GAME_API extern DBCStorage <ItemSetEntry> sItemSetStore;
+TC_GAME_API extern DBCStorage <LFGDungeonEntry> sLFGDungeonStore;
+TC_GAME_API extern DBCStorage <LiquidTypeEntry> sLiquidTypeStore;
+TC_GAME_API extern DBCStorage <LockEntry> sLockStore;
+TC_GAME_API extern DBCStorage <MailTemplateEntry> sMailTemplateStore;
+TC_GAME_API extern DBCStorage <MapEntry> sMapStore;
+//TC_GAME_API extern DBCStorage <MapDifficultyEntry> sMapDifficultyStore; -- use GetMapDifficultyData insteed
+TC_GAME_API extern MapDifficultyMap sMapDifficultyMap;
+TC_GAME_API extern DBCStorage <MovieEntry> sMovieStore;
+TC_GAME_API extern DBCStorage <OverrideSpellDataEntry> sOverrideSpellDataStore;
+TC_GAME_API extern DBCStorage <PowerDisplayEntry> sPowerDisplayStore;
+TC_GAME_API extern DBCStorage <QuestSortEntry> sQuestSortStore;
+TC_GAME_API extern DBCStorage <QuestXPEntry> sQuestXPStore;
+TC_GAME_API extern DBCStorage <QuestFactionRewEntry> sQuestFactionRewardStore;
+TC_GAME_API extern DBCStorage <RandomPropertiesPointsEntry> sRandomPropertiesPointsStore;
+TC_GAME_API extern DBCStorage <ScalingStatDistributionEntry> sScalingStatDistributionStore;
+TC_GAME_API extern DBCStorage <ScalingStatValuesEntry> sScalingStatValuesStore;
+TC_GAME_API extern DBCStorage <SkillLineEntry> sSkillLineStore;
+TC_GAME_API extern DBCStorage <SkillLineAbilityEntry> sSkillLineAbilityStore;
+TC_GAME_API extern DBCStorage <SkillTiersEntry> sSkillTiersStore;
+TC_GAME_API extern DBCStorage <SoundEntriesEntry> sSoundEntriesStore;
+TC_GAME_API extern DBCStorage <SpellCastTimesEntry> sSpellCastTimesStore;
+TC_GAME_API extern DBCStorage <SpellCategoryEntry> sSpellCategoryStore;
+TC_GAME_API extern DBCStorage <SpellDifficultyEntry> sSpellDifficultyStore;
+TC_GAME_API extern DBCStorage <SpellDurationEntry> sSpellDurationStore;
+TC_GAME_API extern DBCStorage <SpellFocusObjectEntry> sSpellFocusObjectStore;
+TC_GAME_API extern DBCStorage <SpellItemEnchantmentEntry> sSpellItemEnchantmentStore;
+TC_GAME_API extern DBCStorage <SpellItemEnchantmentConditionEntry> sSpellItemEnchantmentConditionStore;
+TC_GAME_API extern PetFamilySpellsStore sPetFamilySpellsStore;
+TC_GAME_API extern DBCStorage <SpellRadiusEntry> sSpellRadiusStore;
+TC_GAME_API extern DBCStorage <SpellRangeEntry> sSpellRangeStore;
+TC_GAME_API extern DBCStorage <SpellRuneCostEntry> sSpellRuneCostStore;
+TC_GAME_API extern DBCStorage <SpellShapeshiftEntry> sSpellShapeshiftStore;
+TC_GAME_API extern DBCStorage <SpellEntry> sSpellStore;
+TC_GAME_API extern DBCStorage <StableSlotPricesEntry> sStableSlotPricesStore;
+TC_GAME_API extern DBCStorage <SummonPropertiesEntry> sSummonPropertiesStore;
+TC_GAME_API extern DBCStorage <TalentEntry> sTalentStore;
+TC_GAME_API extern DBCStorage <TalentTabEntry> sTalentTabStore;
+TC_GAME_API extern DBCStorage <TaxiNodesEntry> sTaxiNodesStore;
+TC_GAME_API extern DBCStorage <TaxiPathEntry> sTaxiPathStore;
+TC_GAME_API extern TaxiMask sTaxiNodesMask;
+TC_GAME_API extern TaxiMask sOldContinentsNodesMask;
+TC_GAME_API extern TaxiMask sHordeTaxiNodesMask;
+TC_GAME_API extern TaxiMask sAllianceTaxiNodesMask;
+TC_GAME_API extern TaxiMask sDeathKnightTaxiNodesMask;
+TC_GAME_API extern TaxiPathSetBySource sTaxiPathSetBySource;
+TC_GAME_API extern TaxiPathNodesByPath sTaxiPathNodesByPath;
+TC_GAME_API extern DBCStorage <TeamContributionPointsEntry> sTeamContributionPointsStore;
+TC_GAME_API extern DBCStorage <TotemCategoryEntry> sTotemCategoryStore;
+TC_GAME_API extern DBCStorage <VehicleEntry> sVehicleStore;
+TC_GAME_API extern DBCStorage <VehicleSeatEntry> sVehicleSeatStore;
+TC_GAME_API extern DBCStorage <WMOAreaTableEntry> sWMOAreaTableStore;
+//TC_GAME_API extern DBCStorage <WorldMapAreaEntry> sWorldMapAreaStore; -- use Zone2MapCoordinates and Map2ZoneCoordinates
+TC_GAME_API extern DBCStorage <WorldMapOverlayEntry> sWorldMapOverlayStore;
+TC_GAME_API extern DBCStorage <WorldSafeLocsEntry> sWorldSafeLocsStore;
+
+TC_GAME_API void LoadDBCStores(const std::string& dataPath);
#endif
diff --git a/src/server/game/DungeonFinding/LFG.h b/src/server/game/DungeonFinding/LFG.h
index 73c123723b1..b837a0df272 100644
--- a/src/server/game/DungeonFinding/LFG.h
+++ b/src/server/game/DungeonFinding/LFG.h
@@ -101,9 +101,9 @@ typedef std::map<ObjectGuid, LfgLockMap> LfgLockPartyMap;
typedef std::map<ObjectGuid, uint8> LfgRolesMap;
typedef std::map<ObjectGuid, ObjectGuid> LfgGroupsMap;
-std::string ConcatenateDungeons(LfgDungeonSet const& dungeons);
-std::string GetRolesString(uint8 roles);
-std::string GetStateString(LfgState state);
+TC_GAME_API std::string ConcatenateDungeons(LfgDungeonSet const& dungeons);
+TC_GAME_API std::string GetRolesString(uint8 roles);
+TC_GAME_API std::string GetStateString(LfgState state);
} // namespace lfg
diff --git a/src/server/game/DungeonFinding/LFGGroupData.h b/src/server/game/DungeonFinding/LFGGroupData.h
index 7ae4777cd4d..62a41b6b350 100644
--- a/src/server/game/DungeonFinding/LFGGroupData.h
+++ b/src/server/game/DungeonFinding/LFGGroupData.h
@@ -31,7 +31,7 @@ enum LfgGroupEnum
/**
Stores all lfg data needed about a group.
*/
-class LfgGroupData
+class TC_GAME_API LfgGroupData
{
public:
LfgGroupData();
diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp
index b0a1777f19a..fe997bc0343 100644
--- a/src/server/game/DungeonFinding/LFGMgr.cpp
+++ b/src/server/game/DungeonFinding/LFGMgr.cpp
@@ -261,6 +261,12 @@ void LFGMgr::LoadLFGDungeons(bool reload /* = false */)
}
}
+LFGMgr* LFGMgr::instance()
+{
+ static LFGMgr instance;
+ return &instance;
+}
+
void LFGMgr::Update(uint32 diff)
{
if (!isOptionEnabled(LFG_OPTION_ENABLE_DUNGEON_FINDER | LFG_OPTION_ENABLE_RAID_BROWSER))
diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h
index 90a8d802f9d..c72c0a3cdab 100644
--- a/src/server/game/DungeonFinding/LFGMgr.h
+++ b/src/server/game/DungeonFinding/LFGMgr.h
@@ -289,18 +289,14 @@ struct LFGDungeonData
uint32 Entry() const { return id + (type << 24); }
};
-class LFGMgr
+class TC_GAME_API LFGMgr
{
private:
LFGMgr();
~LFGMgr();
public:
- static LFGMgr* instance()
- {
- static LFGMgr instance;
- return &instance;
- }
+ static LFGMgr* instance();
// Functions used outside lfg namespace
void Update(uint32 diff);
diff --git a/src/server/game/DungeonFinding/LFGPlayerData.h b/src/server/game/DungeonFinding/LFGPlayerData.h
index 859317ca956..91e4153a6d5 100644
--- a/src/server/game/DungeonFinding/LFGPlayerData.h
+++ b/src/server/game/DungeonFinding/LFGPlayerData.h
@@ -26,7 +26,7 @@ namespace lfg
/**
Stores all lfg data needed about the player.
*/
-class LfgPlayerData
+class TC_GAME_API LfgPlayerData
{
public:
LfgPlayerData();
diff --git a/src/server/game/DungeonFinding/LFGQueue.h b/src/server/game/DungeonFinding/LFGQueue.h
index ed8193ab605..7c35c4d04e3 100644
--- a/src/server/game/DungeonFinding/LFGQueue.h
+++ b/src/server/game/DungeonFinding/LFGQueue.h
@@ -83,7 +83,7 @@ typedef std::map<ObjectGuid, LfgQueueData> LfgQueueDataContainer;
/**
Stores all data related to queue
*/
-class LFGQueue
+class TC_GAME_API LFGQueue
{
public:
diff --git a/src/server/game/DungeonFinding/LFGScripts.h b/src/server/game/DungeonFinding/LFGScripts.h
index 377614bc55d..ec64604a282 100644
--- a/src/server/game/DungeonFinding/LFGScripts.h
+++ b/src/server/game/DungeonFinding/LFGScripts.h
@@ -29,7 +29,7 @@ class Group;
namespace lfg
{
-class LFGPlayerScript : public PlayerScript
+class TC_GAME_API LFGPlayerScript : public PlayerScript
{
public:
LFGPlayerScript();
@@ -40,7 +40,7 @@ class LFGPlayerScript : public PlayerScript
void OnMapChanged(Player* player) override;
};
-class LFGGroupScript : public GroupScript
+class TC_GAME_API LFGGroupScript : public GroupScript
{
public:
LFGGroupScript();
diff --git a/src/server/game/Entities/Corpse/Corpse.cpp b/src/server/game/Entities/Corpse/Corpse.cpp
index 8f700cc636f..22bb9bca712 100644
--- a/src/server/game/Entities/Corpse/Corpse.cpp
+++ b/src/server/game/Entities/Corpse/Corpse.cpp
@@ -147,7 +147,7 @@ bool Corpse::LoadCorpseFromDB(ObjectGuid::LowType guid, Field* fields)
SetObjectScale(1.0f);
SetUInt32Value(CORPSE_FIELD_DISPLAY_ID, fields[5].GetUInt32());
- _LoadIntoDataField(fields[6].GetCString(), CORPSE_FIELD_ITEM, EQUIPMENT_SLOT_END);
+ _LoadIntoDataField(fields[6].GetString(), CORPSE_FIELD_ITEM, EQUIPMENT_SLOT_END);
SetUInt32Value(CORPSE_FIELD_BYTES_1, fields[7].GetUInt32());
SetUInt32Value(CORPSE_FIELD_BYTES_2, fields[8].GetUInt32());
SetUInt32Value(CORPSE_FIELD_GUILD, fields[9].GetUInt32());
diff --git a/src/server/game/Entities/Corpse/Corpse.h b/src/server/game/Entities/Corpse/Corpse.h
index 5062645eac8..c9dd0b01509 100644
--- a/src/server/game/Entities/Corpse/Corpse.h
+++ b/src/server/game/Entities/Corpse/Corpse.h
@@ -46,7 +46,7 @@ enum CorpseFlags
CORPSE_FLAG_LOOTABLE = 0x20
};
-class Corpse : public WorldObject, public GridObject<Corpse>
+class TC_GAME_API Corpse : public WorldObject, public GridObject<Corpse>
{
public:
explicit Corpse(CorpseType type = CORPSE_BONES);
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 5d62b740947..08f8181c303 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -578,7 +578,8 @@ void Creature::Update(uint32 diff)
IsAIEnabled = true;
if (!IsInEvadeMode() && LastCharmerGUID)
if (Unit* charmer = ObjectAccessor::GetUnit(*this, LastCharmerGUID))
- i_AI->AttackStart(charmer);
+ if (CanStartAttack(charmer, true))
+ i_AI->AttackStart(charmer);
LastCharmerGUID.Clear();
}
@@ -1356,8 +1357,8 @@ bool Creature::LoadCreatureFromDB(ObjectGuid::LowType spawnId, Map* map, bool ad
m_deathState = DEAD;
if (CanFly())
{
- float tz = map->GetHeight(GetPhaseMask(), data->posX, data->posY, data->posZ, false);
- if (data->posZ - tz > 0.1f)
+ float tz = map->GetHeight(GetPhaseMask(), data->posX, data->posY, data->posZ, true, MAX_FALL_DISTANCE);
+ if (data->posZ - tz > 0.1f && Trinity::IsValidMapCoord(tz))
Relocate(data->posX, data->posY, tz);
}
}
@@ -2774,12 +2775,12 @@ bool Creature::FocusTarget(Spell const* focusSpell, WorldObject const* target)
SetGuidValue(UNIT_FIELD_TARGET, newTarget);
if (target)
SetFacingToObject(target);
-
+
if ( // here we determine if the (relatively expensive) forced update is worth it, or whether we can afford to wait until the scheduled update tick
( // only require instant update for spells that actually have a visual
focusSpell->GetSpellInfo()->SpellVisual[0] ||
focusSpell->GetSpellInfo()->SpellVisual[1]
- ) && (
+ ) && (
!focusSpell->GetCastTime() || // if the spell is instant cast
focusSpell->GetSpellInfo()->HasAttribute(SPELL_ATTR5_DONT_TURN_DURING_CAST) // client gets confused if we attempt to turn at the regularly scheduled update packet
)
@@ -2803,14 +2804,16 @@ bool Creature::FocusTarget(Spell const* focusSpell, WorldObject const* target)
}
// tell the creature that it should reacquire its current target after the cast is done (this is handled in ::Attack)
- MustReacquireTarget();
+ // player pets don't need to do this, as they automatically reacquire their target on focus release
+ if (!IsPet())
+ MustReacquireTarget();
bool canTurnDuringCast = !focusSpell->GetSpellInfo()->HasAttribute(SPELL_ATTR5_DONT_TURN_DURING_CAST);
// Face the target - we need to do this before the unit state is modified for no-turn spells
if (target)
SetInFront(target);
else if (!canTurnDuringCast)
- if(Unit* victim = GetVictim())
+ if (Unit* victim = GetVictim())
SetInFront(victim); // ensure server-side orientation is correct at beginning of cast
if (!canTurnDuringCast)
@@ -2853,13 +2856,16 @@ void Creature::ReleaseFocus(Spell const* focusSpell, bool withDelay)
if (focusSpell && focusSpell != _focusSpell)
return;
- SetGuidValue(UNIT_FIELD_TARGET, ObjectGuid::Empty);
+ if (IsPet() && GetVictim()) // player pets do not use delay system
+ SetGuidValue(UNIT_FIELD_TARGET, EnsureVictim()->GetGUID());
+ else
+ SetGuidValue(UNIT_FIELD_TARGET, ObjectGuid::Empty);
if (_focusSpell->GetSpellInfo()->HasAttribute(SPELL_ATTR5_DONT_TURN_DURING_CAST))
ClearUnitState(UNIT_STATE_CANNOT_TURN);
_focusSpell = nullptr;
- _focusDelay = withDelay ? getMSTime() : 0; // don't allow re-target right away to prevent visual bugs
+ _focusDelay = (!IsPet() && withDelay) ? getMSTime() : 0; // don't allow re-target right away to prevent visual bugs
}
void Creature::StartPickPocketRefillTimer()
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index 49bd854ef2f..c4b6776f30b 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -75,7 +75,7 @@ enum CreatureFlagsExtra
#define CREATURE_MAX_SPELLS 8
// from `creature_template` table
-struct CreatureTemplate
+struct TC_GAME_API CreatureTemplate
{
uint32 Entry;
uint32 DifficultyEntry[MAX_DIFFICULTY - 1];
@@ -179,7 +179,7 @@ typedef std::unordered_map<uint32, CreatureTemplate> CreatureTemplateContainer;
#pragma pack(push, 1)
// Defines base stats for creatures (used to calculate HP/mana/armor/attackpower/rangedattackpower/all damage).
-struct CreatureBaseStats
+struct TC_GAME_API CreatureBaseStats
{
uint32 BaseHealth[MAX_EXPANSIONS];
uint32 BaseMana;
@@ -401,7 +401,7 @@ struct TrainerSpell
typedef std::unordered_map<uint32 /*spellid*/, TrainerSpell> TrainerSpellMap;
-struct TrainerSpellData
+struct TC_GAME_API TrainerSpellData
{
TrainerSpellData() : trainerType(0) { }
~TrainerSpellData() { spellList.clear(); }
@@ -421,7 +421,7 @@ struct TrainerSpellData
typedef std::vector<uint8> CreatureTextRepeatIds;
typedef std::unordered_map<uint8, CreatureTextRepeatIds> CreatureTextRepeatGroup;
-class Creature : public Unit, public GridObject<Creature>, public MapObject
+class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public MapObject
{
public:
@@ -479,7 +479,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject
bool AIM_Initialize(CreatureAI* ai = NULL);
void Motion_Initialize();
- CreatureAI* AI() const { return (CreatureAI*)i_AI; }
+ CreatureAI* AI() const { return reinterpret_cast<CreatureAI*>(i_AI); }
bool SetWalk(bool enable) override;
bool SetDisableGravity(bool disable, bool packetOnly = false) override;
@@ -754,7 +754,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject
CreatureTextRepeatGroup m_textRepeat;
};
-class AssistDelayEvent : public BasicEvent
+class TC_GAME_API AssistDelayEvent : public BasicEvent
{
public:
AssistDelayEvent(ObjectGuid victim, Unit& owner) : BasicEvent(), m_victim(victim), m_owner(owner) { }
@@ -769,7 +769,7 @@ class AssistDelayEvent : public BasicEvent
Unit& m_owner;
};
-class ForcedDespawnDelayEvent : public BasicEvent
+class TC_GAME_API ForcedDespawnDelayEvent : public BasicEvent
{
public:
ForcedDespawnDelayEvent(Creature& owner) : BasicEvent(), m_owner(owner) { }
diff --git a/src/server/game/Entities/Creature/CreatureGroups.cpp b/src/server/game/Entities/Creature/CreatureGroups.cpp
index 9f26c927374..0c41089efce 100644
--- a/src/server/game/Entities/Creature/CreatureGroups.cpp
+++ b/src/server/game/Entities/Creature/CreatureGroups.cpp
@@ -30,6 +30,12 @@ FormationMgr::~FormationMgr()
delete itr->second;
}
+FormationMgr* FormationMgr::instance()
+{
+ static FormationMgr instance;
+ return &instance;
+}
+
void FormationMgr::AddCreatureToGroup(uint32 leaderGuid, Creature* creature)
{
Map* map = creature->FindMap();
diff --git a/src/server/game/Entities/Creature/CreatureGroups.h b/src/server/game/Entities/Creature/CreatureGroups.h
index 7b16585a996..14472a30293 100644
--- a/src/server/game/Entities/Creature/CreatureGroups.h
+++ b/src/server/game/Entities/Creature/CreatureGroups.h
@@ -38,18 +38,14 @@ struct FormationInfo
typedef std::unordered_map<uint32/*memberDBGUID*/, FormationInfo*> CreatureGroupInfoType;
-class FormationMgr
+class TC_GAME_API FormationMgr
{
private:
FormationMgr() { }
~FormationMgr();
public:
- static FormationMgr* instance()
- {
- static FormationMgr instance;
- return &instance;
- }
+ static FormationMgr* instance();
void AddCreatureToGroup(uint32 group_id, Creature* creature);
void RemoveCreatureFromGroup(CreatureGroup* group, Creature* creature);
@@ -57,7 +53,7 @@ class FormationMgr
CreatureGroupInfoType CreatureGroupMap;
};
-class CreatureGroup
+class TC_GAME_API CreatureGroup
{
private:
Creature* m_leader; //Important do not forget sometimes to work with pointers instead synonims :D:D
diff --git a/src/server/game/Entities/Creature/GossipDef.h b/src/server/game/Entities/Creature/GossipDef.h
index 1e64e83c86a..01b27032286 100644
--- a/src/server/game/Entities/Creature/GossipDef.h
+++ b/src/server/game/Entities/Creature/GossipDef.h
@@ -157,7 +157,7 @@ struct QuestMenuItem
typedef std::vector<QuestMenuItem> QuestMenuItemList;
-class GossipMenu
+class TC_GAME_API GossipMenu
{
public:
GossipMenu();
@@ -222,7 +222,7 @@ class GossipMenu
LocaleConstant _locale;
};
-class QuestMenu
+class TC_GAME_API QuestMenu
{
public:
QuestMenu();
@@ -252,7 +252,7 @@ class QuestMenu
QuestMenuItemList _questMenuItems;
};
-class PlayerMenu
+class TC_GAME_API PlayerMenu
{
public:
explicit PlayerMenu(WorldSession* session);
diff --git a/src/server/game/Entities/Creature/TemporarySummon.cpp b/src/server/game/Entities/Creature/TemporarySummon.cpp
index 8bf3a1e2846..12e3af3c290 100644
--- a/src/server/game/Entities/Creature/TemporarySummon.cpp
+++ b/src/server/game/Entities/Creature/TemporarySummon.cpp
@@ -227,6 +227,11 @@ void TempSummon::InitSummon()
}
}
+void TempSummon::UpdateObjectVisibilityOnCreate()
+{
+ WorldObject::UpdateObjectVisibility(true);
+}
+
void TempSummon::SetTempSummonType(TempSummonType type)
{
m_type = type;
diff --git a/src/server/game/Entities/Creature/TemporarySummon.h b/src/server/game/Entities/Creature/TemporarySummon.h
index 6d058f405a8..87cb883b261 100644
--- a/src/server/game/Entities/Creature/TemporarySummon.h
+++ b/src/server/game/Entities/Creature/TemporarySummon.h
@@ -37,7 +37,7 @@ struct TempSummonData
uint32 time; ///< Despawn time, usable only with certain temp summon types
};
-class TempSummon : public Creature
+class TC_GAME_API TempSummon : public Creature
{
public:
explicit TempSummon(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject);
@@ -45,6 +45,7 @@ class TempSummon : public Creature
void Update(uint32 time) override;
virtual void InitStats(uint32 lifetime);
virtual void InitSummon();
+ void UpdateObjectVisibilityOnCreate() override;
virtual void UnSummon(uint32 msTime = 0);
void RemoveFromWorld() override;
void SetTempSummonType(TempSummonType type);
@@ -63,7 +64,7 @@ class TempSummon : public Creature
ObjectGuid m_summonerGUID;
};
-class Minion : public TempSummon
+class TC_GAME_API Minion : public TempSummon
{
public:
Minion(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject);
@@ -81,7 +82,7 @@ class Minion : public TempSummon
float m_followAngle;
};
-class Guardian : public Minion
+class TC_GAME_API Guardian : public Minion
{
public:
Guardian(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject);
@@ -105,7 +106,7 @@ class Guardian : public Minion
float m_statFromOwner[MAX_STATS];
};
-class Puppet : public Minion
+class TC_GAME_API Puppet : public Minion
{
public:
Puppet(SummonPropertiesEntry const* properties, Unit* owner);
@@ -115,7 +116,7 @@ class Puppet : public Minion
void RemoveFromWorld() override;
};
-class ForcedUnsummonDelayEvent : public BasicEvent
+class TC_GAME_API ForcedUnsummonDelayEvent : public BasicEvent
{
public:
ForcedUnsummonDelayEvent(TempSummon& owner) : BasicEvent(), m_owner(owner) { }
diff --git a/src/server/game/Entities/DynamicObject/DynamicObject.h b/src/server/game/Entities/DynamicObject/DynamicObject.h
index 9443a5b5b89..d7c1f0190fd 100644
--- a/src/server/game/Entities/DynamicObject/DynamicObject.h
+++ b/src/server/game/Entities/DynamicObject/DynamicObject.h
@@ -32,7 +32,7 @@ enum DynamicObjectType
DYNAMIC_OBJECT_FARSIGHT_FOCUS = 0x2
};
-class DynamicObject : public WorldObject, public GridObject<DynamicObject>, public MapObject
+class TC_GAME_API DynamicObject : public WorldObject, public GridObject<DynamicObject>, public MapObject
{
public:
DynamicObject(bool isWorldObject);
diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h
index 7be78556a50..49f94013ac2 100644
--- a/src/server/game/Entities/GameObject/GameObject.h
+++ b/src/server/game/Entities/GameObject/GameObject.h
@@ -640,7 +640,7 @@ class GameObjectModel;
// 5 sec for bobber catch
#define FISHING_BOBBER_READY_TIME 5
-class GameObject : public WorldObject, public GridObject<GameObject>, public MapObject
+class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>, public MapObject
{
public:
explicit GameObject();
diff --git a/src/server/game/Entities/Item/Container/Bag.h b/src/server/game/Entities/Item/Container/Bag.h
index 5bfafa4238c..89615f94e52 100644
--- a/src/server/game/Entities/Item/Container/Bag.h
+++ b/src/server/game/Entities/Item/Container/Bag.h
@@ -25,7 +25,7 @@
#include "Item.h"
#include "ItemPrototype.h"
-class Bag : public Item
+class TC_GAME_API Bag : public Item
{
public:
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp
index 70fa4714547..773d5a05772 100644
--- a/src/server/game/Entities/Item/Item.cpp
+++ b/src/server/game/Entities/Item/Item.cpp
@@ -447,8 +447,7 @@ bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid owner_guid, Field* fi
need_save = true;
}
- std::string enchants = fields[6].GetString();
- _LoadIntoDataField(enchants.c_str(), ITEM_FIELD_ENCHANTMENT_1_1, MAX_ENCHANTMENT_SLOT * MAX_ENCHANTMENT_OFFSET);
+ _LoadIntoDataField(fields[6].GetString(), ITEM_FIELD_ENCHANTMENT_1_1, MAX_ENCHANTMENT_SLOT * MAX_ENCHANTMENT_OFFSET);
SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, fields[7].GetInt16());
// recalculate suffix factor
if (GetItemRandomPropertyId() < 0)
diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h
index 378d7f5e2e4..8658200c28c 100644
--- a/src/server/game/Entities/Item/Item.h
+++ b/src/server/game/Entities/Item/Item.h
@@ -203,7 +203,7 @@ enum ItemUpdateState
bool ItemCanGoIntoBag(ItemTemplate const* proto, ItemTemplate const* pBagProto);
-class Item : public Object
+class TC_GAME_API Item : public Object
{
public:
static Item* CreateItem(uint32 itemEntry, uint32 count, Player const* player = NULL);
diff --git a/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp b/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp
index a7b410bc04b..b44a3e7ad7b 100644
--- a/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp
+++ b/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp
@@ -44,7 +44,7 @@ typedef std::unordered_map<uint32, EnchStoreList> EnchantmentStore;
static EnchantmentStore RandomItemEnch;
-void LoadRandomEnchantmentsTable()
+TC_GAME_API void LoadRandomEnchantmentsTable()
{
uint32 oldMSTime = getMSTime();
@@ -77,7 +77,7 @@ void LoadRandomEnchantmentsTable()
TC_LOG_ERROR("server.loading", ">> Loaded 0 Item Enchantment definitions. DB table `item_enchantment_template` is empty.");
}
-uint32 GetItemEnchantMod(int32 entry)
+TC_GAME_API uint32 GetItemEnchantMod(int32 entry)
{
if (!entry)
return 0;
@@ -118,7 +118,7 @@ uint32 GetItemEnchantMod(int32 entry)
return 0;
}
-uint32 GenerateEnchSuffixFactor(uint32 item_id)
+TC_GAME_API uint32 GenerateEnchSuffixFactor(uint32 item_id)
{
ItemTemplate const* itemProto = sObjectMgr->GetItemTemplate(item_id);
diff --git a/src/server/game/Entities/Item/ItemEnchantmentMgr.h b/src/server/game/Entities/Item/ItemEnchantmentMgr.h
index 2d5c27177b1..8ce9ae780fe 100644
--- a/src/server/game/Entities/Item/ItemEnchantmentMgr.h
+++ b/src/server/game/Entities/Item/ItemEnchantmentMgr.h
@@ -21,8 +21,9 @@
#include "Common.h"
-void LoadRandomEnchantmentsTable();
-uint32 GetItemEnchantMod(int32 entry);
-uint32 GenerateEnchSuffixFactor(uint32 item_id);
+TC_GAME_API void LoadRandomEnchantmentsTable();
+TC_GAME_API uint32 GetItemEnchantMod(int32 entry);
+TC_GAME_API uint32 GenerateEnchSuffixFactor(uint32 item_id);
+
#endif
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 4877ff094e1..836a041abc3 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -1878,7 +1878,9 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert
AddToMap(summon->ToCreature());
summon->InitSummon();
- //ObjectAccessor::UpdateObjectVisibility(summon);
+ // call MoveInLineOfSight for nearby creatures
+ Trinity::AIRelocationNotifier notifier(*summon);
+ summon->VisitNearbyObject(GetVisibilityRange(), notifier);
return summon;
}
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index 419044081e3..029a8c08fd7 100644
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -90,7 +90,7 @@ class ZoneScript;
typedef std::unordered_map<Player*, UpdateData> UpdateDataMapType;
-class Object
+class TC_GAME_API Object
{
public:
virtual ~Object();
@@ -397,7 +397,7 @@ enum MapObjectCellMoveState
MAP_OBJECT_CELL_MOVE_INACTIVE, //in move list but should not move
};
-class MapObject
+class TC_GAME_API MapObject
{
friend class Map; //map for moving creatures
friend class ObjectGridLoader; //grid loader for loading creatures
@@ -422,7 +422,7 @@ class MapObject
}
};
-class WorldObject : public Object, public WorldLocation
+class TC_GAME_API WorldObject : public Object, public WorldLocation
{
protected:
explicit WorldObject(bool isWorldObject); //note: here it means if it is in grid object list or world object list
@@ -555,6 +555,11 @@ class WorldObject : public Object, public WorldLocation
void DestroyForNearbyPlayers();
virtual void UpdateObjectVisibility(bool forced = true);
+ virtual void UpdateObjectVisibilityOnCreate()
+ {
+ UpdateObjectVisibility(true);
+ }
+
void BuildUpdate(UpdateDataMapType&) override;
void AddToObjectUpdate() override;
diff --git a/src/server/game/Entities/Object/ObjectGuid.cpp b/src/server/game/Entities/Object/ObjectGuid.cpp
index 3e2bd000b6e..2fb766c5201 100644
--- a/src/server/game/Entities/Object/ObjectGuid.cpp
+++ b/src/server/game/Entities/Object/ObjectGuid.cpp
@@ -95,4 +95,19 @@ void ObjectGuidGeneratorBase::HandleCounterOverflow(HighGuid high)
{
TC_LOG_ERROR("misc", "%s guid overflow!! Can't continue, shutting down server. ", ObjectGuid::GetTypeName(high));
World::StopNow(ERROR_EXIT_CODE);
-} \ No newline at end of file
+}
+
+#define GUID_TRAIT_INSTANTIATE_GUID( HIGH_GUID ) \
+ template class TC_GAME_API ObjectGuidGenerator< HIGH_GUID >;
+
+GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Container)
+GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Player)
+GUID_TRAIT_INSTANTIATE_GUID(HighGuid::GameObject)
+GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Transport)
+GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Unit)
+GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Pet)
+GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Vehicle)
+GUID_TRAIT_INSTANTIATE_GUID(HighGuid::DynamicObject)
+GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Mo_Transport)
+GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Instance)
+GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Group)
diff --git a/src/server/game/Entities/Object/ObjectGuid.h b/src/server/game/Entities/Object/ObjectGuid.h
index 44644421567..71c66622790 100644
--- a/src/server/game/Entities/Object/ObjectGuid.h
+++ b/src/server/game/Entities/Object/ObjectGuid.h
@@ -111,7 +111,7 @@ struct PackedGuidReader
ObjectGuid* GuidPtr;
};
-class ObjectGuid
+class TC_GAME_API ObjectGuid
{
public:
static ObjectGuid const Empty;
@@ -252,9 +252,9 @@ typedef std::unordered_set<ObjectGuid> GuidUnorderedSet;
// minimum buffer size for packed guid is 9 bytes
#define PACKED_GUID_MIN_BUFFER_SIZE 9
-class PackedGuid
+class TC_GAME_API PackedGuid
{
- friend ByteBuffer& operator<<(ByteBuffer& buf, PackedGuid const& guid);
+ friend TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, PackedGuid const& guid);
public:
explicit PackedGuid() : _packedGuid(PACKED_GUID_MIN_BUFFER_SIZE) { _packedGuid.appendPackGUID(0); }
@@ -270,8 +270,7 @@ class PackedGuid
ByteBuffer _packedGuid;
};
-
-class ObjectGuidGeneratorBase
+class TC_GAME_API ObjectGuidGeneratorBase
{
public:
ObjectGuidGeneratorBase(ObjectGuid::LowType start = 1) : _nextGuid(start) { }
@@ -286,7 +285,7 @@ protected:
};
template<HighGuid high>
-class ObjectGuidGenerator : public ObjectGuidGeneratorBase
+class TC_GAME_API ObjectGuidGenerator : public ObjectGuidGeneratorBase
{
public:
explicit ObjectGuidGenerator(ObjectGuid::LowType start = 1) : ObjectGuidGeneratorBase(start) { }
@@ -299,11 +298,11 @@ public:
}
};
-ByteBuffer& operator<<(ByteBuffer& buf, ObjectGuid const& guid);
-ByteBuffer& operator>>(ByteBuffer& buf, ObjectGuid& guid);
+TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, ObjectGuid const& guid);
+TC_GAME_API ByteBuffer& operator>>(ByteBuffer& buf, ObjectGuid& guid);
-ByteBuffer& operator<<(ByteBuffer& buf, PackedGuid const& guid);
-ByteBuffer& operator>>(ByteBuffer& buf, PackedGuidReader const& guid);
+TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, PackedGuid const& guid);
+TC_GAME_API ByteBuffer& operator>>(ByteBuffer& buf, PackedGuidReader const& guid);
inline PackedGuid ObjectGuid::WriteAsPacked() const { return PackedGuid(*this); }
diff --git a/src/server/game/Entities/Object/ObjectPosSelector.h b/src/server/game/Entities/Object/ObjectPosSelector.h
index 26a23678009..84c694abf08 100644
--- a/src/server/game/Entities/Object/ObjectPosSelector.h
+++ b/src/server/game/Entities/Object/ObjectPosSelector.h
@@ -30,7 +30,7 @@ inline UsedPosType operator ~(UsedPosType uptype)
return uptype==USED_POS_PLUS ? USED_POS_MINUS : USED_POS_PLUS;
}
-struct ObjectPosSelector
+struct TC_GAME_API ObjectPosSelector
{
struct UsedPos
{
diff --git a/src/server/game/Entities/Object/Position.h b/src/server/game/Entities/Object/Position.h
index 18d356c28d4..6325cc51fe2 100644
--- a/src/server/game/Entities/Object/Position.h
+++ b/src/server/game/Entities/Object/Position.h
@@ -22,7 +22,7 @@
class ByteBuffer;
-struct Position
+struct TC_GAME_API Position
{
Position(float x = 0, float y = 0, float z = 0, float o = 0)
: m_positionX(x), m_positionY(y), m_positionZ(z), m_orientation(NormalizeOrientation(o)) { }
@@ -216,11 +216,11 @@ public:
}
};
-ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYStreamer const& streamer);
-ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYStreamer const& streamer);
-ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYZStreamer const& streamer);
-ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYZStreamer const& streamer);
-ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYZOStreamer const& streamer);
-ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYZOStreamer const& streamer);
+TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYStreamer const& streamer);
+TC_GAME_API ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYStreamer const& streamer);
+TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYZStreamer const& streamer);
+TC_GAME_API ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYZStreamer const& streamer);
+TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYZOStreamer const& streamer);
+TC_GAME_API ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYZOStreamer const& streamer);
#endif // Trinity_game_Position_h__
diff --git a/src/server/game/Entities/Object/Updates/UpdateFieldFlags.h b/src/server/game/Entities/Object/Updates/UpdateFieldFlags.h
index 0b4e59f4f9b..8208a5e9894 100644
--- a/src/server/game/Entities/Object/Updates/UpdateFieldFlags.h
+++ b/src/server/game/Entities/Object/Updates/UpdateFieldFlags.h
@@ -35,10 +35,10 @@ enum UpdatefieldFlags
UF_FLAG_DYNAMIC = 0x100
};
-extern uint32 ItemUpdateFieldFlags[CONTAINER_END];
-extern uint32 UnitUpdateFieldFlags[PLAYER_END];
-extern uint32 GameObjectUpdateFieldFlags[GAMEOBJECT_END];
-extern uint32 DynamicObjectUpdateFieldFlags[DYNAMICOBJECT_END];
-extern uint32 CorpseUpdateFieldFlags[CORPSE_END];
+TC_GAME_API extern uint32 ItemUpdateFieldFlags[CONTAINER_END];
+TC_GAME_API extern uint32 UnitUpdateFieldFlags[PLAYER_END];
+TC_GAME_API extern uint32 GameObjectUpdateFieldFlags[GAMEOBJECT_END];
+TC_GAME_API extern uint32 DynamicObjectUpdateFieldFlags[DYNAMICOBJECT_END];
+TC_GAME_API extern uint32 CorpseUpdateFieldFlags[CORPSE_END];
#endif // _UPDATEFIELDFLAGS_H
diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h
index b0863a371e6..3a65fb44e04 100644
--- a/src/server/game/Entities/Pet/Pet.h
+++ b/src/server/game/Entities/Pet/Pet.h
@@ -37,7 +37,7 @@ typedef std::vector<uint32> AutoSpellList;
class Player;
-class Pet : public Guardian
+class TC_GAME_API Pet : public Guardian
{
public:
explicit Pet(Player* owner, PetType type = MAX_PET_TYPE);
diff --git a/src/server/game/Entities/Player/KillRewarder.h b/src/server/game/Entities/Player/KillRewarder.h
index 08530de900c..210e5ff0246 100644
--- a/src/server/game/Entities/Player/KillRewarder.h
+++ b/src/server/game/Entities/Player/KillRewarder.h
@@ -24,7 +24,7 @@ class Player;
class Unit;
class Group;
-class KillRewarder
+class TC_GAME_API KillRewarder
{
public:
KillRewarder(Player* killer, Unit* victim, bool isBattleGround);
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index c7f674ec72c..13661f80cb2 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -213,7 +213,7 @@ void PlayerTaxi::AppendTaximaskTo(ByteBuffer& data, bool all)
if (all)
{
for (uint8 i = 0; i < TaxiMaskSize; ++i)
- data << uint32(sTaxiNodesMask[i]); // all existed nodes
+ data << uint32(sTaxiNodesMask[i]); // all existing nodes
}
else
{
@@ -306,7 +306,7 @@ Player::Player(WorldSession* session): Unit(true)
m_ExtraFlags = 0;
- m_spellModTakingSpell = NULL;
+ m_spellModTakingSpell = nullptr;
//m_pad = 0;
// players always accept
@@ -332,19 +332,17 @@ Player::Player(WorldSession* session): Unit(true)
m_nextSave = sWorld->getIntConfig(CONFIG_INTERVAL_SAVE);
- clearResurrectRequestData();
-
memset(m_items, 0, sizeof(Item*)*PLAYER_SLOTS_COUNT);
- m_social = NULL;
+ m_social = nullptr;
// group is initialized in the reference constructor
- SetGroupInvite(NULL);
+ SetGroupInvite(nullptr);
m_groupUpdateMask = 0;
m_auraRaidUpdateMask = 0;
m_bPassOnGroupLoot = false;
- duel = NULL;
+ duel = nullptr;
m_GuildIdInvited = 0;
m_ArenaTeamIdInvited = 0;
@@ -359,7 +357,7 @@ Player::Player(WorldSession* session): Unit(true)
m_bHasDelayedTeleport = false;
m_teleport_options = 0;
- m_trade = NULL;
+ m_trade = nullptr;
m_cinematic = 0;
@@ -394,7 +392,7 @@ Player::Player(WorldSession* session): Unit(true)
m_bgBattlegroundQueueID[j].invitedToInstance = 0;
}
- m_logintime = time(NULL);
+ m_logintime = time(nullptr);
m_Last_tick = m_logintime;
m_Played_time[PLAYED_TIME_TOTAL] = 0;
m_Played_time[PLAYED_TIME_LEVEL] = 0;
@@ -470,7 +468,7 @@ Player::Player(WorldSession* session): Unit(true)
m_spellPenetrationItemMod = 0;
// Honor System
- m_lastHonorUpdateTime = time(NULL);
+ m_lastHonorUpdateTime = time(nullptr);
m_IsBGRandomWinner = false;
@@ -499,11 +497,11 @@ Player::Player(WorldSession* session): Unit(true)
m_contestedPvPTimer = 0;
- m_declinedname = NULL;
+ m_declinedname = nullptr;
m_isActive = true;
- m_runes = NULL;
+ m_runes = nullptr;
m_lastFallTime = 0;
m_lastFallZ = 0;
@@ -543,7 +541,7 @@ Player::Player(WorldSession* session): Unit(true)
Player::~Player()
{
- // it must be unloaded already in PlayerLogout and accessed only for loggined player
+ // it must be unloaded already in PlayerLogout and accessed only for logged in player
//m_social = NULL;
// Note: buy back item already deleted from DB when player was saved
@@ -605,20 +603,20 @@ bool Player::Create(ObjectGuid::LowType guidlow, CharacterCreateInfo* createInfo
PlayerInfo const* info = sObjectMgr->GetPlayerInfo(createInfo->Race, createInfo->Class);
if (!info)
{
- TC_LOG_ERROR("entities.player", "Player::Create: Possible hacking-attempt: Account %u tried creating a character named '%s' with an invalid race/class pair (%u/%u) - refusing to do so.",
+ TC_LOG_ERROR("entities.player", "Player::Create: Possible hacking attempt: Account %u tried to create a character named '%s' with an invalid race/class pair (%u/%u) - refusing to do so.",
GetSession()->GetAccountId(), m_name.c_str(), createInfo->Race, createInfo->Class);
return false;
}
for (uint8 i = 0; i < PLAYER_SLOTS_COUNT; i++)
- m_items[i] = NULL;
+ m_items[i] = nullptr;
Relocate(info->positionX, info->positionY, info->positionZ, info->orientation);
ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(createInfo->Class);
if (!cEntry)
{
- TC_LOG_ERROR("entities.player", "Player::Create: Possible hacking-attempt: Account %u tried creating a character named '%s' with an invalid character class (%u) - refusing to do so (wrong DBC-files?)",
+ TC_LOG_ERROR("entities.player", "Player::Create: Possible hacking attempt: Account %u tried to create a character named '%s' with an invalid character class (%u) - refusing to do so (wrong DBC-files?)",
GetSession()->GetAccountId(), m_name.c_str(), createInfo->Class);
return false;
}
@@ -633,14 +631,14 @@ bool Player::Create(ObjectGuid::LowType guidlow, CharacterCreateInfo* createInfo
if (!IsValidGender(createInfo->Gender))
{
- TC_LOG_ERROR("entities.player", "Player::Create: Possible hacking-attempt: Account %u tried creating a character named '%s' with an invalid gender (%u) - refusing to do so",
+ TC_LOG_ERROR("entities.player", "Player::Create: Possible hacking attempt: Account %u tried to create a character named '%s' with an invalid gender (%u) - refusing to do so",
GetSession()->GetAccountId(), m_name.c_str(), createInfo->Gender);
return false;
}
if (!ValidateAppearance(createInfo->Race, createInfo->Class, createInfo->Gender, createInfo->HairStyle, createInfo->HairColor, createInfo->Face, createInfo->FacialHair, createInfo->Skin, true))
{
- TC_LOG_ERROR("entities.player", "Player::Create: Possible hacking-attempt: Account %u tried creating a character named '%s' with invalid appearance attributes - refusing to do so",
+ TC_LOG_ERROR("entities.player", "Player::Create: Possible hacking attempt: Account %u tried to create a character named '%s' with invalid appearance attributes - refusing to do so",
GetSession()->GetAccountId(), m_name.c_str());
return false;
}
@@ -752,7 +750,7 @@ bool Player::Create(ObjectGuid::LowType guidlow, CharacterCreateInfo* createInfo
}
// Played time
- m_Last_tick = time(NULL);
+ m_Last_tick = time(nullptr);
m_Played_time[PLAYED_TIME_TOTAL] = 0;
m_Played_time[PLAYED_TIME_LEVEL] = 0;
@@ -851,7 +849,7 @@ bool Player::Create(ObjectGuid::LowType guidlow, CharacterCreateInfo* createInfo
if (msg == EQUIP_ERR_OK)
{
RemoveItem(INVENTORY_SLOT_BAG_0, i, true);
- pItem = StoreItem(sDest, pItem, true);
+ StoreItem(sDest, pItem, true);
}
// if this is ammo then use it
@@ -868,7 +866,8 @@ bool Player::Create(ObjectGuid::LowType guidlow, CharacterCreateInfo* createInfo
bool Player::StoreNewItemInBestSlots(uint32 titem_id, uint32 titem_amount)
{
- TC_LOG_DEBUG("entities.player.items", "STORAGE: Creating initial item, itemId = %u, count = %u", titem_id, titem_amount);
+ TC_LOG_DEBUG("entities.player.items", "Player::StoreNewItemInBestSlots: Player '%s' (%s) creates initial item (ItemID: %u, Count: %u)",
+ GetName().c_str(), GetGUID().ToString().c_str(), titem_id, titem_amount);
// attempt equip by one
while (titem_amount > 0)
@@ -897,7 +896,8 @@ bool Player::StoreNewItemInBestSlots(uint32 titem_id, uint32 titem_amount)
}
// item can't be added
- TC_LOG_ERROR("entities.player.items", "STORAGE: Can't equip or store initial item %u for race %u class %u, error msg = %u", titem_id, getRace(), getClass(), msg);
+ TC_LOG_ERROR("entities.player.items", "Player::StoreNewItemInBestSlots: Player '%s' (%s) can't equip or store initial item (ItemID: %u, Race: %u, Class: %u, InventoryResult: %u)",
+ GetName().c_str(), GetGUID().ToString().c_str(), titem_id, getRace(), getClass(), msg);
return false;
}
@@ -927,10 +927,10 @@ void Player::StopMirrorTimer(MirrorTimerType Type)
GetSession()->SendPacket(&data);
}
-bool Player::IsImmuneToEnvironmentalDamage()
+bool Player::IsImmuneToEnvironmentalDamage() const
{
// check for GM and death state included in isAttackableByAOE
- return (!isTargetableForAttack(false));
+ return !isTargetableForAttack(false);
}
uint32 Player::EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
@@ -958,13 +958,14 @@ uint32 Player::EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
data << uint32(resist);
SendMessageToSet(&data, true);
- uint32 final_damage = DealDamage(this, damage, NULL, SELF_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ uint32 final_damage = DealDamage(this, damage, nullptr, SELF_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
if (!IsAlive())
{
- if (type == DAMAGE_FALL) // DealDamage not apply item durability loss at self damage
+ if (type == DAMAGE_FALL) // DealDamage does not apply item durability loss from self-induced damage.
{
- TC_LOG_DEBUG("entities.player", "We are fall to death, loosing 10 percents durability");
+ TC_LOG_DEBUG("entities.player", "Player::EnvironmentalDamage: Player '%s' (%s) fall to death, losing 10%% durability",
+ GetName().c_str(), GetGUID().ToString().c_str());
DurabilityLossAll(0.10f, false);
// durability lost message
WorldPacket data2(SMSG_DURABILITY_DAMAGE_DEATH, 0);
@@ -977,7 +978,7 @@ uint32 Player::EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
return final_damage;
}
-int32 Player::getMaxTimer(MirrorTimerType timer)
+int32 Player::getMaxTimer(MirrorTimerType timer) const
{
switch (timer)
{
@@ -1018,7 +1019,7 @@ void Player::StopMirrorTimers()
StopMirrorTimer(FIRE_TIMER);
}
-bool Player::IsMirrorTimerActive(MirrorTimerType type)
+bool Player::IsMirrorTimerActive(MirrorTimerType type) const
{
return m_MirrorTimer[type] == getMaxTimer(type);
}
@@ -1200,7 +1201,7 @@ void Player::Update(uint32 p_time)
return;
// undelivered mail
- if (m_nextMailDelivereTime && m_nextMailDelivereTime <= time(NULL))
+ if (m_nextMailDelivereTime && m_nextMailDelivereTime <= time(nullptr))
{
SendNewMail();
++unReadMails;
@@ -1216,16 +1217,17 @@ void Player::Update(uint32 p_time)
{
//TC_LOG_FATAL("entities.player", "Player has m_pad %u during update!", m_pad);
//if (m_spellModTakingSpell)
- TC_LOG_FATAL("spells", "Player has m_spellModTakingSpell %u during update!", m_spellModTakingSpell->m_spellInfo->Id);
- m_spellModTakingSpell = NULL;
+ TC_LOG_FATAL("spells", "Player::Update: Player '%s' (%s) has m_spellModTakingSpell (SpellID: %u) during update!",
+ GetName().c_str(), GetGUID().ToString().c_str(), m_spellModTakingSpell->m_spellInfo->Id);
+ m_spellModTakingSpell = nullptr;
}
- //used to implement delayed far teleports
+ //used to implement delayed far teleport
SetCanDelayTeleport(true);
Unit::Update(p_time);
SetCanDelayTeleport(false);
- time_t now = time(NULL);
+ time_t now = time(nullptr);
UpdatePvPFlag(now);
@@ -1237,13 +1239,14 @@ void Player::Update(uint32 p_time)
UpdateAfkReport(now);
- if (IsCharmed())
- if (Unit* charmer = GetCharmer())
- if (charmer->GetTypeId() == TYPEID_UNIT && charmer->IsAlive())
- UpdateCharmedAI();
-
- if (GetAI() && IsAIEnabled)
+ if (IsAIEnabled && GetAI())
GetAI()->UpdateAI(p_time);
+ else if (NeedChangeAI)
+ {
+ UpdateCharmAI();
+ NeedChangeAI = false;
+ IsAIEnabled = (GetAI() != nullptr);
+ }
// Update items that have just a limited lifetime
if (now > m_Last_tick)
@@ -1441,7 +1444,7 @@ void Player::Update(uint32 p_time)
{
// m_nextSave reset in SaveToDB call
SaveToDB();
- TC_LOG_DEBUG("entities.player", "Player '%s' (GUID: %u) saved", GetName().c_str(), GetGUID().GetCounter());
+ TC_LOG_DEBUG("entities.player", "Player::Update: Player '%s' (%s) saved", GetName().c_str(), GetGUID().ToString().c_str());
}
else
m_nextSave -= p_time;
@@ -1551,7 +1554,7 @@ void Player::setDeathState(DeathState s)
{
if (!cur)
{
- TC_LOG_ERROR("entities.player", "setDeathState: attempt to kill a dead player %s(%d)", GetName().c_str(), GetGUID().GetCounter());
+ TC_LOG_ERROR("entities.player", "Player::setDeathState: Attempt to kill a dead player '%s' (%s)", GetName().c_str(), GetGUID().ToString().c_str());
return;
}
@@ -1560,10 +1563,10 @@ void Player::setDeathState(DeathState s)
// lost combo points at any target (targeted combo points clear in Unit::setDeathState)
ClearComboPoints();
- clearResurrectRequestData();
+ ClearResurrectRequestData();
//FIXME: is pet dismissed at dying or releasing spirit? if second, add setDeathState(DEAD) to HandleRepopRequestOpcode and define pet unsummon here with (s == DEAD)
- RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
+ RemovePet(nullptr, PET_SAVE_NOT_IN_SLOT, true);
// save value before aura remove in Unit::setDeathState
ressSpellId = GetUInt32Value(PLAYER_SELF_RES_SPELL);
@@ -1592,12 +1595,14 @@ void Player::setDeathState(DeathState s)
bool Player::BuildEnumData(PreparedQueryResult result, WorldPacket* data)
{
- // 0 1 2 3 4 5 6 7
- // "SELECT characters.guid, characters.name, characters.race, characters.class, characters.gender, characters.playerBytes, characters.playerBytes2, characters.level, "
- // 8 9 10 11 12 13 14
- // "characters.zone, characters.map, characters.position_x, characters.position_y, characters.position_z, guild_member.guildid, characters.playerFlags, "
- // 15 16 17 18 19 20 21
- // "characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.data, character_banned.guid, character_declinedname.genitive "
+ // 0 1 2 3 4 5 6 7
+ // SELECT characters.guid, characters.name, characters.race, characters.class, characters.gender, characters.skin, characters.face, characters.hairStyle,
+ // 8 9 10 11 12 13 14 15
+ // characters.hairColor, characters.facialStyle, characters.level, characters.zone, characters.map, characters.position_x, characters.position_y, characters.position_z,
+ // 16 17 18 19 20 21 22
+ // guild_member.guildid, characters.playerFlags, characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.equipmentCache,
+ // 23 24
+ // character_banned.guid, character_declinedname.genitive
Field* fields = result->Fetch();
@@ -1624,12 +1629,15 @@ bool Player::BuildEnumData(PreparedQueryResult result, WorldPacket* data)
*data << uint8(plrClass); // class
*data << uint8(gender); // gender
- uint32 playerBytes = fields[5].GetUInt32();
- uint32 playerBytes2 = fields[6].GetUInt32();
+ uint8 skin = fields[5].GetUInt8();
+ uint8 face = fields[6].GetUInt8();
+ uint8 hairStyle = fields[7].GetUInt8();
+ uint8 hairColor = fields[8].GetUInt8();
+ uint8 facialStyle = fields[9].GetUInt8();
- uint16 atLoginFlags = fields[15].GetUInt16();
+ uint16 atLoginFlags = fields[18].GetUInt16();
- if (!ValidateAppearance(uint8(plrRace), uint8(plrClass), gender, uint8(playerBytes >> 16), uint8(playerBytes >> 24), uint8(playerBytes >> 8), uint8(playerBytes2), uint8(playerBytes)))
+ if (!ValidateAppearance(uint8(plrRace), uint8(plrClass), gender, hairStyle, hairColor, face, facialStyle, skin))
{
TC_LOG_ERROR("entities.player.loading", "Player %u has wrong Appearance values (Hair/Skin/Color), forcing recustomize", guid);
@@ -1643,25 +1651,24 @@ bool Player::BuildEnumData(PreparedQueryResult result, WorldPacket* data)
}
}
- *data << uint8(playerBytes); // skin
- *data << uint8(playerBytes >> 8); // face
- *data << uint8(playerBytes >> 16); // hair style
- *data << uint8(playerBytes >> 24); // hair color
-
- *data << uint8(playerBytes2 & 0xFF); // facial hair
+ *data << uint8(skin);
+ *data << uint8(face);
+ *data << uint8(hairStyle);
+ *data << uint8(hairColor);
+ *data << uint8(facialStyle);
- *data << uint8(fields[7].GetUInt8()); // level
- *data << uint32(fields[8].GetUInt16()); // zone
- *data << uint32(fields[9].GetUInt16()); // map
+ *data << uint8(fields[10].GetUInt8()); // level
+ *data << uint32(fields[11].GetUInt16()); // zone
+ *data << uint32(fields[12].GetUInt16()); // map
- *data << fields[10].GetFloat(); // x
- *data << fields[11].GetFloat(); // y
- *data << fields[12].GetFloat(); // z
+ *data << fields[13].GetFloat(); // x
+ *data << fields[14].GetFloat(); // y
+ *data << fields[15].GetFloat(); // z
- *data << uint32(fields[13].GetUInt32()); // guild id
+ *data << uint32(fields[16].GetUInt32()); // guild id
uint32 charFlags = 0;
- uint32 playerFlags = fields[14].GetUInt32();
+ uint32 playerFlags = fields[17].GetUInt32();
if (atLoginFlags & AT_LOGIN_RESURRECT)
playerFlags &= ~PLAYER_FLAGS_GHOST;
if (playerFlags & PLAYER_FLAGS_HIDE_HELM)
@@ -1672,11 +1679,11 @@ bool Player::BuildEnumData(PreparedQueryResult result, WorldPacket* data)
charFlags |= CHARACTER_FLAG_GHOST;
if (atLoginFlags & AT_LOGIN_RENAME)
charFlags |= CHARACTER_FLAG_RENAME;
- if (fields[20].GetUInt32())
+ if (fields[23].GetUInt32())
charFlags |= CHARACTER_FLAG_LOCKED_BY_BILLING;
if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED))
{
- if (!fields[21].GetString().empty())
+ if (!fields[24].GetString().empty())
charFlags |= CHARACTER_FLAG_DECLINED;
}
else
@@ -1705,12 +1712,12 @@ bool Player::BuildEnumData(PreparedQueryResult result, WorldPacket* data)
// show pet at selection character in character list only for non-ghost character
if (result && !(playerFlags & PLAYER_FLAGS_GHOST) && (plrClass == CLASS_WARLOCK || plrClass == CLASS_HUNTER || plrClass == CLASS_DEATH_KNIGHT))
{
- uint32 entry = fields[16].GetUInt32();
+ uint32 entry = fields[19].GetUInt32();
CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(entry);
if (creatureInfo)
{
- petDisplayId = fields[17].GetUInt32();
- petLevel = fields[18].GetUInt16();
+ petDisplayId = fields[20].GetUInt32();
+ petLevel = fields[21].GetUInt16();
petFamily = creatureInfo->family;
}
}
@@ -1719,7 +1726,7 @@ bool Player::BuildEnumData(PreparedQueryResult result, WorldPacket* data)
*data << uint32(petLevel);
*data << uint32(petFamily);
- Tokenizer equipment(fields[19].GetString(), ' ');
+ Tokenizer equipment(fields[22].GetString(), ' ');
for (uint8 slot = 0; slot < INVENTORY_SLOT_BAG_END; ++slot)
{
uint32 visualBase = slot * 2;
@@ -1739,7 +1746,7 @@ bool Player::BuildEnumData(PreparedQueryResult result, WorldPacket* data)
for (uint8 enchantSlot = PERM_ENCHANTMENT_SLOT; enchantSlot <= TEMP_ENCHANTMENT_SLOT; ++enchantSlot)
{
// values stored in 2 uint16
- uint32 enchantId = 0x0000FFFF & (enchants >> enchantSlot*16);
+ uint32 enchantId = 0x0000FFFF & (enchants >> enchantSlot * 16);
if (!enchantId)
continue;
@@ -1799,14 +1806,14 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
{
if (!MapManager::IsValidMapCoord(mapid, x, y, z, orientation))
{
- TC_LOG_ERROR("maps", "TeleportTo: invalid map (%d) or invalid coordinates (X: %f, Y: %f, Z: %f, O: %f) given when teleporting player (GUID: %u, name: %s, map: %d, X: %f, Y: %f, Z: %f, O: %f).",
- mapid, x, y, z, orientation, GetGUID().GetCounter(), GetName().c_str(), GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation());
+ TC_LOG_ERROR("maps", "Player::TeleportTo: Invalid map (%d) or invalid coordinates (X: %f, Y: %f, Z: %f, O: %f) given when teleporting player '%s' (%s, MapID: %d, X: %f, Y: %f, Z: %f, O: %f).",
+ mapid, x, y, z, orientation, GetGUID().ToString().c_str(), GetName().c_str(), GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation());
return false;
}
if (!GetSession()->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_DISABLE_MAP) && DisableMgr::IsDisabledFor(DISABLE_TYPE_MAP, mapid, this))
{
- TC_LOG_ERROR("maps", "Player (GUID: %u, name: %s) tried to enter a forbidden map %u", GetGUID().GetCounter(), GetName().c_str(), mapid);
+ TC_LOG_ERROR("maps", "Player::TeleportTo: Player '%s' (%s) tried to enter a forbidden map (MapID: %u)", GetGUID().ToString().c_str(), GetName().c_str(), mapid);
SendTransferAborted(mapid, TRANSFER_ABORT_MAP_NOT_ALLOWED);
return false;
}
@@ -1824,7 +1831,8 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
// client without expansion support
if (GetSession()->Expansion() < mEntry->Expansion())
{
- TC_LOG_DEBUG("maps", "Player %s using client without required expansion tried teleport to non accessible map %u", GetName().c_str(), mapid);
+ TC_LOG_DEBUG("maps", "Player '%s' (%s) using client without required expansion tried teleport to non accessible map (MapID: %u)",
+ GetName().c_str(), GetGUID().ToString().c_str(), mapid);
if (Transport* transport = GetTransport())
{
@@ -1837,7 +1845,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
return false; // normal client can't teleport to this map...
}
else
- TC_LOG_DEBUG("maps", "Player %s is being teleported to map %u", GetName().c_str(), mapid);
+ TC_LOG_DEBUG("maps", "Player %s (%s) is being teleported to map (MapID: %u)", GetName().c_str(), GetGUID().ToString().c_str(), mapid);
if (m_vehicle)
ExitVehicle();
@@ -1862,7 +1870,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
if (GetMapId() == mapid)
{
- //lets reset far teleport flag if it wasn't reset during chained teleports
+ //lets reset far teleport flag if it wasn't reset during chained teleport
SetSemaphoreTeleportFar(false);
//setup delayed teleport flag
SetDelayedTeleportFlag(IsCanDelayTeleport());
@@ -2046,24 +2054,7 @@ void Player::ProcessDelayedOperations()
return;
if (m_DelayedOperations & DELAYED_RESURRECT_PLAYER)
- {
- ResurrectPlayer(0.0f, false);
-
- if (GetMaxHealth() > m_resurrectHealth)
- SetHealth(m_resurrectHealth);
- else
- SetFullHealth();
-
- if (GetMaxPower(POWER_MANA) > m_resurrectMana)
- SetPower(POWER_MANA, m_resurrectMana);
- else
- SetPower(POWER_MANA, GetMaxPower(POWER_MANA));
-
- SetPower(POWER_RAGE, 0);
- SetPower(POWER_ENERGY, GetMaxPower(POWER_ENERGY));
-
- SpawnCorpseBones();
- }
+ ResurrectUsingRequestDataImpl();
if (m_DelayedOperations & DELAYED_SAVE_PLAYER)
SaveToDB();
@@ -2146,8 +2137,8 @@ void Player::RemoveFromWorld()
{
if (WorldObject* viewpoint = GetViewpoint())
{
- TC_LOG_ERROR("entities.player", "Player %s has viewpoint %u %u when removed from world",
- GetName().c_str(), viewpoint->GetEntry(), viewpoint->GetTypeId());
+ TC_LOG_ERROR("entities.player", "Player::RemoveFromWorld: Player '%s' (%s) has viewpoint (Entry:%u, Type: %u) when removed from world",
+ GetName().c_str(), GetGUID().ToString().c_str(), viewpoint->GetEntry(), viewpoint->GetTypeId());
SetViewpoint(viewpoint, false);
}
}
@@ -2388,14 +2379,14 @@ void Player::ResetAllPowers()
}
}
-bool Player::CanInteractWithQuestGiver(Object* questGiver)
+bool Player::CanInteractWithQuestGiver(Object* questGiver) const
{
switch (questGiver->GetTypeId())
{
case TYPEID_UNIT:
- return GetNPCIfCanInteractWith(questGiver->GetGUID(), UNIT_NPC_FLAG_QUESTGIVER) != NULL;
+ return GetNPCIfCanInteractWith(questGiver->GetGUID(), UNIT_NPC_FLAG_QUESTGIVER) != nullptr;
case TYPEID_GAMEOBJECT:
- return GetGameObjectIfCanInteractWith(questGiver->GetGUID(), GAMEOBJECT_TYPE_QUESTGIVER) != NULL;
+ return GetGameObjectIfCanInteractWith(questGiver->GetGUID(), GAMEOBJECT_TYPE_QUESTGIVER) != nullptr;
case TYPEID_PLAYER:
return IsAlive() && questGiver->ToPlayer()->IsAlive();
case TYPEID_ITEM:
@@ -2406,46 +2397,46 @@ bool Player::CanInteractWithQuestGiver(Object* questGiver)
return false;
}
-Creature* Player::GetNPCIfCanInteractWith(ObjectGuid const& guid, uint32 npcflagmask)
+Creature* Player::GetNPCIfCanInteractWith(ObjectGuid const& guid, uint32 npcflagmask) const
{
// unit checks
if (!guid)
- return NULL;
+ return nullptr;
if (!IsInWorld())
- return NULL;
+ return nullptr;
if (IsInFlight())
- return NULL;
+ return nullptr;
// exist (we need look pets also for some interaction (quest/etc)
Creature* creature = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, guid);
if (!creature)
- return NULL;
+ return nullptr;
// Deathstate checks
if (!IsAlive() && !(creature->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_GHOST))
- return NULL;
+ return nullptr;
// alive or spirit healer
if (!creature->IsAlive() && !(creature->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_DEAD_INTERACT))
- return NULL;
+ return nullptr;
// appropriate npc type
if (npcflagmask && !creature->HasFlag(UNIT_NPC_FLAGS, npcflagmask))
- return NULL;
+ return nullptr;
// not allow interaction under control, but allow with own pets
if (creature->GetCharmerGUID())
- return NULL;
+ return nullptr;
// not unfriendly/hostile
if (creature->GetReactionTo(this) <= REP_UNFRIENDLY)
- return NULL;
+ return nullptr;
// not too far
if (!creature->IsWithinDistInMap(this, INTERACTION_DISTANCE))
- return NULL;
+ return nullptr;
return creature;
}
@@ -2473,8 +2464,8 @@ GameObject* Player::GetGameObjectIfCanInteractWith(ObjectGuid const& guid, Gameo
if (go->IsWithinDistInMap(this, go->GetInteractionDistance()))
return go;
- TC_LOG_DEBUG("maps", "GetGameObjectIfCanInteractWith: GameObject '%s' [GUID: %u] is too far away from player %s [GUID: %u] to be used by him (distance=%f, maximal %f is allowed)", go->GetGOInfo()->name.c_str(),
- go->GetGUID().GetCounter(), GetName().c_str(), GetGUID().GetCounter(), go->GetDistance(this), go->GetInteractionDistance());
+ TC_LOG_DEBUG("maps", "Player::GetGameObjectIfCanInteractWith: GameObject '%s' (%s) is too far away from player '%s' (%s) to be used by him (Distance: %f, maximal 10 is allowed)",
+ go->GetGOInfo()->name.c_str(), go->GetGUID().ToString().c_str(), GetName().c_str(), GetGUID().ToString().c_str(), go->GetDistance(this));
}
}
@@ -2625,14 +2616,14 @@ bool Player::IsGroupVisibleFor(Player const* p) const
bool Player::IsInSameGroupWith(Player const* p) const
{
- return p == this || (GetGroup() != NULL &&
+ return p == this || (GetGroup() != nullptr &&
GetGroup() == p->GetGroup() &&
GetGroup()->SameSubGroup(this, p));
}
bool Player::IsInSameRaidWith(Player const* p) const
{
- return p == this || (GetGroup() != NULL && GetGroup() == p->GetGroup());
+ return p == this || (GetGroup() != nullptr && GetGroup() == p->GetGroup());
}
///- If the player is invited, remove him. If the group if then only 1 person, disband the group.
@@ -2667,7 +2658,7 @@ void Player::RemoveFromGroup(Group* group, ObjectGuid guid, RemoveMethod method
group->RemoveMember(guid, method, kicker, reason);
}
-void Player::SendLogXPGain(uint32 GivenXP, Unit* victim, uint32 BonusXP, bool recruitAFriend, float /*group_rate*/)
+void Player::SendLogXPGain(uint32 GivenXP, Unit* victim, uint32 BonusXP, bool recruitAFriend, float /*group_rate*/) const
{
WorldPacket data(SMSG_LOG_XPGAIN, 21); // guess size?
data << uint64(victim ? victim->GetGUID() : ObjectGuid::Empty);
@@ -2708,7 +2699,7 @@ void Player::GiveXP(uint32 xp, Unit* victim, float group_rate)
if (level >= sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
return;
- uint32 bonus_xp = 0;
+ uint32 bonus_xp;
bool recruitAFriend = GetsRecruitAFriendBonus(true);
// RaF does NOT stack with rested experience
@@ -3069,8 +3060,6 @@ void Player::SendInitialSpells()
GetSpellHistory()->WritePacket<Player>(data);
GetSession()->SendPacket(&data);
-
- TC_LOG_DEBUG("network", "CHARACTER: Sent Initial Spells");
}
void Player::RemoveMail(uint32 id)
@@ -3086,7 +3075,7 @@ void Player::RemoveMail(uint32 id)
}
}
-void Player::SendMailResult(uint32 mailId, MailResponseType mailAction, MailResponseResult mailError, uint32 equipError, ObjectGuid::LowType item_guid, uint32 item_count)
+void Player::SendMailResult(uint32 mailId, MailResponseType mailAction, MailResponseResult mailError, uint32 equipError, ObjectGuid::LowType item_guid, uint32 item_count) const
{
WorldPacket data(SMSG_SEND_MAIL_RESULT, (4+4+4+(mailError == MAIL_ERR_EQUIP_ERROR?4:(mailAction == MAIL_ITEM_TAKEN?4+4:0))));
data << (uint32) mailId;
@@ -3102,7 +3091,7 @@ void Player::SendMailResult(uint32 mailId, MailResponseType mailAction, MailResp
GetSession()->SendPacket(&data);
}
-void Player::SendNewMail()
+void Player::SendNewMail() const
{
// deliver undelivered mail
WorldPacket data(SMSG_RECEIVED_MAIL, 4);
@@ -3114,7 +3103,7 @@ void Player::UpdateNextMailTimeAndUnreads()
{
// calculate next delivery time (min. from non-delivered mails
// and recalculate unReadMail
- time_t cTime = time(NULL);
+ time_t cTime = time(nullptr);
m_nextMailDelivereTime = 0;
unReadMails = 0;
for (PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end(); ++itr)
@@ -3131,7 +3120,7 @@ void Player::UpdateNextMailTimeAndUnreads()
void Player::AddNewMailDeliverTime(time_t deliver_time)
{
- if (deliver_time <= time(NULL)) // ready now
+ if (deliver_time <= time(nullptr)) // ready now
{
++unReadMails;
SendNewMail();
@@ -3164,12 +3153,12 @@ bool Player::AddTalent(uint32 spellId, uint8 spec, bool learning)
// do character spell book cleanup (all characters)
if (!IsInWorld() && !learning) // spell load case
{
- TC_LOG_ERROR("spells", "Player::addSpell: Non-existed in SpellStore spell #%u request, deleting for all characters in `character_spell`.", spellId);
+ TC_LOG_ERROR("spells", "Player::AddTalent: Spell (ID: %u) does not exist. Deleting for all characters in `character_spell` and `character_talent`.", spellId);
DeleteSpellFromAllPlayers(spellId);
}
else
- TC_LOG_ERROR("spells", "Player::addSpell: Non-existed in SpellStore spell #%u request.", spellId);
+ TC_LOG_ERROR("spells", "Player::AddTalent: Spell (ID: %u) does not exist", spellId);
return false;
}
@@ -3179,12 +3168,12 @@ bool Player::AddTalent(uint32 spellId, uint8 spec, bool learning)
// do character spell book cleanup (all characters)
if (!IsInWorld() && !learning) // spell load case
{
- TC_LOG_ERROR("spells", "Player::addTalent: Broken spell #%u learning not allowed, deleting for all characters in `character_talent`.", spellId);
+ TC_LOG_ERROR("spells", "Player::AddTalent: Spell (ID: %u) is invalid. Deleting for all characters in `character_spell` and `character_talent`.", spellId);
DeleteSpellFromAllPlayers(spellId);
}
else
- TC_LOG_ERROR("spells", "Player::addTalent: Broken spell #%u learning not allowed.", spellId);
+ TC_LOG_ERROR("spells", "Player::AddTalent: Spell (ID: %u) is invalid", spellId);
return false;
}
@@ -3229,12 +3218,12 @@ bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent
// do character spell book cleanup (all characters)
if (!IsInWorld() && !learning) // spell load case
{
- TC_LOG_ERROR("spells", "Player::addSpell: Non-existed in SpellStore spell #%u request, deleting for all characters in `character_spell`.", spellId);
+ TC_LOG_ERROR("spells", "Player::AddSpell: Spell (ID: %u) does not exist. deleting for all characters in `character_spell` and `character_talent`.", spellId);
DeleteSpellFromAllPlayers(spellId);
}
else
- TC_LOG_ERROR("spells", "Player::addSpell: Non-existed in SpellStore spell #%u request.", spellId);
+ TC_LOG_ERROR("spells", "Player::AddSpell: Spell (ID: %u) does not exist", spellId);
return false;
}
@@ -3244,12 +3233,12 @@ bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent
// do character spell book cleanup (all characters)
if (!IsInWorld() && !learning) // spell load case
{
- TC_LOG_ERROR("spells", "Player::addSpell: Broken spell #%u learning not allowed, deleting for all characters in `character_spell`.", spellId);
+ TC_LOG_ERROR("spells", "Player::AddSpell: Spell (ID: %u) is invalid. deleting for all characters in `character_spell` and `character_talent`.", spellId);
DeleteSpellFromAllPlayers(spellId);
}
else
- TC_LOG_ERROR("spells", "Player::addSpell: Broken spell #%u learning not allowed.", spellId);
+ TC_LOG_ERROR("spells", "Player::AddSpell: Spell (ID: %u) is invalid", spellId);
return false;
}
@@ -3939,12 +3928,12 @@ bool Player::ResetTalents(bool no_cost)
if (!HasEnoughMoney(cost))
{
- SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0);
+ SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, nullptr, 0, 0);
return false;
}
}
- RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
+ RemovePet(nullptr, PET_SAVE_NOT_IN_SLOT, true);
for (uint32 talentId = 0; talentId < sTalentStore.GetNumRows(); ++talentId)
{
@@ -3966,7 +3955,7 @@ bool Player::ResetTalents(bool no_cost)
for (int8 rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
{
- // skip non-existant talent ranks
+ // skip non-existing talent ranks
if (talentInfo->RankID[rank] == 0)
continue;
const SpellInfo* _spellEntry = sSpellMgr->GetSpellInfo(talentInfo->RankID[rank]);
@@ -4024,7 +4013,7 @@ Mail* Player::GetMail(uint32 id)
if ((*itr)->messageID == id)
return (*itr);
- return NULL;
+ return nullptr;
}
void Player::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const
@@ -4033,7 +4022,7 @@ void Player::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) c
{
for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i)
{
- if (m_items[i] == NULL)
+ if (m_items[i] == nullptr)
continue;
m_items[i]->BuildCreateUpdateBlockForPlayer(data, target);
@@ -4041,7 +4030,7 @@ void Player::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) c
for (uint8 i = INVENTORY_SLOT_BAG_START; i < BANK_SLOT_BAG_END; ++i)
{
- if (m_items[i] == NULL)
+ if (m_items[i] == nullptr)
continue;
m_items[i]->BuildCreateUpdateBlockForPlayer(data, target);
@@ -4064,7 +4053,7 @@ void Player::DestroyForPlayer(Player* target, bool onDeath) const
for (uint8 i = 0; i < INVENTORY_SLOT_BAG_END; ++i)
{
- if (m_items[i] == NULL)
+ if (m_items[i] == nullptr)
continue;
m_items[i]->DestroyForPlayer(target);
@@ -4074,7 +4063,7 @@ void Player::DestroyForPlayer(Player* target, bool onDeath) const
{
for (uint8 i = INVENTORY_SLOT_BAG_START; i < BANK_SLOT_BAG_END; ++i)
{
- if (m_items[i] == NULL)
+ if (m_items[i] == nullptr)
continue;
m_items[i]->DestroyForPlayer(target);
@@ -4164,7 +4153,7 @@ TrainerSpellState Player::GetTrainerSpellState(TrainerSpell const* trainer_spell
}
// check primary prof. limit
- // first rank of primary profession spell when there are no proffesions avalible is disabled
+ // first rank of primary profession spell when there are no professions available is disabled
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
if (!trainer_spell->learnedSpell[i])
@@ -4542,7 +4531,8 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe
break;
}
default:
- TC_LOG_ERROR("entities.player", "Player::DeleteFromDB: Unsupported delete method: %u.", charDelete_method);
+ TC_LOG_ERROR("entities.player", "Player::DeleteFromDB: Tried to delete player (%s) with unsupported delete method (%u).",
+ playerguid.ToString().c_str(), charDelete_method);
return;
}
@@ -4571,19 +4561,19 @@ void Player::DeleteOldCharacters()
*
* @see Player::DeleteFromDB
*
- * @param keepDays overrite the config option by another amount of days
+ * @param keepDays overwrite the config option by another amount of days
*/
void Player::DeleteOldCharacters(uint32 keepDays)
{
- TC_LOG_INFO("entities.player", "Player::DeleteOldChars: Removing characters older than %u day(s)", keepDays);
+ TC_LOG_INFO("entities.player", "Player::DeleteOldCharacters: Deleting all characters which have been deleted %u days before...", keepDays);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_OLD_CHARS);
- stmt->setUInt32(0, uint32(time(NULL) - time_t(keepDays * DAY)));
+ stmt->setUInt32(0, uint32(time(nullptr) - time_t(keepDays * DAY)));
PreparedQueryResult result = CharacterDatabase.Query(stmt);
if (result)
{
- TC_LOG_DEBUG("entities.player", "Player::DeleteOldChars: " UI64FMTD " character(s) to remove", result->GetRowCount());
+ TC_LOG_DEBUG("entities.player", "Player::DeleteOldCharacters: Found " UI64FMTD " character(s) to delete", result->GetRowCount());
do
{
Field* fields = result->Fetch();
@@ -4632,7 +4622,7 @@ void Player::BuildPlayerRepop()
WorldLocation corpseLocation = GetCorpseLocation();
if (corpseLocation.GetMapId() == GetMapId())
{
- TC_LOG_ERROR("entities.player", "BuildPlayerRepop: player %s(%d) already has a corpse", GetName().c_str(), GetGUID().GetCounter());
+ TC_LOG_ERROR("entities.player", "Player::BuildPlayerRepop: Player '%s' (%s) already has a corpse", GetName().c_str(), GetGUID().ToString().c_str());
return;
}
@@ -4640,7 +4630,7 @@ void Player::BuildPlayerRepop()
Corpse* corpse = CreateCorpse();
if (!corpse)
{
- TC_LOG_ERROR("entities.player", "Error creating corpse for Player %s [%u]", GetName().c_str(), GetGUID().GetCounter());
+ TC_LOG_ERROR("entities.player", "Player::BuildPlayerRepop: Error creating corpse for player '%s' (%s)", GetName().c_str(), GetGUID().ToString().c_str());
return;
}
GetMap()->AddToMap(corpse);
@@ -4749,30 +4739,9 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
}
}
-void Player::SendGhoulResurrectRequest(Player* target)
-{
- target->m_ghoulResurrectPlayerGUID = GetGUID();
-
- WorldPacket data(SMSG_RESURRECT_REQUEST, 8 + 4 + 1 + 1);
- data << uint64(GetGUID());
- data << uint32(0);
- data << uint8(0);
- data << uint8(0);
- target->GetSession()->SendPacket(&data);
-}
-
-void Player::GhoulResurrect()
-{
- CastSpell(this, 46619 /*SPELL_DK_RAISE_ALLY*/, true, nullptr, nullptr, m_ghoulResurrectPlayerGUID);
-
- m_ghoulResurrectPlayerGUID = ObjectGuid::Empty;
-}
-
void Player::RemoveGhoul()
{
- if (IsGhouled())
- if (Creature* ghoul = ObjectAccessor::GetCreature(*this, m_ghoulResurrectGhoulGUID))
- ghoul->DespawnOrUnsummon(); // Raise Ally aura will handle unauras
+ RemoveAura(SPELL_DK_RAISE_ALLY);
}
void Player::KillPlayer()
@@ -4817,7 +4786,7 @@ void Player::OfflineResurrect(ObjectGuid const& guid, SQLTransaction& trans)
Corpse* Player::CreateCorpse()
{
- // prevent existence 2 corpse for player
+ // prevent the existence of 2 corpses for one player
SpawnCorpseBones();
uint32 _pb, _pb2, _cfb1, _cfb2;
@@ -4962,7 +4931,7 @@ void Player::DurabilityPointsLossAll(int32 points, bool inventory)
//for (int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++)
for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++)
- if (Bag* pBag = (Bag*)GetItemByPos(INVENTORY_SLOT_BAG_0, i))
+ if (Bag* pBag = static_cast<Bag*>(GetItemByPos(INVENTORY_SLOT_BAG_0, i)))
for (uint32 j = 0; j < pBag->GetBagSize(); j++)
if (Item* pItem = GetItemByPos(i, j))
DurabilityPointsLoss(pItem, points);
@@ -5042,7 +5011,8 @@ uint32 Player::DurabilityRepair(uint16 pos, bool cost, float discountMod, bool g
DurabilityCostsEntry const* dcost = sDurabilityCostsStore.LookupEntry(ditemProto->ItemLevel);
if (!dcost)
{
- TC_LOG_ERROR("entities.player.items", "RepairDurability: Wrong item lvl %u", ditemProto->ItemLevel);
+ TC_LOG_ERROR("entities.player.items", "Player::DurabilityRepair: Player '%s' (%s) tried to repair an item (ItemID: %u) with invalid item level %u",
+ GetName().c_str(), GetGUID().ToString().c_str(), ditemProto->ItemId, ditemProto->ItemLevel);
return TotalCost;
}
@@ -5050,7 +5020,8 @@ uint32 Player::DurabilityRepair(uint16 pos, bool cost, float discountMod, bool g
DurabilityQualityEntry const* dQualitymodEntry = sDurabilityQualityStore.LookupEntry(dQualitymodEntryId);
if (!dQualitymodEntry)
{
- TC_LOG_ERROR("entities.player.items", "RepairDurability: Wrong dQualityModEntry %u", dQualitymodEntryId);
+ TC_LOG_ERROR("entities.player.items", "Player::DurabilityRepair: Player '%s' (%s) tried to repair an item (ItemID: %u) with invalid QualitymodEntry %u",
+ GetName().c_str(), GetGUID().ToString().c_str(), ditemProto->ItemId, dQualitymodEntryId);
return TotalCost;
}
@@ -5066,7 +5037,8 @@ uint32 Player::DurabilityRepair(uint16 pos, bool cost, float discountMod, bool g
{
if (GetGuildId() == 0)
{
- TC_LOG_DEBUG("entities.player.items", "You are not member of a guild");
+ TC_LOG_DEBUG("entities.player.items", "Player::DurabilityRepair: Player '%s' (%s) tried to repair item in a guild bank but is not member of a guild",
+ GetName().c_str(), GetGUID().ToString().c_str());
return TotalCost;
}
@@ -5081,7 +5053,8 @@ uint32 Player::DurabilityRepair(uint16 pos, bool cost, float discountMod, bool g
}
else if (!HasEnoughMoney(costs))
{
- TC_LOG_DEBUG("entities.player.items", "You do not have enough money");
+ TC_LOG_DEBUG("entities.player.items", "Player::DurabilityRepair: Player '%s' (%s) has not enough money to repair item",
+ GetName().c_str(), GetGUID().ToString().c_str());
return TotalCost;
}
else
@@ -5112,7 +5085,7 @@ void Player::RepopAtGraveyard()
SpawnCorpseBones();
}
- WorldSafeLocsEntry const* ClosestGrave = NULL;
+ WorldSafeLocsEntry const* ClosestGrave;
// Special handle for battleground maps
if (Battleground* bg = GetBattleground())
@@ -5149,7 +5122,7 @@ void Player::RepopAtGraveyard()
RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_IS_OUT_OF_BOUNDS);
}
-bool Player::CanJoinConstantChannelInZone(ChatChannelsEntry const* channel, AreaTableEntry const* zone)
+bool Player::CanJoinConstantChannelInZone(ChatChannelsEntry const* channel, AreaTableEntry const* zone) const
{
if (channel->flags & CHANNEL_DBC_FLAG_ZONE_DEP && zone->flags & AREA_FLAG_ARENA_INSTANCE)
return false;
@@ -5183,7 +5156,7 @@ void Player::CleanupChannels()
if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetTeam()))
cMgr->LeftChannel(ch->GetName()); // deleted channel if empty
}
- TC_LOG_DEBUG("chat.system", "Player %s: channels cleaned up!", GetName().c_str());
+ TC_LOG_DEBUG("chat.system", "Player::CleanupChannels: Channels of player '%s' (%s) cleaned up.", GetName().c_str(), GetGUID().ToString().c_str());
}
void Player::UpdateLocalChannels(uint32 newZone)
@@ -5205,7 +5178,7 @@ void Player::UpdateLocalChannels(uint32 newZone)
{
if (ChatChannelsEntry const* channel = sChatChannelsStore.LookupEntry(i))
{
- Channel* usedChannel = NULL;
+ Channel* usedChannel = nullptr;
for (JoinedChannelsList::iterator itr = m_channels.begin(); itr != m_channels.end(); ++itr)
{
@@ -5216,8 +5189,8 @@ void Player::UpdateLocalChannels(uint32 newZone)
}
}
- Channel* removeChannel = NULL;
- Channel* joinChannel = NULL;
+ Channel* removeChannel = nullptr;
+ Channel* joinChannel = nullptr;
bool sendRemove = true;
if (CanJoinConstantChannelInZone(channel, current_zone))
@@ -5246,7 +5219,7 @@ void Player::UpdateLocalChannels(uint32 newZone)
sendRemove = false; // Do not send leave channel, it already replaced at client
}
else
- joinChannel = NULL;
+ joinChannel = nullptr;
}
}
else
@@ -5291,7 +5264,8 @@ void Player::HandleBaseModValue(BaseModGroup modGroup, BaseModType modType, floa
{
if (modGroup >= BASEMOD_END || modType >= MOD_END)
{
- TC_LOG_ERROR("spells", "ERROR in HandleBaseModValue(): non existed BaseModGroup of wrong BaseModType!");
+ TC_LOG_ERROR("spells", "Player::HandleBaseModValue: Invalid BaseModGroup/BaseModType (%u/%u) for player '%s' (%s)",
+ modGroup, modType, GetName().c_str(), GetGUID().ToString().c_str());
return;
}
@@ -5317,7 +5291,8 @@ float Player::GetBaseModValue(BaseModGroup modGroup, BaseModType modType) const
{
if (modGroup >= BASEMOD_END || modType >= MOD_END)
{
- TC_LOG_ERROR("spells", "trial to access non existed BaseModGroup or wrong BaseModType!");
+ TC_LOG_ERROR("spells", "Player::GetBaseModValue: Invalid BaseModGroup/BaseModType (%u/%u) for player '%s' (%s)",
+ modGroup, modType, GetName().c_str(), GetGUID().ToString().c_str());
return 0.0f;
}
@@ -5331,7 +5306,8 @@ float Player::GetTotalBaseModValue(BaseModGroup modGroup) const
{
if (modGroup >= BASEMOD_END)
{
- TC_LOG_ERROR("spells", "wrong BaseModGroup in GetTotalBaseModValue()!");
+ TC_LOG_ERROR("spells", "Player::GetTotalBaseModValue: Invalid BaseModGroup (%u) for player '%s' (%s)",
+ modGroup, GetName().c_str(), GetGUID().ToString().c_str());
return 0.0f;
}
@@ -5350,7 +5326,7 @@ uint32 Player::GetShieldBlockValue() const
return uint32(value);
}
-float Player::GetMeleeCritFromAgility()
+float Player::GetMeleeCritFromAgility() const
{
uint8 level = getLevel();
uint32 pclass = getClass();
@@ -5360,14 +5336,14 @@ float Player::GetMeleeCritFromAgility()
GtChanceToMeleeCritBaseEntry const* critBase = sGtChanceToMeleeCritBaseStore.LookupEntry(pclass-1);
GtChanceToMeleeCritEntry const* critRatio = sGtChanceToMeleeCritStore.LookupEntry((pclass-1)*GT_MAX_LEVEL + level-1);
- if (critBase == NULL || critRatio == NULL)
+ if (critBase == nullptr || critRatio == nullptr)
return 0.0f;
float crit = critBase->base + GetStat(STAT_AGILITY)*critRatio->ratio;
return crit*100.0f;
}
-void Player::GetDodgeFromAgility(float &diminishing, float &nondiminishing)
+void Player::GetDodgeFromAgility(float &diminishing, float &nondiminishing) const
{
// Table for base dodge values
const float dodge_base[MAX_CLASSES] =
@@ -5408,7 +5384,7 @@ void Player::GetDodgeFromAgility(float &diminishing, float &nondiminishing)
// Dodge per agility is proportional to crit per agility, which is available from DBC files
GtChanceToMeleeCritEntry const* dodgeRatio = sGtChanceToMeleeCritStore.LookupEntry((pclass-1)*GT_MAX_LEVEL + level-1);
- if (dodgeRatio == NULL || pclass > MAX_CLASSES)
+ if (dodgeRatio == nullptr || pclass > MAX_CLASSES)
return;
/// @todo research if talents/effects that increase total agility by x% should increase non-diminishing part
@@ -5420,7 +5396,7 @@ void Player::GetDodgeFromAgility(float &diminishing, float &nondiminishing)
nondiminishing = 100.0f * (dodge_base[pclass-1] + base_agility * dodgeRatio->ratio * crit_to_dodge[pclass-1]);
}
-float Player::GetSpellCritFromIntellect()
+float Player::GetSpellCritFromIntellect() const
{
uint8 level = getLevel();
uint32 pclass = getClass();
@@ -5430,7 +5406,7 @@ float Player::GetSpellCritFromIntellect()
GtChanceToSpellCritBaseEntry const* critBase = sGtChanceToSpellCritBaseStore.LookupEntry(pclass-1);
GtChanceToSpellCritEntry const* critRatio = sGtChanceToSpellCritStore.LookupEntry((pclass-1)*GT_MAX_LEVEL + level-1);
- if (critBase == NULL || critRatio == NULL)
+ if (critBase == nullptr || critRatio == nullptr)
return 0.0f;
float crit=critBase->base + GetStat(STAT_INTELLECT)*critRatio->ratio;
@@ -5472,7 +5448,7 @@ float Player::GetExpertiseDodgeOrParryReduction(WeaponAttackType attType) const
return 0.0f;
}
-float Player::OCTRegenHPPerSpirit()
+float Player::OCTRegenHPPerSpirit() const
{
uint8 level = getLevel();
uint32 pclass = getClass();
@@ -5495,7 +5471,7 @@ float Player::OCTRegenHPPerSpirit()
return regen;
}
-float Player::OCTRegenMPPerSpirit()
+float Player::OCTRegenMPPerSpirit() const
{
uint8 level = getLevel();
uint32 pclass = getClass();
@@ -5505,7 +5481,7 @@ float Player::OCTRegenMPPerSpirit()
// GtOCTRegenMPEntry const* baseRatio = sGtOCTRegenMPStore.LookupEntry((pclass-1)*GT_MAX_LEVEL + level-1);
GtRegenMPPerSptEntry const* moreRatio = sGtRegenMPPerSptStore.LookupEntry((pclass-1)*GT_MAX_LEVEL + level-1);
- if (moreRatio == NULL)
+ if (moreRatio == nullptr)
return 0.0f;
// Formula get from PaperDollFrame script
@@ -5703,7 +5679,8 @@ inline int SkillGainChance(uint32 SkillValue, uint32 GrayLevel, uint32 GreenLeve
bool Player::UpdateCraftSkill(uint32 spellid)
{
- TC_LOG_DEBUG("entities.player.skills", "UpdateCraftSkill spellid %d", spellid);
+ TC_LOG_DEBUG("entities.player.skills", "Player::UpdateCraftSkill: Player '%s' (%s), SpellID: %d",
+ GetName().c_str(), GetGUID().ToString().c_str(), spellid);
SkillLineAbilityMapBounds bounds = sSpellMgr->GetSkillLineAbilityMapBounds(spellid);
@@ -5735,7 +5712,8 @@ bool Player::UpdateCraftSkill(uint32 spellid)
bool Player::UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator)
{
- TC_LOG_DEBUG("entities.player.skills", "UpdateGatherSkill(SkillId %d SkillLevel %d RedLevel %d)", SkillId, SkillValue, RedLevel);
+ TC_LOG_DEBUG("entities.player.skills", "Player::UpdateGatherSkill: Player '%s' (%s), SkillID: %u, SkillLevel: %u, RedLevel: %u)",
+ GetName().c_str(), GetGUID().ToString().c_str(), SkillId, SkillValue, RedLevel);
uint32 gathering_skill_gain = sWorld->getIntConfig(CONFIG_SKILL_GAIN_GATHERING);
@@ -5763,7 +5741,7 @@ bool Player::UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLeve
bool Player::UpdateFishingSkill()
{
- TC_LOG_DEBUG("entities.player.skills", "UpdateFishingSkill");
+ TC_LOG_DEBUG("entities.player.skills", "Player::UpdateFishingSkill: Player '%s' (%s)", GetName().c_str(), GetGUID().ToString().c_str());
uint32 SkillValue = GetPureSkillValue(SKILL_FISHING);
@@ -5782,13 +5760,15 @@ static const size_t bonusSkillLevelsSize = sizeof(bonusSkillLevels) / sizeof(uin
bool Player::UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step)
{
- TC_LOG_DEBUG("entities.player.skills", "UpdateSkillPro(SkillId %d, Chance %3.1f%%)", SkillId, Chance / 10.0f);
+ TC_LOG_DEBUG("entities.player.skills", "Player::UpdateSkillPro: Player '%s' (%s), SkillID: %u, Chance: %3.1f%%)",
+ GetName().c_str(), GetGUID().ToString().c_str(), SkillId, Chance / 10.0f);
if (!SkillId)
return false;
if (Chance <= 0) // speedup in 0 chance case
{
- TC_LOG_DEBUG("entities.player.skills", "Player::UpdateSkillPro Chance=%3.1f%% missed", Chance / 10.0f);
+ TC_LOG_DEBUG("entities.player.skills", "Player::UpdateSkillPro: Player '%s' (%s), SkillID: %u, Chance: %3.1f%% missed",
+ GetName().c_str(), GetGUID().ToString().c_str(), SkillId, Chance / 10.0f);
return false;
}
@@ -5827,11 +5807,13 @@ bool Player::UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step)
}
UpdateSkillEnchantments(SkillId, SkillValue, new_value);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, SkillId);
- TC_LOG_DEBUG("entities.player.skills", "Player::UpdateSkillPro Chance=%3.1f%% taken", Chance / 10.0f);
+ TC_LOG_DEBUG("entities.player.skills", "Player::UpdateSkillPro: Player '%s' (%s), SkillID: %u, Chance: %3.1f%% taken",
+ GetName().c_str(), GetGUID().ToString().c_str(), SkillId, Chance / 10.0f);
return true;
}
- TC_LOG_DEBUG("entities.player.skills", "Player::UpdateSkillPro Chance=%3.1f%% missed", Chance / 10.0f);
+ TC_LOG_DEBUG("entities.player.skills", "Player::UpdateSkillPro: Player '%s' (%s), SkillID: %u, Chance: %3.1f%% missed",
+ GetName().c_str(), GetGUID().ToString().c_str(), SkillId, Chance / 10.0f);
return false;
}
@@ -6065,7 +6047,8 @@ void Player::SetSkill(uint16 id, uint16 step, uint16 newVal, uint16 maxVal)
SkillLineEntry const* pSkill = sSkillLineStore.LookupEntry(id);
if (!pSkill)
{
- TC_LOG_ERROR("entities.player.skills", "Skill not found in SkillLineStore: skill #%u", id);
+ TC_LOG_ERROR("misc", "Player::SetSkill: Skill (SkillID: %u) not found in SkillLineStore for player '%s' (%s)",
+ id, GetName().c_str(), GetGUID().ToString().c_str());
return;
}
@@ -6247,20 +6230,22 @@ void Player::SendActionButtons(uint32 state) const
}
GetSession()->SendPacket(&data);
- TC_LOG_DEBUG("network", "SMSG_ACTION_BUTTONS sent '%u' spec '%u' Sent", GetGUID().GetCounter(), m_activeSpec);
+
}
-bool Player::IsActionButtonDataValid(uint8 button, uint32 action, uint8 type)
+bool Player::IsActionButtonDataValid(uint8 button, uint32 action, uint8 type) const
{
if (button >= MAX_ACTION_BUTTONS)
{
- TC_LOG_DEBUG("entities.player", "Action %u not added into button %u for player %s (GUID: %u): button must be < %u", action, button, GetName().c_str(), GetGUID().GetCounter(), MAX_ACTION_BUTTONS );
+ TC_LOG_ERROR("entities.player", "Player::IsActionButtonDataValid: Action %u not added into button %u for player %s (%s): button must be < %u",
+ action, button, GetName().c_str(), GetGUID().ToString().c_str(), MAX_ACTION_BUTTONS);
return false;
}
if (action >= MAX_ACTION_BUTTON_ACTION_VALUE)
{
- TC_LOG_DEBUG("entities.player", "Action %u not added into button %u for player %s (GUID: %u): action must be < %u", action, button, GetName().c_str(), GetGUID().GetCounter(), MAX_ACTION_BUTTON_ACTION_VALUE);
+ TC_LOG_ERROR("entities.player", "Player::IsActionButtonDataValid: Action %u not added into button %u for player %s (%s): action must be < %u",
+ action, button, GetName().c_str(), GetGUID().ToString().c_str(), MAX_ACTION_BUTTON_ACTION_VALUE);
return false;
}
@@ -6269,20 +6254,23 @@ bool Player::IsActionButtonDataValid(uint8 button, uint32 action, uint8 type)
case ACTION_BUTTON_SPELL:
if (!sSpellMgr->GetSpellInfo(action))
{
- TC_LOG_DEBUG("entities.player", "Spell action %u not added into button %u for player %s (GUID: %u): spell not exist", action, button, GetName().c_str(), GetGUID().GetCounter());
+ TC_LOG_ERROR("entities.player", "Player::IsActionButtonDataValid: Spell action %u not added into button %u for player %s (%s): spell not exist",
+ action, button, GetName().c_str(), GetGUID().ToString().c_str());
return false;
}
if (!HasSpell(action))
{
- TC_LOG_DEBUG("entities.player", "Spell action %u not added into button %u for player %s (GUID: %u): player don't known this spell", action, button, GetName().c_str(), GetGUID().GetCounter());
+ TC_LOG_ERROR("entities.player", "Player::IsActionButtonDataValid: Spell action %u not added into button %u for player %s (%s): player don't known this spell",
+ action, button, GetName().c_str(), GetGUID().ToString().c_str());
return false;
}
break;
case ACTION_BUTTON_ITEM:
if (!sObjectMgr->GetItemTemplate(action))
{
- TC_LOG_DEBUG("entities.player", "Item action %u not added into button %u for player %s (GUID: %u): item not exist", action, button, GetName().c_str(), GetGUID().GetCounter());
+ TC_LOG_ERROR("entities.player", "Player::IsActionButtonDataValid: Item action %u not added into button %u for player %s (%s): item not exist",
+ action, button, GetName().c_str(), GetGUID().ToString().c_str());
return false;
}
break;
@@ -6292,7 +6280,7 @@ bool Player::IsActionButtonDataValid(uint8 button, uint32 action, uint8 type)
case ACTION_BUTTON_EQSET:
break;
default:
- TC_LOG_DEBUG("entities.player", "Unknown action type %u", type);
+ TC_LOG_ERROR("entities.player", "Player::IsActionButtonDataValid: Unknown action type %u", type);
return false; // other cases not checked at this moment
}
@@ -6302,15 +6290,16 @@ bool Player::IsActionButtonDataValid(uint8 button, uint32 action, uint8 type)
ActionButton* Player::addActionButton(uint8 button, uint32 action, uint8 type)
{
if (!IsActionButtonDataValid(button, action, type))
- return NULL;
+ return nullptr;
- // it create new button (NEW state) if need or return existed
+ // it create new button (NEW state) if need or return existing
ActionButton& ab = m_actionButtons[button];
// set data and update to CHANGED if not NEW
ab.SetActionAndType(action, ActionButtonType(type));
- TC_LOG_DEBUG("entities.player", "Player '%u' Added Action '%u' (type %u) to Button '%u'", GetGUID().GetCounter(), action, type, button);
+ TC_LOG_DEBUG("entities.player", "Player::AddActionButton: Player '%s' (%s) added action '%u' (type %u) to button '%u'",
+ GetName().c_str(), GetGUID().ToString().c_str(), action, type, button);
return &ab;
}
@@ -6325,14 +6314,15 @@ void Player::removeActionButton(uint8 button)
else
buttonItr->second.uState = ACTIONBUTTON_DELETED; // saved, will deleted at next save
- TC_LOG_DEBUG("entities.player", "Action Button '%u' Removed from Player '%u'", button, GetGUID().GetCounter());
+ TC_LOG_DEBUG("entities.player", "Player::RemoveActionButton: Player '%s' (%s) removed action button '%u'",
+ GetName().c_str(), GetGUID().ToString().c_str(), button);
}
ActionButton const* Player::GetActionButton(uint8 button)
{
ActionButtonList::iterator buttonItr = m_actionButtons.find(button);
if (buttonItr == m_actionButtons.end() || buttonItr->second.uState == ACTIONBUTTON_DELETED)
- return NULL;
+ return nullptr;
return &buttonItr->second;
}
@@ -6404,19 +6394,19 @@ void Player::SendMessageToSet(WorldPacket* data, Player const* skipped_rcvr)
VisitNearbyWorldObject(GetVisibilityRange(), notifier);
}
-void Player::SendDirectMessage(WorldPacket* data)
+void Player::SendDirectMessage(WorldPacket const* data) const
{
m_session->SendPacket(data);
}
-void Player::SendCinematicStart(uint32 CinematicSequenceId)
+void Player::SendCinematicStart(uint32 CinematicSequenceId) const
{
WorldPacket data(SMSG_TRIGGER_CINEMATIC, 4);
data << uint32(CinematicSequenceId);
SendDirectMessage(&data);
}
-void Player::SendMovieStart(uint32 MovieId)
+void Player::SendMovieStart(uint32 MovieId) const
{
WorldPacket data(SMSG_TRIGGER_MOVIE, 4);
data << uint32(MovieId);
@@ -6475,7 +6465,7 @@ void Player::CheckAreaExploreAndOutdoor()
else
{
int32 diff = int32(getLevel()) - areaEntry->area_level;
- uint32 XP = 0;
+ uint32 XP;
if (diff < -5)
{
XP = uint32(sObjectMgr->GetBaseXP(getLevel()+5)*sWorld->getRate(RATE_XP_EXPLORE));
@@ -6493,7 +6483,7 @@ void Player::CheckAreaExploreAndOutdoor()
XP = uint32(sObjectMgr->GetBaseXP(areaEntry->area_level)*sWorld->getRate(RATE_XP_EXPLORE));
}
- GiveXP(XP, NULL);
+ GiveXP(XP, nullptr);
SendExplorationExperience(areaId, XP);
}
TC_LOG_DEBUG("entities.player", "Player '%s' (%s) discovered a new area: %u", GetName().c_str(),GetGUID().ToString().c_str(), areaId);
@@ -6710,8 +6700,8 @@ void Player::RewardReputation(Quest const* quest)
void Player::UpdateHonorFields()
{
/// called when rewarding honor and at each save
- time_t now = time_t(time(NULL));
- time_t today = time_t(time(NULL) / DAY) * DAY;
+ time_t now = time_t(time(nullptr));
+ time_t today = time_t(time(nullptr) / DAY) * DAY;
if (m_lastHonorUpdateTime < today)
{
@@ -6835,7 +6825,7 @@ bool Player::RewardHonor(Unit* victim, uint32 groupsize, int32 honor, bool pvpto
}
}
- if (victim != NULL)
+ if (victim != nullptr)
{
if (groupsize > 1)
honor_f /= groupsize;
@@ -6980,6 +6970,7 @@ void Player::SetInArenaTeam(uint32 ArenaTeamId, uint8 slot, uint8 type)
SetArenaTeamInfoField(slot, ARENA_TEAM_ID, ArenaTeamId);
SetArenaTeamInfoField(slot, ARENA_TEAM_TYPE, type);
}
+
void Player::SetArenaTeamInfoField(uint8 slot, ArenaTeamInfoType type, uint32 value)
{
SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * ARENA_TEAM_END) + type, value);
@@ -7212,7 +7203,7 @@ void Player::CheckDuelDistance(time_t currTime)
}
}
-bool Player::IsOutdoorPvPActive()
+bool Player::IsOutdoorPvPActive() const
{
return IsAlive() && !HasInvisibilityAura() && !HasStealthAura() && IsPvP() && !HasUnitMovementFlag(MOVEMENTFLAG_FLYING) && !IsInFlight();
}
@@ -7223,7 +7214,8 @@ void Player::DuelComplete(DuelCompleteType type)
if (!duel)
return;
- TC_LOG_DEBUG("entities.unit", "Duel Complete %s %s", GetName().c_str(), duel->opponent->GetName().c_str());
+ TC_LOG_DEBUG("entities.unit", "Player::DuelComplete: Player '%s' (%s), Opponent: '%s' (%s)",
+ GetName().c_str(), GetGUID().ToString().c_str(), duel->opponent->GetName().c_str(), duel->opponent->GetGUID().ToString().c_str());
WorldPacket data(SMSG_DUEL_COMPLETE, (1));
data << (uint8)((type != DUEL_INTERRUPTED) ? 1 : 0);
@@ -7271,7 +7263,7 @@ void Player::DuelComplete(DuelCompleteType type)
// Honor points after duel (the winner) - ImpConfig
if (uint32 amount = sWorld->getIntConfig(CONFIG_HONOR_AFTER_DUEL))
- duel->opponent->RewardHonor(NULL, 1, amount);
+ duel->opponent->RewardHonor(nullptr, 1, amount);
break;
default:
@@ -7326,9 +7318,9 @@ void Player::DuelComplete(DuelCompleteType type)
duel->opponent->SetUInt32Value(PLAYER_DUEL_TEAM, 0);
delete duel->opponent->duel;
- duel->opponent->duel = NULL;
+ duel->opponent->duel = nullptr;
delete duel;
- duel = NULL;
+ duel = nullptr;
}
//---------------------------------------------------------//
@@ -7347,7 +7339,7 @@ void Player::_ApplyItemMods(Item* item, uint8 slot, bool apply)
if (item->IsBroken())
return;
- TC_LOG_DEBUG("entities.player.items", "applying mods for item %u ", item->GetGUID().GetCounter());
+ TC_LOG_DEBUG("entities.player.items", "Player::_ApplyItemMods: Applying mods for item %s", item->GetGUID().ToString().c_str());
uint8 attacktype = Player::GetAttackBySlot(slot);
@@ -7365,7 +7357,7 @@ void Player::_ApplyItemMods(Item* item, uint8 slot, bool apply)
ApplyItemEquipSpell(item, apply);
ApplyEnchantment(item, apply);
- TC_LOG_DEBUG("entities.player.items", "_ApplyItemMods complete.");
+ TC_LOG_DEBUG("entities.player.items", "Player::_ApplyItemMods: completed");
}
void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply, bool only_level_scale /*= false*/)
@@ -7741,7 +7733,7 @@ void Player::_ApplyWeaponDependentAuraCritMod(Item* item, WeaponAttackType attac
if (aura->GetSpellInfo()->EquippedItemClass == -1)
return;
- BaseModGroup mod = BASEMOD_END;
+ BaseModGroup mod;
switch (attackType)
{
case BASE_ATTACK: mod = CRIT_PERCENTAGE; break;
@@ -7768,7 +7760,7 @@ void Player::_ApplyWeaponDependentAuraDamageMod(Item* item, WeaponAttackType att
if (aura->GetSpellInfo()->EquippedItemClass == -1)
return;
- UnitMods unitMod = UNIT_MOD_END;
+ UnitMods unitMod;
switch (attackType)
{
case BASE_ATTACK: unitMod = UNIT_MOD_DAMAGE_MAINHAND; break;
@@ -7777,7 +7769,7 @@ void Player::_ApplyWeaponDependentAuraDamageMod(Item* item, WeaponAttackType att
default: return;
}
- UnitModifierType unitModType = TOTAL_VALUE;
+ UnitModifierType unitModType;
switch (aura->GetAuraType())
{
case SPELL_AURA_MOD_DAMAGE_DONE: unitModType = TOTAL_VALUE; break;
@@ -7844,7 +7836,8 @@ void Player::ApplyEquipSpell(SpellInfo const* spellInfo, Item* item, bool apply,
return;
}
- TC_LOG_DEBUG("entities.player", "WORLD: cast %s Equip spellId - %i", (item ? "item" : "itemset"), spellInfo->Id);
+ TC_LOG_DEBUG("entities.player", "Player::ApplyEquipSpell: Player '%s' (%s) cast %s equip spell (ID: %i)",
+ GetName().c_str(), GetGUID().ToString().c_str(), (item ? "item" : "itemset"), spellInfo->Id);
CastSpell(this, spellInfo, true, item);
}
@@ -7950,7 +7943,8 @@ void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellData.SpellId);
if (!spellInfo)
{
- TC_LOG_ERROR("entities.player.items", "WORLD: unknown Item spellid %i", spellData.SpellId);
+ TC_LOG_ERROR("entities.player.items", "Player::CastItemCombatSpell: Player '%s' (%s) cast unknown item spell (ID: %i)",
+ GetName().c_str(), GetGUID().ToString().c_str(), spellData.SpellId);
continue;
}
@@ -8005,8 +7999,8 @@ void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(pEnchant->spellid[s]);
if (!spellInfo)
{
- TC_LOG_ERROR("entities.player.items", "Player::CastItemCombatSpell(GUID: %u, name: %s, enchant: %i): unknown spell %i is cast, ignoring...",
- GetGUID().GetCounter(), GetName().c_str(), pEnchant->ID, pEnchant->spellid[s]);
+ TC_LOG_ERROR("entities.player.items", "Player::CastItemCombatSpell: Player '%s' (%s) cast unknown spell (EnchantID: %u, SpellID: %i), ignoring",
+ GetName().c_str(), GetGUID().ToString().c_str(), pEnchant->ID, pEnchant->spellid[s]);
continue;
}
@@ -8050,7 +8044,7 @@ void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(learn_spell_id);
if (!spellInfo)
{
- TC_LOG_ERROR("entities.player", "Player::CastItemUseSpell: Item (Entry: %u) in have wrong spell id %u, ignoring ", proto->ItemId, learn_spell_id);
+ TC_LOG_ERROR("entities.player", "Player::CastItemUseSpell: Item (Entry: %u) has wrong spell id %u, ignoring.", proto->ItemId, learn_spell_id);
SendEquipError(EQUIP_ERR_NONE, item, NULL);
return;
}
@@ -8079,7 +8073,7 @@ void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellData.SpellId);
if (!spellInfo)
{
- TC_LOG_ERROR("entities.player", "Player::CastItemUseSpell: Item (Entry: %u) in have wrong spell id %u, ignoring", proto->ItemId, spellData.SpellId);
+ TC_LOG_ERROR("entities.player", "Player::CastItemUseSpell: Item (Entry: %u) has wrong spell id %u, ignoring", proto->ItemId, spellData.SpellId);
continue;
}
@@ -8106,7 +8100,7 @@ void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(pEnchant->spellid[s]);
if (!spellInfo)
{
- TC_LOG_ERROR("entities.player", "Player::CastItemUseSpell Enchant %i, cast unknown spell %i", pEnchant->ID, pEnchant->spellid[s]);
+ TC_LOG_ERROR("entities.player", "Player::CastItemUseSpell: Enchant %i, cast unknown spell %i", pEnchant->ID, pEnchant->spellid[s]);
continue;
}
@@ -8325,7 +8319,7 @@ void Player::RemovedInsignia(Player* looterPlr)
looterPlr->SendLoot(bones->GetGUID(), LOOT_INSIGNIA);
}
-void Player::SendLootRelease(ObjectGuid guid)
+void Player::SendLootRelease(ObjectGuid guid) const
{
WorldPacket data(SMSG_LOOT_RELEASE_RESPONSE, (8+1));
data << uint64(guid) << uint8(1);
@@ -8337,13 +8331,13 @@ void Player::SendLoot(ObjectGuid guid, LootType loot_type)
if (ObjectGuid lguid = GetLootGUID())
m_session->DoLootRelease(lguid);
- Loot* loot = 0;
+ Loot* loot;
PermissionTypes permission = ALL_PERMISSION;
- TC_LOG_DEBUG("loot", "Player::SendLoot");
+ TC_LOG_DEBUG("loot", "Player::SendLoot: Player: '%s' (%s), Loot: %s",
+ GetName().c_str(), GetGUID().ToString().c_str(), guid.ToString().c_str());
if (guid.IsGameObject())
{
- TC_LOG_DEBUG("loot", "IS_GAMEOBJECT_GUID(guid)");
GameObject* go = GetMap()->GetGameObject(guid);
// not check distance for GO in case owned GO (fishing bobber case, for example)
@@ -8552,7 +8546,6 @@ void Player::SendLoot(ObjectGuid guid, LootType loot_type)
}
else
{
- permission = NONE_PERMISSION;
SendLootError(guid, LOOT_ERROR_ALREADY_PICKPOCKETED);
return;
}
@@ -8667,7 +8660,7 @@ void Player::SendLoot(ObjectGuid guid, LootType loot_type)
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_LOOTING);
}
-void Player::SendLootError(ObjectGuid guid, LootError error)
+void Player::SendLootError(ObjectGuid guid, LootError error) const
{
WorldPacket data(SMSG_LOOT_RESPONSE, 10);
data << uint64(guid);
@@ -8676,20 +8669,20 @@ void Player::SendLootError(ObjectGuid guid, LootError error)
SendDirectMessage(&data);
}
-void Player::SendNotifyLootMoneyRemoved()
+void Player::SendNotifyLootMoneyRemoved() const
{
WorldPacket data(SMSG_LOOT_CLEAR_MONEY, 0);
GetSession()->SendPacket(&data);
}
-void Player::SendNotifyLootItemRemoved(uint8 lootSlot)
+void Player::SendNotifyLootItemRemoved(uint8 lootSlot) const
{
WorldPacket data(SMSG_LOOT_REMOVED, 1);
data << uint8(lootSlot);
GetSession()->SendPacket(&data);
}
-void Player::SendUpdateWorldState(uint32 Field, uint32 Value)
+void Player::SendUpdateWorldState(uint32 Field, uint32 Value) const
{
WorldPacket data(SMSG_UPDATE_WORLD_STATE, 8);
data << Field;
@@ -9324,7 +9317,7 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
SendBattlefieldWorldStates();
}
-void Player::SendBGWeekendWorldStates()
+void Player::SendBGWeekendWorldStates() const
{
for (uint32 i = 1; i < sBattlemasterListStore.GetNumRows(); ++i)
{
@@ -9339,7 +9332,7 @@ void Player::SendBGWeekendWorldStates()
}
}
-void Player::SendBattlefieldWorldStates()
+void Player::SendBattlefieldWorldStates() const
{
/// Send misc stuff that needs to be sent on every login, like the battle timers.
if (sWorld->getBoolConfig(CONFIG_WINTERGRASP_ENABLE))
@@ -9348,7 +9341,7 @@ void Player::SendBattlefieldWorldStates()
{
SendUpdateWorldState(BATTLEFIELD_WG_WORLD_STATE_ACTIVE, wg->IsWarTime() ? 0 : 1);
uint32 timer = wg->IsWarTime() ? 0 : (wg->GetTimer() / 1000); // 0 - Time to next battle
- SendUpdateWorldState(ClockWorldState[1], uint32(time(NULL) + timer));
+ SendUpdateWorldState(ClockWorldState[1], uint32(time(nullptr) + timer));
}
}
}
@@ -9362,18 +9355,18 @@ uint32 Player::GetXPRestBonus(uint32 xp)
SetRestBonus(GetRestBonus() - rested_bonus);
- TC_LOG_DEBUG("entities.player", "GetXPRestBonus: Player %s (%u) gain %u xp (+%u Rested Bonus). Rested points=%f", GetName().c_str(), GetGUID().GetCounter(), xp+rested_bonus, rested_bonus, GetRestBonus());
+ TC_LOG_DEBUG("entities.player", "Player::GetXPRestBonus: Player '%s' (%s) gain %u xp (+%u Rested Bonus). Rested points=%f", GetGUID().ToString().c_str(), GetName().c_str(), xp + rested_bonus, rested_bonus, GetRestBonus());
return rested_bonus;
}
-void Player::SetBindPoint(ObjectGuid guid)
+void Player::SetBindPoint(ObjectGuid guid) const
{
WorldPacket data(SMSG_BINDER_CONFIRM, 8);
data << uint64(guid);
GetSession()->SendPacket(&data);
}
-void Player::SendTalentWipeConfirm(ObjectGuid guid)
+void Player::SendTalentWipeConfirm(ObjectGuid guid) const
{
WorldPacket data(MSG_TALENT_WIPE_CONFIRM, (8+4));
data << uint64(guid);
@@ -9394,7 +9387,7 @@ void Player::ResetPetTalents()
CharmInfo* charmInfo = pet->GetCharmInfo();
if (!charmInfo)
{
- TC_LOG_ERROR("entities.player", "Object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUID().GetCounter(), pet->GetTypeId());
+ TC_LOG_ERROR("entities.player", "Object (GUID: %u TypeId: %u) is considered pet-like, but doesn't have charm info!", pet->GetGUID().GetCounter(), pet->GetTypeId());
return;
}
pet->resetTalents();
@@ -9430,24 +9423,24 @@ void Player::SetSheath(SheathState sheathed)
switch (sheathed)
{
case SHEATH_STATE_UNARMED: // no prepared weapon
- SetVirtualItemSlot(0, NULL);
- SetVirtualItemSlot(1, NULL);
- SetVirtualItemSlot(2, NULL);
+ SetVirtualItemSlot(0, nullptr);
+ SetVirtualItemSlot(1, nullptr);
+ SetVirtualItemSlot(2, nullptr);
break;
case SHEATH_STATE_MELEE: // prepared melee weapon
SetVirtualItemSlot(0, GetWeaponForAttack(BASE_ATTACK, true));
SetVirtualItemSlot(1, GetWeaponForAttack(OFF_ATTACK, true));
- SetVirtualItemSlot(2, NULL);
+ SetVirtualItemSlot(2, nullptr);
break;
case SHEATH_STATE_RANGED: // prepared ranged weapon
- SetVirtualItemSlot(0, NULL);
- SetVirtualItemSlot(1, NULL);
+ SetVirtualItemSlot(0, nullptr);
+ SetVirtualItemSlot(1, nullptr);
SetVirtualItemSlot(2, GetWeaponForAttack(RANGED_ATTACK, true));
break;
default:
- SetVirtualItemSlot(0, NULL);
- SetVirtualItemSlot(1, NULL);
- SetVirtualItemSlot(2, NULL);
+ SetVirtualItemSlot(0, nullptr);
+ SetVirtualItemSlot(1, nullptr);
+ SetVirtualItemSlot(2, nullptr);
break;
}
Unit::SetSheath(sheathed); // this must visualize Sheath changing for other players...
@@ -9795,7 +9788,7 @@ Item* Player::GetItemByGuid(ObjectGuid guid) const
if (pItem->GetGUID() == guid)
return pItem;
- return NULL;
+ return nullptr;
}
Item* Player::GetItemByPos(uint16 pos) const
@@ -9809,9 +9802,9 @@ Item* Player::GetItemByPos(uint8 bag, uint8 slot) const
{
if (bag == INVENTORY_SLOT_BAG_0 && (slot < BANK_SLOT_BAG_END || (slot >= KEYRING_SLOT_START && slot < CURRENCYTOKEN_SLOT_END)))
return m_items[slot];
- else if (Bag* pBag = GetBagByPos(bag))
+ if (Bag* pBag = GetBagByPos(bag))
return pBag->GetItemByPos(slot);
- return NULL;
+ return nullptr;
}
//Does additional check for disarmed weapons
@@ -9828,7 +9821,7 @@ Bag* Player::GetBagByPos(uint8 bag) const
|| (bag >= BANK_SLOT_BAG_START && bag < BANK_SLOT_BAG_END))
if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, bag))
return item->ToBag();
- return NULL;
+ return nullptr;
}
Item* Player::GetWeaponForAttack(WeaponAttackType attackType, bool useable /*= false*/) const
@@ -9839,41 +9832,41 @@ Item* Player::GetWeaponForAttack(WeaponAttackType attackType, bool useable /*= f
case BASE_ATTACK: slot = EQUIPMENT_SLOT_MAINHAND; break;
case OFF_ATTACK: slot = EQUIPMENT_SLOT_OFFHAND; break;
case RANGED_ATTACK: slot = EQUIPMENT_SLOT_RANGED; break;
- default: return NULL;
+ default: return nullptr;
}
- Item* item = NULL;
+ Item* item;
if (useable)
item = GetUseableItemByPos(INVENTORY_SLOT_BAG_0, slot);
else
item = GetItemByPos(INVENTORY_SLOT_BAG_0, slot);
if (!item || item->GetTemplate()->Class != ITEM_CLASS_WEAPON)
- return NULL;
+ return nullptr;
if (!useable)
return item;
if (item->IsBroken() || IsInFeralForm())
- return NULL;
+ return nullptr;
return item;
}
Item* Player::GetShield(bool useable) const
{
- Item* item = NULL;
+ Item* item;
if (useable)
item = GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
else
item = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
if (!item || item->GetTemplate()->Class != ITEM_CLASS_ARMOR)
- return NULL;
+ return nullptr;
if (!useable)
return item;
if (item->IsBroken())
- return NULL;
+ return nullptr;
return item;
}
@@ -9933,7 +9926,7 @@ bool Player::IsBagPos(uint16 pos)
return false;
}
-bool Player::IsValidPos(uint8 bag, uint8 slot, bool explicit_pos)
+bool Player::IsValidPos(uint8 bag, uint8 slot, bool explicit_pos) const
{
// post selected
if (bag == NULL_BAG && !explicit_pos)
@@ -10190,7 +10183,7 @@ InventoryResult Player::CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item
InventoryResult Player::CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 item, uint32 count, uint32* no_space_count /*= NULL*/) const
{
- return CanStoreItem(bag, slot, dest, item, count, NULL, false, no_space_count);
+ return CanStoreItem(bag, slot, dest, item, count, nullptr, false, no_space_count);
}
InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, Item* pItem, bool swap /*= false*/) const
@@ -10198,7 +10191,7 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec& des
if (!pItem)
return EQUIP_ERR_ITEM_NOT_FOUND;
uint32 count = pItem->GetCount();
- return CanStoreItem(bag, slot, dest, pItem->GetEntry(), count, pItem, swap, NULL);
+ return CanStoreItem(bag, slot, dest, pItem->GetEntry(), count, pItem, swap, nullptr);
}
bool Player::HasItemTotemCategory(uint32 TotemCategory) const
@@ -10237,7 +10230,7 @@ InventoryResult Player::CanStoreItem_InSpecificSlot(uint8 bag, uint8 slot, ItemP
// ignore move item (this slot will be empty at move)
if (pItem2 == pSrcItem)
- pItem2 = NULL;
+ pItem2 = nullptr;
uint32 need_space;
@@ -10311,7 +10304,7 @@ InventoryResult Player::CanStoreItem_InBag(uint8 bag, ItemPosCountVec &dest, Ite
if (bag == skip_bag)
return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
- // skip not existed bag or self targeted bag
+ // skip non-existing bag or self targeted bag
Bag* pBag = GetBagByPos(bag);
if (!pBag || pBag == pSrcItem)
return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
@@ -10323,7 +10316,7 @@ InventoryResult Player::CanStoreItem_InBag(uint8 bag, ItemPosCountVec &dest, Ite
if (!pBagProto)
return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
- // specialized bag mode or non-specilized
+ // specialized bag mode or non-specialized
if (non_specialized != (pBagProto->Class == ITEM_CLASS_CONTAINER && pBagProto->SubClass == ITEM_SUBCLASS_CONTAINER))
return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
@@ -10340,10 +10333,10 @@ InventoryResult Player::CanStoreItem_InBag(uint8 bag, ItemPosCountVec &dest, Ite
// ignore move item (this slot will be empty at move)
if (pItem2 == pSrcItem)
- pItem2 = NULL;
+ pItem2 = nullptr;
// if merge skip empty, if !merge skip non-empty
- if ((pItem2 != NULL) != merge)
+ if ((pItem2 != nullptr) != merge)
continue;
uint32 need_space = pProto->GetMaxStackSize();
@@ -10391,10 +10384,10 @@ InventoryResult Player::CanStoreItem_InInventorySlots(uint8 slot_begin, uint8 sl
// ignore move item (this slot will be empty at move)
if (pItem2 == pSrcItem)
- pItem2 = NULL;
+ pItem2 = nullptr;
// if merge skip empty, if !merge skip non-empty
- if ((pItem2 != NULL) != merge)
+ if ((pItem2 != nullptr) != merge)
continue;
uint32 need_space = pProto->GetMaxStackSize();
@@ -10428,7 +10421,7 @@ InventoryResult Player::CanStoreItem_InInventorySlots(uint8 slot_begin, uint8 sl
InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 entry, uint32 count, Item* pItem, bool swap, uint32* no_space_count) const
{
- TC_LOG_DEBUG("entities.player.items", "STORAGE: CanStoreItem bag = %u, slot = %u, item = %u, count = %u", bag, slot, entry, count);
+ TC_LOG_DEBUG("entities.player.items", "Player::CanStoreItem: Bag: %u, Slot: %u, Item: %u, Count: %u", bag, slot, entry, count);
ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(entry);
if (!pProto)
@@ -10913,7 +10906,8 @@ InventoryResult Player::CanStoreItems(Item** items, int count, uint32* itemLimit
if (!item)
continue;
- TC_LOG_DEBUG("entities.player.items", "STORAGE: CanStoreItems %i. item = %u, count = %u", k + 1, item->GetEntry(), item->GetCount());
+ TC_LOG_DEBUG("entities.player.items", "Player::CanStoreItems: Player '%s' (%s), Index: %i ItemID: %u, Count: %u",
+ GetName().c_str(), GetGUID().ToString().c_str(), k + 1, item->GetEntry(), item->GetCount());
ItemTemplate const* pProto = item->GetTemplate();
// strange item
@@ -11130,7 +11124,8 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16 &dest, Item* pItem, bool
dest = 0;
if (pItem)
{
- TC_LOG_DEBUG("entities.player.items", "STORAGE: CanEquipItem slot = %u, item = %u, count = %u", slot, pItem->GetEntry(), pItem->GetCount());
+ TC_LOG_DEBUG("entities.player.items", "Player::CanEquipItem: Player '%s' (%s), Slot: %u, Item: %u, Count: %u",
+ GetName().c_str(), GetGUID().ToString().c_str(), slot, pItem->GetEntry(), pItem->GetCount());
ItemTemplate const* pProto = pItem->GetTemplate();
if (pProto)
{
@@ -11296,11 +11291,12 @@ InventoryResult Player::CanUnequipItem(uint16 pos, bool swap) const
Item* pItem = GetItemByPos(pos);
- // Applied only to existed equipped item
+ // Applied only to existing equipped item
if (!pItem)
return EQUIP_ERR_OK;
- TC_LOG_DEBUG("entities.player.items", "STORAGE: CanUnequipItem slot = %u, item = %u, count = %u", pos, pItem->GetEntry(), pItem->GetCount());
+ TC_LOG_DEBUG("entities.player.items", "Player::CanUnequipItem: Player '%s' (%s), Slot: %u, Item: %u, Count: %u",
+ GetName().c_str(), GetGUID().ToString().c_str(), pos, pItem->GetEntry(), pItem->GetCount());
ItemTemplate const* pProto = pItem->GetTemplate();
if (!pProto)
@@ -11336,7 +11332,8 @@ InventoryResult Player::CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest
uint32 count = pItem->GetCount();
- TC_LOG_DEBUG("entities.player.items", "STORAGE: CanBankItem bag = %u, slot = %u, item = %u, count = %u", bag, slot, pItem->GetEntry(), pItem->GetCount());
+ TC_LOG_DEBUG("entities.player.items", "Player::CanBankItem: Player '%s' (%s), Bag: %u, Slot: %u, Item: %u, Count: %u",
+ GetName().c_str(), GetGUID().ToString().c_str(), bag, slot, pItem->GetEntry(), pItem->GetCount());
ItemTemplate const* pProto = pItem->GetTemplate();
if (!pProto)
return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED : EQUIP_ERR_ITEM_NOT_FOUND;
@@ -11352,8 +11349,8 @@ InventoryResult Player::CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest
uint8 pItemslot = pItem->GetSlot();
if (pItemslot >= CURRENCYTOKEN_SLOT_START && pItemslot < CURRENCYTOKEN_SLOT_END)
{
- TC_LOG_ERROR("entities.player", "Possible hacking attempt: Player %s [guid: %u] tried to move token [guid: %u, entry: %u] out of the currency bag!",
- GetName().c_str(), GetGUID().GetCounter(), pItem->GetGUID().GetCounter(), pProto->ItemId);
+ TC_LOG_ERROR("entities.player", "Possible hacking attempt: Player %s (%s) tried to move token [%s entry: %u] out of the currency bag!",
+ GetName().c_str(), GetGUID().ToString().c_str(), pItem->GetGUID().ToString().c_str(), pProto->ItemId);
return EQUIP_ERR_ITEMS_CANT_BE_SWAPPED;
}
@@ -11520,7 +11517,8 @@ InventoryResult Player::CanUseItem(Item* pItem, bool not_loading) const
{
if (pItem)
{
- TC_LOG_DEBUG("entities.player.items", "STORAGE: CanUseItem item = %u", pItem->GetEntry());
+ TC_LOG_DEBUG("entities.player.items", "Player::CanUseItem: Player '%s' (%s), Item: %u",
+ GetName().c_str(), GetGUID().ToString().c_str(), pItem->GetEntry());
if (!IsAlive() && not_loading)
return EQUIP_ERR_YOU_ARE_DEAD;
@@ -11801,7 +11799,7 @@ Item* Player::StoreNewItem(ItemPosCountVec const& dest, uint32 item, bool update
Item* Player::StoreItem(ItemPosCountVec const& dest, Item* pItem, bool update)
{
if (!pItem)
- return NULL;
+ return nullptr;
Item* lastItem = pItem;
for (ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end();)
@@ -11826,12 +11824,13 @@ Item* Player::StoreItem(ItemPosCountVec const& dest, Item* pItem, bool update)
Item* Player::_StoreItem(uint16 pos, Item* pItem, uint32 count, bool clone, bool update)
{
if (!pItem)
- return NULL;
+ return nullptr;
uint8 bag = pos >> 8;
uint8 slot = pos & 255;
- TC_LOG_DEBUG("entities.player.items", "STORAGE: StoreItem bag = %u, slot = %u, item = %u, count = %u, guid = %u", bag, slot, pItem->GetEntry(), count, pItem->GetGUID().GetCounter());
+ TC_LOG_DEBUG("entities.player.items", "Player::_StoreItem: Player '%s' (%s), Bag: %u, Slot: %u, Item: %u (%s), Count: %u",
+ GetName().c_str(), GetGUID().ToString().c_str(), bag, slot, pItem->GetEntry(), pItem->GetGUID().ToString().c_str(), count);
Item* pItem2 = GetItemByPos(bag, slot);
@@ -11843,7 +11842,7 @@ Item* Player::_StoreItem(uint16 pos, Item* pItem, uint32 count, bool clone, bool
pItem->SetCount(count);
if (!pItem)
- return NULL;
+ return nullptr;
if (pItem->GetTemplate()->Bonding == BIND_WHEN_PICKED_UP ||
pItem->GetTemplate()->Bonding == BIND_QUEST_ITEM ||
@@ -11859,7 +11858,7 @@ Item* Player::_StoreItem(uint16 pos, Item* pItem, uint32 count, bool clone, bool
pItem->SetGuidValue(ITEM_FIELD_OWNER, GetGUID());
pItem->SetSlot(slot);
- pItem->SetContainer(NULL);
+ pItem->SetContainer(nullptr);
// need update known currency
if (slot >= CURRENCYTOKEN_SLOT_START && slot < CURRENCYTOKEN_SLOT_END)
@@ -11944,7 +11943,7 @@ Item* Player::EquipNewItem(uint16 pos, uint32 item, bool update)
return EquipItem(pos, pItem, update);
}
- return NULL;
+ return nullptr;
}
Item* Player::EquipItem(uint16 pos, Item* pItem, bool update)
@@ -11977,7 +11976,8 @@ Item* Player::EquipItem(uint16 pos, Item* pItem, bool update)
SpellInfo const* spellProto = sSpellMgr->GetSpellInfo(cooldownSpell);
if (!spellProto)
- TC_LOG_ERROR("entities.player", "Weapon switch cooldown spell %u couldn't be found in Spell.dbc", cooldownSpell);
+ TC_LOG_ERROR("entities.player", "Player::EquipItem: Weapon switch cooldown spell %u for player '%s' (%s) couldn't be found in Spell.dbc",
+ cooldownSpell, GetName().c_str(), GetGUID().ToString().c_str());
else
{
m_weaponChangeTimer = spellProto->StartRecoveryTime;
@@ -12097,14 +12097,15 @@ void Player::VisualizeItem(uint8 slot, Item* pItem)
if (pItem->GetTemplate()->Bonding == BIND_WHEN_EQUIPED || pItem->GetTemplate()->Bonding == BIND_WHEN_PICKED_UP || pItem->GetTemplate()->Bonding == BIND_QUEST_ITEM)
pItem->SetBinding(true);
- TC_LOG_DEBUG("entities.player.items", "STORAGE: EquipItem slot = %u, item = %u", slot, pItem->GetEntry());
+ TC_LOG_DEBUG("entities.player.items", "Player::SetVisibleItemSlot: Player '%s' (%s), Slot: %u, Item: %u",
+ GetName().c_str(), GetGUID().ToString().c_str(), slot, pItem->GetEntry());
m_items[slot] = pItem;
SetGuidValue(PLAYER_FIELD_INV_SLOT_HEAD + (slot * 2), pItem->GetGUID());
pItem->SetGuidValue(ITEM_FIELD_CONTAINED, GetGUID());
pItem->SetGuidValue(ITEM_FIELD_OWNER, GetGUID());
pItem->SetSlot(slot);
- pItem->SetContainer(NULL);
+ pItem->SetContainer(nullptr);
if (slot < EQUIPMENT_SLOT_END)
SetVisibleItemSlot(slot, pItem);
@@ -12127,7 +12128,8 @@ void Player::RemoveItem(uint8 bag, uint8 slot, bool update)
Item* pItem = GetItemByPos(bag, slot);
if (pItem)
{
- TC_LOG_DEBUG("entities.player.items", "STORAGE: RemoveItem bag = %u, slot = %u, item = %u", bag, slot, pItem->GetEntry());
+ TC_LOG_DEBUG("entities.player.items", "Player::RemoveItem: Player '%s' (%s), Bag: %u, Slot: %u, Item: %u",
+ GetName().c_str(), GetGUID().ToString().c_str(), bag, slot, pItem->GetEntry());
RemoveEnchantmentDurations(pItem);
RemoveItemDurations(pItem);
@@ -12181,11 +12183,11 @@ void Player::RemoveItem(uint8 bag, uint8 slot, bool update)
}
}
- m_items[slot] = NULL;
+ m_items[slot] = nullptr;
SetGuidValue(PLAYER_FIELD_INV_SLOT_HEAD + (slot * 2), ObjectGuid::Empty);
if (slot < EQUIPMENT_SLOT_END)
- SetVisibleItemSlot(slot, NULL);
+ SetVisibleItemSlot(slot, nullptr);
}
else if (Bag* pBag = GetBagByPos(bag))
pBag->RemoveItem(slot, update);
@@ -12225,7 +12227,7 @@ void Player::MoveItemToInventory(ItemPosCountVec const& dest, Item* pItem, bool
// store item
Item* pLastItem = StoreItem(dest, pItem, update);
- // only set if not merged to existed stack (pItem can be deleted already but we can compare pointers any way)
+ // only set if not merged to existing stack (pItem can be deleted already but we can compare pointers any way)
if (pLastItem == pItem)
{
// update owner for last item (this can be original item with wrong owner
@@ -12246,7 +12248,8 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update)
Item* pItem = GetItemByPos(bag, slot);
if (pItem)
{
- TC_LOG_DEBUG("entities.player.items", "STORAGE: DestroyItem bag = %u, slot = %u, item = %u", bag, slot, pItem->GetEntry());
+ TC_LOG_DEBUG("entities.player.items", "Player::DestroyItem: Player '%s' (%s), Bag: %u, Slot: %u, Item: %u",
+ GetName().c_str(), GetGUID().ToString().c_str(), bag, slot, pItem->GetEntry());
// Also remove all contained items if the item is a bag.
// This if () prevents item saving crashes if the condition for a bag to be empty before being destroyed was bypassed somehow.
if (pItem->IsNotEmptyBag())
@@ -12315,10 +12318,10 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update)
UpdateExpertise(OFF_ATTACK);
// equipment visual show
- SetVisibleItemSlot(slot, NULL);
+ SetVisibleItemSlot(slot, nullptr);
}
- m_items[slot] = NULL;
+ m_items[slot] = nullptr;
}
else if (Bag* pBag = GetBagByPos(bag))
pBag->RemoveItem(slot, update);
@@ -12344,7 +12347,8 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update)
void Player::DestroyItemCount(uint32 itemEntry, uint32 count, bool update, bool unequip_check)
{
- TC_LOG_DEBUG("entities.player.items", "STORAGE: DestroyItemCount item = %u, count = %u", itemEntry, count);
+ TC_LOG_DEBUG("entities.player.items", "Player::DestroyItemCount: Player '%s' (%s), Item: %u, Count: %u",
+ GetName().c_str(), GetGUID().ToString().c_str(), itemEntry, count);
uint32 remcount = 0;
// in inventory
@@ -12535,7 +12539,8 @@ void Player::DestroyItemCount(uint32 itemEntry, uint32 count, bool update, bool
void Player::DestroyZoneLimitedItem(bool update, uint32 new_zone)
{
- TC_LOG_DEBUG("entities.player.items", "STORAGE: DestroyZoneLimitedItem in map %u and area %u", GetMapId(), new_zone);
+ TC_LOG_DEBUG("entities.player.items", "Player::DestroyZoneLimitedItem: In map %u and area %u for player '%s' (%s)",
+ GetMapId(), new_zone, GetName().c_str(), GetGUID().ToString().c_str());
// in inventory
for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++)
@@ -12567,7 +12572,8 @@ void Player::DestroyConjuredItems(bool update)
{
// used when entering arena
// destroys all conjured items
- TC_LOG_DEBUG("entities.player.items", "STORAGE: DestroyConjuredItems");
+ TC_LOG_DEBUG("entities.player.items", "Player::DestroyConjuredItems: Player '%s' (%s)",
+ GetName().c_str(), GetGUID().ToString().c_str());
// in inventory
for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++)
@@ -12615,7 +12621,7 @@ Item* Player::GetItemByEntry(uint32 entry) const
if (pItem->GetEntry() == entry)
return pItem;
- return NULL;
+ return nullptr;
}
void Player::DestroyItemCount(Item* pItem, uint32 &count, bool update)
@@ -12623,7 +12629,8 @@ void Player::DestroyItemCount(Item* pItem, uint32 &count, bool update)
if (!pItem)
return;
- TC_LOG_DEBUG("entities.player.items", "STORAGE: DestroyItemCount item (GUID: %u, Entry: %u) count = %u", pItem->GetGUID().GetCounter(), pItem->GetEntry(), count);
+ TC_LOG_DEBUG("entities.player.items", "Player::DestroyItemCount: Player '%s' (%s), Item (%s, Entry: %u), Count: %u",
+ GetName().c_str(), GetGUID().ToString().c_str(), pItem->GetGUID().ToString().c_str(), pItem->GetEntry(), count);
if (pItem->GetCount() <= count)
{
@@ -12653,28 +12660,28 @@ void Player::SplitItem(uint16 src, uint16 dst, uint32 count)
Item* pSrcItem = GetItemByPos(srcbag, srcslot);
if (!pSrcItem)
{
- SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pSrcItem, NULL);
+ SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pSrcItem, nullptr);
return;
}
if (pSrcItem->m_lootGenerated) // prevent split looting item (item
{
//best error message found for attempting to split while looting
- SendEquipError(EQUIP_ERR_COULDNT_SPLIT_ITEMS, pSrcItem, NULL);
+ SendEquipError(EQUIP_ERR_COULDNT_SPLIT_ITEMS, pSrcItem, nullptr);
return;
}
// not let split all items (can be only at cheating)
if (pSrcItem->GetCount() == count)
{
- SendEquipError(EQUIP_ERR_COULDNT_SPLIT_ITEMS, pSrcItem, NULL);
+ SendEquipError(EQUIP_ERR_COULDNT_SPLIT_ITEMS, pSrcItem, nullptr);
return;
}
- // not let split more existed items (can be only at cheating)
+ // not let split more existing items (can be only at cheating)
if (pSrcItem->GetCount() < count)
{
- SendEquipError(EQUIP_ERR_TRIED_TO_SPLIT_MORE_THAN_COUNT, pSrcItem, NULL);
+ SendEquipError(EQUIP_ERR_TRIED_TO_SPLIT_MORE_THAN_COUNT, pSrcItem, nullptr);
return;
}
@@ -12686,11 +12693,12 @@ void Player::SplitItem(uint16 src, uint16 dst, uint32 count)
return;
}
- TC_LOG_DEBUG("entities.player.items", "STORAGE: SplitItem bag = %u, slot = %u, item = %u, count = %u", dstbag, dstslot, pSrcItem->GetEntry(), count);
+ TC_LOG_DEBUG("entities.player.items", "Player::SplitItem: Player '%s' (%s), Bag: %u, Slot: %u, Item: %u, Count: %u",
+ GetName().c_str(), GetGUID().ToString().c_str(), dstbag, dstslot, pSrcItem->GetEntry(), count);
Item* pNewItem = pSrcItem->CloneItem(count, this);
if (!pNewItem)
{
- SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pSrcItem, NULL);
+ SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pSrcItem, nullptr);
return;
}
@@ -12705,7 +12713,7 @@ void Player::SplitItem(uint16 src, uint16 dst, uint32 count)
{
delete pNewItem;
pSrcItem->SetCount(pSrcItem->GetCount() + count);
- SendEquipError(msg, pSrcItem, NULL);
+ SendEquipError(msg, pSrcItem, nullptr);
return;
}
@@ -12725,7 +12733,7 @@ void Player::SplitItem(uint16 src, uint16 dst, uint32 count)
{
delete pNewItem;
pSrcItem->SetCount(pSrcItem->GetCount() + count);
- SendEquipError(msg, pSrcItem, NULL);
+ SendEquipError(msg, pSrcItem, nullptr);
return;
}
@@ -12745,7 +12753,7 @@ void Player::SplitItem(uint16 src, uint16 dst, uint32 count)
{
delete pNewItem;
pSrcItem->SetCount(pSrcItem->GetCount() + count);
- SendEquipError(msg, pSrcItem, NULL);
+ SendEquipError(msg, pSrcItem, nullptr);
return;
}
@@ -12771,7 +12779,8 @@ void Player::SwapItem(uint16 src, uint16 dst)
if (!pSrcItem)
return;
- TC_LOG_DEBUG("entities.player.items", "STORAGE: SwapItem bag = %u, slot = %u, item = %u", dstbag, dstslot, pSrcItem->GetEntry());
+ TC_LOG_DEBUG("entities.player.items", "Player::SwapItem: Player '%s' (%s), Bag: %u, Slot: %u, Item: %u",
+ GetName().c_str(), GetGUID().ToString().c_str(), dstbag, dstslot, pSrcItem->GetEntry());
if (!IsAlive())
{
@@ -12836,7 +12845,7 @@ void Player::SwapItem(uint16 src, uint16 dst)
InventoryResult msg = CanStoreItem(dstbag, dstslot, dest, pSrcItem, false);
if (msg != EQUIP_ERR_OK)
{
- SendEquipError(msg, pSrcItem, NULL);
+ SendEquipError(msg, pSrcItem, nullptr);
return;
}
@@ -12851,7 +12860,7 @@ void Player::SwapItem(uint16 src, uint16 dst)
InventoryResult msg = CanBankItem(dstbag, dstslot, dest, pSrcItem, false);
if (msg != EQUIP_ERR_OK)
{
- SendEquipError(msg, pSrcItem, NULL);
+ SendEquipError(msg, pSrcItem, nullptr);
return;
}
@@ -12865,7 +12874,7 @@ void Player::SwapItem(uint16 src, uint16 dst)
InventoryResult msg = CanEquipItem(dstslot, dest, pSrcItem, false);
if (msg != EQUIP_ERR_OK)
{
- SendEquipError(msg, pSrcItem, NULL);
+ SendEquipError(msg, pSrcItem, nullptr);
return;
}
@@ -12974,8 +12983,8 @@ void Player::SwapItem(uint16 src, uint16 dst)
{
if (Bag* dstBag = pDstItem->ToBag())
{
- Bag* emptyBag = NULL;
- Bag* fullBag = NULL;
+ Bag* emptyBag = nullptr;
+ Bag* fullBag = nullptr;
if (srcBag->IsEmpty() && !IsBagPos(src))
{
emptyBag = srcBag;
@@ -13088,7 +13097,6 @@ void Player::SwapItem(uint16 src, uint16 dst)
if (bagItem->m_lootGenerated)
{
m_session->DoLootRelease(GetLootGUID());
- released = true; // not realy needed here
break;
}
}
@@ -13133,10 +13141,11 @@ void Player::AddItemToBuyBackSlot(Item* pItem)
}
RemoveItemFromBuyBackSlot(slot, true);
- TC_LOG_DEBUG("entities.player.items", "STORAGE: AddItemToBuyBackSlot item = %u, slot = %u", pItem->GetEntry(), slot);
+ TC_LOG_DEBUG("entities.player.items", "Player::AddItemToBuyBackSlot: Player '%s' (%s), Item: %u, Slot: %u",
+ GetName().c_str(), GetGUID().ToString().c_str(), pItem->GetEntry(), slot);
m_items[slot] = pItem;
- time_t base = time(NULL);
+ time_t base = time(nullptr);
uint32 etime = uint32(base - m_logintime + (30 * 3600));
uint32 eslot = slot - BUYBACK_SLOT_START;
@@ -13155,15 +13164,17 @@ void Player::AddItemToBuyBackSlot(Item* pItem)
Item* Player::GetItemFromBuyBackSlot(uint32 slot)
{
- TC_LOG_DEBUG("entities.player.items", "STORAGE: GetItemFromBuyBackSlot slot = %u", slot);
+ TC_LOG_DEBUG("entities.player.items", "Player::GetItemFromBuyBackSlot: Player '%s' (%s), Slot: %u",
+ GetName().c_str(), GetGUID().ToString().c_str(), slot);
if (slot >= BUYBACK_SLOT_START && slot < BUYBACK_SLOT_END)
return m_items[slot];
- return NULL;
+ return nullptr;
}
void Player::RemoveItemFromBuyBackSlot(uint32 slot, bool del)
{
- TC_LOG_DEBUG("entities.player.items", "STORAGE: RemoveItemFromBuyBackSlot slot = %u", slot);
+ TC_LOG_DEBUG("entities.player.items", "Player::RemoveItemFromBuyBackSlot: Player '%s' (%s), Slot: %u",
+ GetName().c_str(), GetGUID().ToString().c_str(), slot);
if (slot >= BUYBACK_SLOT_START && slot < BUYBACK_SLOT_END)
{
Item* pItem = m_items[slot];
@@ -13174,7 +13185,7 @@ void Player::RemoveItemFromBuyBackSlot(uint32 slot, bool del)
pItem->SetState(ITEM_REMOVED, this);
}
- m_items[slot] = NULL;
+ m_items[slot] = nullptr;
uint32 eslot = slot - BUYBACK_SLOT_START;
SetGuidValue(PLAYER_FIELD_VENDORBUYBACK_SLOT_1 + (eslot * 2), ObjectGuid::Empty);
@@ -13187,9 +13198,9 @@ void Player::RemoveItemFromBuyBackSlot(uint32 slot, bool del)
}
}
-void Player::SendEquipError(InventoryResult msg, Item* pItem, Item* pItem2, uint32 itemid)
+void Player::SendEquipError(InventoryResult msg, Item* pItem, Item* pItem2, uint32 itemid) const
{
- TC_LOG_DEBUG("network", "WORLD: Sent SMSG_INVENTORY_CHANGE_FAILURE (%u)", msg);
+
WorldPacket data(SMSG_INVENTORY_CHANGE_FAILURE, (msg == EQUIP_ERR_CANT_EQUIP_LEVEL_I ? 22 : 18));
data << uint8(msg);
@@ -13230,9 +13241,8 @@ void Player::SendEquipError(InventoryResult msg, Item* pItem, Item* pItem2, uint
GetSession()->SendPacket(&data);
}
-void Player::SendBuyError(BuyResult msg, Creature* creature, uint32 item, uint32 param)
+void Player::SendBuyError(BuyResult msg, Creature* creature, uint32 item, uint32 param) const
{
- TC_LOG_DEBUG("network", "WORLD: Sent SMSG_BUY_FAILED");
WorldPacket data(SMSG_BUY_FAILED, (8+4+4+1));
data << uint64(creature ? creature->GetGUID() : ObjectGuid::Empty);
data << uint32(item);
@@ -13242,9 +13252,8 @@ void Player::SendBuyError(BuyResult msg, Creature* creature, uint32 item, uint32
GetSession()->SendPacket(&data);
}
-void Player::SendSellError(SellResult msg, Creature* creature, ObjectGuid guid, uint32 param)
+void Player::SendSellError(SellResult msg, Creature* creature, ObjectGuid guid, uint32 param) const
{
- TC_LOG_DEBUG("network", "WORLD: Sent SMSG_SELL_ITEM");
WorldPacket data(SMSG_SELL_ITEM, (8+8+(param?4:0)+1)); // last check 2.0.10
data << uint64(creature ? creature->GetGUID() : ObjectGuid::Empty);
data << uint64(guid);
@@ -13280,9 +13289,9 @@ void Player::TradeCancel(bool sendback)
// cleanup
delete m_trade;
- m_trade = NULL;
+ m_trade = nullptr;
delete trader->m_trade;
- trader->m_trade = NULL;
+ trader->m_trade = nullptr;
}
}
@@ -13314,7 +13323,8 @@ void Player::UpdateItemDuration(uint32 time, bool realtimeonly)
if (m_itemDuration.empty())
return;
- TC_LOG_DEBUG("entities.player.items", "Player::UpdateItemDuration(%u, %u)", time, realtimeonly);
+ TC_LOG_DEBUG("entities.player.items", "Player::UpdateItemDuration: Player '%s' (%s), Time: %u, RealTimeOnly: %u",
+ GetName().c_str(), GetGUID().ToString().c_str(), time, realtimeonly);
for (ItemDurationList::const_iterator itr = m_itemDuration.begin(); itr != m_itemDuration.end();)
{
@@ -13775,7 +13785,7 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
{
if (getClass() == CLASS_SHAMAN)
{
- float addValue = 0.0f;
+ float addValue;
if (item->GetSlot() == EQUIPMENT_SLOT_MAINHAND)
{
addValue = float(enchant_amount * item->GetTemplate()->Delay / 1000.0f);
@@ -13796,7 +13806,8 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
// nothing do..
break;
default:
- TC_LOG_ERROR("entities.player", "Unknown item enchantment (id = %d) display type: %d", enchant_id, enchant_display_type);
+ TC_LOG_ERROR("entities.player", "Player::ApplyEnchantment: Unknown item enchantment (ID: %u, DisplayType: %u) for player '%s' (%s)",
+ enchant_id, enchant_display_type, GetName().c_str(), GetGUID().ToString().c_str());
break;
} /*switch (enchant_display_type)*/
} /*for*/
@@ -13967,7 +13978,7 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId /*= 0*/, bool
VendorItemData const* vendorItems = creature->GetVendorItems();
if (!vendorItems || vendorItems->Empty())
{
- TC_LOG_ERROR("sql.sql", "Creature %s (Entry: %u GUID: %u DB GUID: %u) has UNIT_NPC_FLAG_VENDOR set but has an empty trading item list.", creature->GetName().c_str(), creature->GetEntry(), creature->GetGUID().GetCounter(), creature->GetSpawnId());
+ TC_LOG_ERROR("sql.sql", "Creature %s (Entry: %u GUID: %u DB GUID: %u) has UNIT_NPC_FLAG_VENDOR set, but has an empty trading item list.", creature->GetName().c_str(), creature->GetEntry(), creature->GetGUID().GetCounter(), creature->GetSpawnId());
canTalk = false;
}
break;
@@ -14001,7 +14012,7 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId /*= 0*/, bool
break;
case GOSSIP_OPTION_TRAINER:
if (getClass() != creature->GetCreatureTemplate()->trainer_class && creature->GetCreatureTemplate()->trainer_type == TRAINER_TYPE_CLASS)
- TC_LOG_ERROR("sql.sql", "GOSSIP_OPTION_TRAINER:: Player %s (GUID: %u) request wrong gossip menu: %u with wrong class: %u at Creature: %s (Entry: %u, Trainer Class: %u)",
+ TC_LOG_ERROR("sql.sql", "GOSSIP_OPTION_TRAINER:: Player %s (GUID: %u) requested wrong gossip menu: %u with wrong class: %u at Creature: %s (Entry: %u, Trainer Class: %u)",
GetName().c_str(), GetGUID().GetCounter(), menu->GetGossipMenu().GetMenuId(), getClass(), creature->GetName().c_str(), creature->GetEntry(), creature->GetCreatureTemplate()->trainer_class);
// no break;
case GOSSIP_OPTION_GOSSIP:
@@ -14017,7 +14028,7 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId /*= 0*/, bool
canTalk = false;
break;
default:
- TC_LOG_ERROR("sql.sql", "Creature entry %u has unknown gossip option %u for menu %u", creature->GetEntry(), itr->second.OptionType, itr->second.MenuId);
+ TC_LOG_ERROR("sql.sql", "Creature entry %u has unknown gossip option %u for menu %u.", creature->GetEntry(), itr->second.OptionType, itr->second.MenuId);
canTalk = false;
break;
}
@@ -14058,14 +14069,14 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId /*= 0*/, bool
if (!optionBroadcastText)
{
/// Find localizations from database.
- if (GossipMenuItemsLocale const* gossipMenuLocale = sObjectMgr->GetGossipMenuItemsLocale(MAKE_PAIR32(menuId, menuId)))
+ if (GossipMenuItemsLocale const* gossipMenuLocale = sObjectMgr->GetGossipMenuItemsLocale(MAKE_PAIR32(menuId, itr->second.OptionIndex)))
ObjectMgr::GetLocaleString(gossipMenuLocale->OptionText, locale, strOptionText);
}
if (!boxBroadcastText)
{
/// Find localizations from database.
- if (GossipMenuItemsLocale const* gossipMenuLocale = sObjectMgr->GetGossipMenuItemsLocale(MAKE_PAIR32(menuId, menuId)))
+ if (GossipMenuItemsLocale const* gossipMenuLocale = sObjectMgr->GetGossipMenuItemsLocale(MAKE_PAIR32(menuId, itr->second.OptionIndex)))
ObjectMgr::GetLocaleString(gossipMenuLocale->BoxText, locale, strBoxText);
}
}
@@ -14130,7 +14141,8 @@ void Player::OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 men
{
if (gossipOptionId > GOSSIP_OPTION_QUESTGIVER)
{
- TC_LOG_ERROR("entities.player", "Player guid %u request invalid gossip option for GameObject entry %u", GetGUID().GetCounter(), source->GetEntry());
+ TC_LOG_ERROR("entities.player", "Player '%s' (%s) requests invalid gossip option for GameObject (Entry: %u)",
+ GetName().c_str(), GetGUID().ToString().c_str(), source->GetEntry());
return;
}
}
@@ -14142,7 +14154,7 @@ void Player::OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 men
int32 cost = int32(item->BoxMoney);
if (!HasEnoughMoney(cost))
{
- SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0);
+ SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, nullptr, 0, 0);
PlayerTalkClass->SendCloseGossip();
return;
}
@@ -14167,7 +14179,7 @@ void Player::OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 men
break;
case GOSSIP_OPTION_SPIRITHEALER:
if (isDead())
- source->ToCreature()->CastSpell(source->ToCreature(), 17251, true, NULL, NULL, GetGUID());
+ source->ToCreature()->CastSpell(source->ToCreature(), 17251, true, nullptr, nullptr, GetGUID());
break;
case GOSSIP_OPTION_QUESTGIVER:
PrepareQuestMenu(guid);
@@ -14188,8 +14200,8 @@ void Player::OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 men
{
// Cast spells that teach dual spec
// Both are also ImplicitTarget self and must be cast by player
- CastSpell(this, 63680, true, NULL, NULL, GetGUID());
- CastSpell(this, 63624, true, NULL, NULL, GetGUID());
+ CastSpell(this, 63680, true, nullptr, nullptr, GetGUID());
+ CastSpell(this, 63624, true, nullptr, nullptr, GetGUID());
// Should show another Gossip text with "Congratulations..."
PlayerTalkClass->SendCloseGossip();
@@ -14234,7 +14246,8 @@ void Player::OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 men
if (bgTypeId == BATTLEGROUND_TYPE_NONE)
{
- TC_LOG_ERROR("entities.player", "a user (guid %u) requested battlegroundlist from a npc who is no battlemaster", GetGUID().GetCounter());
+ TC_LOG_ERROR("entities.player", "Player '%s' (%s) requested battlegroundlist from an invalid creature (%s)",
+ GetName().c_str(), GetGUID().ToString().c_str(), source->GetGUID().ToString().c_str());
return;
}
@@ -14442,7 +14455,7 @@ bool Player::IsActiveQuest(uint32 quest_id) const
return m_QuestStatus.find(quest_id) != m_QuestStatus.end();
}
-Quest const* Player::GetNextQuest(ObjectGuid guid, Quest const* quest)
+Quest const* Player::GetNextQuest(ObjectGuid guid, Quest const* quest) const
{
QuestRelationBounds objectQR;
@@ -14459,7 +14472,7 @@ Quest const* Player::GetNextQuest(ObjectGuid guid, Quest const* quest)
if (pGameObject)
objectQR = sObjectMgr->GetGOQuestRelationBounds(pGameObject->GetEntry());
else
- return NULL;
+ return nullptr;
}
uint32 nextQuestID = quest->GetNextQuestInChain();
@@ -14469,7 +14482,7 @@ Quest const* Player::GetNextQuest(ObjectGuid guid, Quest const* quest)
return sObjectMgr->GetQuestTemplate(nextQuestID);
}
- return NULL;
+ return nullptr;
}
bool Player::CanSeeStartQuest(Quest const* quest)
@@ -14499,7 +14512,7 @@ bool Player::CanTakeQuest(Quest const* quest, bool msg)
&& SatisfyQuestConditions(quest, msg);
}
-bool Player::CanAddQuest(Quest const* quest, bool msg)
+bool Player::CanAddQuest(Quest const* quest, bool msg) const
{
if (!SatisfyQuestLog(msg))
return false;
@@ -14514,9 +14527,9 @@ bool Player::CanAddQuest(Quest const* quest, bool msg)
// player already have max number (in most case 1) source item, no additional item needed and quest can be added.
if (msg2 == EQUIP_ERR_CANT_CARRY_MORE_OF_THIS)
return true;
- else if (msg2 != EQUIP_ERR_OK)
+ if (msg2 != EQUIP_ERR_OK)
{
- SendEquipError(msg2, NULL, NULL, srcitem);
+ SendEquipError(msg2, nullptr, nullptr, srcitem);
return false;
}
}
@@ -14635,7 +14648,7 @@ bool Player::CanRewardQuest(Quest const* quest, bool msg)
GetItemCount(quest->RequiredItemId[i]) < quest->RequiredItemCount[i])
{
if (msg)
- SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL, quest->RequiredItemId[i]);
+ SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr, quest->RequiredItemId[i]);
return false;
}
}
@@ -14667,7 +14680,7 @@ void Player::AddQuestAndCheckCompletion(Quest const* quest, Object* questGiver)
case TYPEID_ITEM:
case TYPEID_CONTAINER:
{
- Item* item = (Item*)questGiver;
+ Item* item = static_cast<Item*>(questGiver);
sScriptMgr->OnQuestAccept(this, item, quest);
// destroy not required for quest finish quest starting item
@@ -14709,7 +14722,7 @@ bool Player::CanRewardQuest(Quest const* quest, uint32 reward, bool msg)
InventoryResult res = CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, quest->RewardChoiceItemId[reward], quest->RewardChoiceItemCount[reward]);
if (res != EQUIP_ERR_OK)
{
- SendEquipError(res, NULL, NULL, quest->RewardChoiceItemId[reward]);
+ SendEquipError(res, nullptr, nullptr, quest->RewardChoiceItemId[reward]);
return false;
}
}
@@ -14724,7 +14737,7 @@ bool Player::CanRewardQuest(Quest const* quest, uint32 reward, bool msg)
InventoryResult res = CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, quest->RewardItemId[i], quest->RewardItemIdCount[i]);
if (res != EQUIP_ERR_OK)
{
- SendEquipError(res, NULL, NULL, quest->RewardItemId[i]);
+ SendEquipError(res, nullptr, nullptr, quest->RewardItemId[i]);
return false;
}
}
@@ -14787,7 +14800,7 @@ void Player::AddQuest(Quest const* quest, Object* questGiver)
AddTimedQuest(quest_id);
questStatusData.Timer = timeAllowed * IN_MILLISECONDS;
- qtime = static_cast<uint32>(time(NULL)) + timeAllowed;
+ qtime = static_cast<uint32>(time(nullptr)) + timeAllowed;
}
else
questStatusData.Timer = 0;
@@ -14841,7 +14854,7 @@ void Player::CompleteQuest(uint32 quest_id)
if (sWorld->getBoolConfig(CONFIG_QUEST_ENABLE_QUEST_TRACKER)) // check if Quest Tracker is enabled
{
- // prepare Quest Tracker datas
+ // prepare Quest Tracker data
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_QUEST_TRACK_COMPLETE_TIME);
stmt->setUInt32(0, quest_id);
stmt->setUInt32(1, GetGUID().GetCounter());
@@ -14935,7 +14948,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
int32 moneyRew = 0;
if (getLevel() < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
- GiveXP(XP, NULL);
+ GiveXP(XP, nullptr);
else
moneyRew = int32(quest->GetRewMoneyMaxLevel() * sWorld->getRate(RATE_DROP_MONEY));
@@ -14953,7 +14966,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
// honor reward
if (uint32 honor = quest->CalculateHonorGain(getLevel()))
- RewardHonor(NULL, 0, honor);
+ RewardHonor(nullptr, 0, honor);
// title reward
if (quest->GetCharTitleId())
@@ -15003,7 +15016,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
// StoreNewItem, mail reward, etc. save data directly to the database
// to prevent exploitable data desynchronisation we save the quest status to the database too
// (to prevent rewarding this quest another time while rewards were already given out)
- SQLTransaction trans = SQLTransaction(NULL);
+ SQLTransaction trans = SQLTransaction(nullptr);
_SaveQuestStatus(trans);
if (announce)
@@ -15107,7 +15120,8 @@ bool Player::SatisfyQuestSkill(Quest const* qInfo, bool msg) const
if (msg)
{
SendCanTakeQuestResponse(INVALIDREASON_DONT_HAVE_REQ);
- TC_LOG_DEBUG("misc", "SatisfyQuestSkill: Sent INVALIDREASON_DONT_HAVE_REQ (questId: %u) because player does not have required skill value.", qInfo->GetQuestId());
+ TC_LOG_DEBUG("misc", "Player::SatisfyQuestSkill: Sent INVALIDREASON_DONT_HAVE_REQ (QuestID: %u) because player '%s' (%s) doesn't have the required skill value.",
+ qInfo->GetQuestId(), GetName().c_str(), GetGUID().ToString().c_str());
}
return false;
@@ -15116,30 +15130,33 @@ bool Player::SatisfyQuestSkill(Quest const* qInfo, bool msg) const
return true;
}
-bool Player::SatisfyQuestLevel(Quest const* qInfo, bool msg)
+bool Player::SatisfyQuestLevel(Quest const* qInfo, bool msg) const
{
if (getLevel() < qInfo->GetMinLevel())
{
if (msg)
{
SendCanTakeQuestResponse(INVALIDREASON_QUEST_FAILED_LOW_LEVEL);
- TC_LOG_DEBUG("misc", "SatisfyQuestLevel: Sent INVALIDREASON_QUEST_FAILED_LOW_LEVEL (questId: %u) because player does not have required (min) level.", qInfo->GetQuestId());
+ TC_LOG_DEBUG("misc", "Player::SatisfyQuestLevel: Sent INVALIDREASON_QUEST_FAILED_LOW_LEVEL (QuestID: %u) because player '%s' (%s) doesn't have the required (min) level.",
+ qInfo->GetQuestId(), GetName().c_str(), GetGUID().ToString().c_str());
}
return false;
}
- else if (qInfo->GetMaxLevel() > 0 && getLevel() > qInfo->GetMaxLevel())
+
+ if (qInfo->GetMaxLevel() > 0 && getLevel() > qInfo->GetMaxLevel())
{
if (msg)
{
SendCanTakeQuestResponse(INVALIDREASON_DONT_HAVE_REQ); // There doesn't seem to be a specific response for too high player level
- TC_LOG_DEBUG("misc", "SatisfyQuestLevel: Sent INVALIDREASON_QUEST_FAILED_LOW_LEVEL (questId: %u) because player does not have required (max) level.", qInfo->GetQuestId());
+ TC_LOG_DEBUG("misc", "Player::SatisfyQuestLevel: Sent INVALIDREASON_DONT_HAVE_REQ (QuestID: %u) because player '%s' (%s) doesn't have the required (max) level.",
+ qInfo->GetQuestId(), GetName().c_str(), GetGUID().ToString().c_str());
}
return false;
}
return true;
}
-bool Player::SatisfyQuestLog(bool msg)
+bool Player::SatisfyQuestLog(bool msg) const
{
// exist free slot
if (FindQuestSlot(0) < MAX_QUEST_LOG_SIZE)
@@ -15149,7 +15166,6 @@ bool Player::SatisfyQuestLog(bool msg)
{
WorldPacket data(SMSG_QUESTLOG_FULL, 0);
GetSession()->SendPacket(&data);
- TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTLOG_FULL");
}
return false;
}
@@ -15193,7 +15209,8 @@ bool Player::SatisfyQuestPreviousQuest(Quest const* qInfo, bool msg)
if (msg)
{
SendCanTakeQuestResponse(INVALIDREASON_DONT_HAVE_REQ);
- TC_LOG_DEBUG("misc", "SatisfyQuestPreviousQuest: Sent INVALIDREASON_DONT_HAVE_REQ (questId: %u) because player does not have required quest (1).", qInfo->GetQuestId());
+ TC_LOG_DEBUG("misc", "Player::SatisfyQuestPreviousQuest: Sent INVALIDREASON_DONT_HAVE_REQ (QuestID: %u) because player '%s' (%s) doesn't have the required quest (1).",
+ qInfo->GetQuestId(), GetName().c_str(), GetGUID().ToString().c_str());
}
return false;
}
@@ -15226,7 +15243,8 @@ bool Player::SatisfyQuestPreviousQuest(Quest const* qInfo, bool msg)
if (msg)
{
SendCanTakeQuestResponse(INVALIDREASON_DONT_HAVE_REQ);
- TC_LOG_DEBUG("misc", "SatisfyQuestPreviousQuest: Sent INVALIDREASON_DONT_HAVE_REQ (questId: %u) because player does not have required quest (2).", qInfo->GetQuestId());
+ TC_LOG_DEBUG("misc", "Player::SatisfyQuestPreviousQuest: Sent INVALIDREASON_DONT_HAVE_REQ (QuestID: %u) because player '%s' (%s) doesn't have the required quest (2).",
+ qInfo->GetQuestId(), GetName().c_str(), GetGUID().ToString().c_str());
}
return false;
@@ -15242,7 +15260,8 @@ bool Player::SatisfyQuestPreviousQuest(Quest const* qInfo, bool msg)
if (msg)
{
SendCanTakeQuestResponse(INVALIDREASON_DONT_HAVE_REQ);
- TC_LOG_DEBUG("misc", "SatisfyQuestPreviousQuest: Sent INVALIDREASON_DONT_HAVE_REQ (questId: %u) because player does not have required quest (3).", qInfo->GetQuestId());
+ TC_LOG_DEBUG("misc", "Player::SatisfyQuestPreviousQuest: Sent INVALIDREASON_DONT_HAVE_REQ (QuestID: %u) because player '%s' (%s) doesn't have required quest (3).",
+ qInfo->GetQuestId(), GetName().c_str(), GetGUID().ToString().c_str());
}
return false;
@@ -15260,7 +15279,8 @@ bool Player::SatisfyQuestClass(Quest const* qInfo, bool msg) const
if (msg)
{
SendCanTakeQuestResponse(INVALIDREASON_DONT_HAVE_REQ);
- TC_LOG_DEBUG("misc", "SatisfyQuestClass: Sent INVALIDREASON_DONT_HAVE_REQ (questId: %u) because player does not have required class.", qInfo->GetQuestId());
+ TC_LOG_DEBUG("misc", "Player::SatisfyQuestClass: Sent INVALIDREASON_DONT_HAVE_REQ (QuestID: %u) because player '%s' (%s) doesn't have required class.",
+ qInfo->GetQuestId(), GetName().c_str(), GetGUID().ToString().c_str());
}
return false;
@@ -15269,7 +15289,7 @@ bool Player::SatisfyQuestClass(Quest const* qInfo, bool msg) const
return true;
}
-bool Player::SatisfyQuestRace(Quest const* qInfo, bool msg)
+bool Player::SatisfyQuestRace(Quest const* qInfo, bool msg) const
{
uint32 reqraces = qInfo->GetAllowableRaces();
if (reqraces == 0)
@@ -15279,7 +15299,8 @@ bool Player::SatisfyQuestRace(Quest const* qInfo, bool msg)
if (msg)
{
SendCanTakeQuestResponse(INVALIDREASON_QUEST_FAILED_WRONG_RACE);
- TC_LOG_DEBUG("misc", "SatisfyQuestRace: Sent INVALIDREASON_QUEST_FAILED_WRONG_RACE (questId: %u) because player does not have required race.", qInfo->GetQuestId());
+ TC_LOG_DEBUG("misc", "Player::SatisfyQuestRace: Sent INVALIDREASON_QUEST_FAILED_WRONG_RACE (QuestID: %u) because player '%s' (%s) doesn't have required race.",
+ qInfo->GetQuestId(), GetName().c_str(), GetGUID().ToString().c_str());
}
return false;
@@ -15295,7 +15316,8 @@ bool Player::SatisfyQuestReputation(Quest const* qInfo, bool msg)
if (msg)
{
SendCanTakeQuestResponse(INVALIDREASON_DONT_HAVE_REQ);
- TC_LOG_DEBUG("misc", "SatisfyQuestReputation: Sent INVALIDREASON_DONT_HAVE_REQ (questId: %u) because player does not have required reputation (min).", qInfo->GetQuestId());
+ TC_LOG_DEBUG("misc", "Player::SatisfyQuestReputation: Sent INVALIDREASON_DONT_HAVE_REQ (QuestID: %u) because player '%s' (%s) doesn't required reputation (min).",
+ qInfo->GetQuestId(), GetName().c_str(), GetGUID().ToString().c_str());
}
return false;
}
@@ -15306,7 +15328,8 @@ bool Player::SatisfyQuestReputation(Quest const* qInfo, bool msg)
if (msg)
{
SendCanTakeQuestResponse(INVALIDREASON_DONT_HAVE_REQ);
- TC_LOG_DEBUG("misc", "SatisfyQuestReputation: Sent INVALIDREASON_DONT_HAVE_REQ (questId: %u) because player does not have required reputation (max).", qInfo->GetQuestId());
+ TC_LOG_DEBUG("misc", "SatisfyQuestReputation: Sent INVALIDREASON_DONT_HAVE_REQ (QuestID: %u) because player '%s' (%s) doesn't required reputation (max).",
+ qInfo->GetQuestId(), GetName().c_str(), GetGUID().ToString().c_str());
}
return false;
}
@@ -15319,7 +15342,7 @@ bool Player::SatisfyQuestReputation(Quest const* qInfo, bool msg)
if (msg)
{
SendCanTakeQuestResponse(INVALIDREASON_DONT_HAVE_REQ);
- TC_LOG_DEBUG("misc", "SatisfyQuestReputation: Sent INVALIDREASON_DONT_HAVE_REQ (questId: %u) because player does not have required reputation (ReputationObjective2).", qInfo->GetQuestId());
+ TC_LOG_DEBUG("misc", "SatisfyQuestReputation: Sent INVALIDREASON_DONT_HAVE_REQ (questId: %u) because player does not have the required reputation (ReputationObjective2).", qInfo->GetQuestId());
}
return false;
}
@@ -15327,14 +15350,15 @@ bool Player::SatisfyQuestReputation(Quest const* qInfo, bool msg)
return true;
}
-bool Player::SatisfyQuestStatus(Quest const* qInfo, bool msg)
+bool Player::SatisfyQuestStatus(Quest const* qInfo, bool msg) const
{
if (GetQuestStatus(qInfo->GetQuestId()) != QUEST_STATUS_NONE)
{
if (msg)
{
SendCanTakeQuestResponse(INVALIDREASON_QUEST_ALREADY_ON);
- TC_LOG_DEBUG("misc", "SatisfyQuestStatus: Sent INVALIDREASON_QUEST_ALREADY_ON (questId: %u) because player quest status is not NONE.", qInfo->GetQuestId());
+ TC_LOG_DEBUG("misc", "Player::SatisfyQuestStatus: Sent INVALIDREASON_QUEST_ALREADY_ON (QuestID: %u) because player '%s' (%s) quest status is not NONE.",
+ qInfo->GetQuestId(), GetName().c_str(), GetGUID().ToString().c_str());
}
return false;
}
@@ -15348,7 +15372,8 @@ bool Player::SatisfyQuestConditions(Quest const* qInfo, bool msg)
if (msg)
{
SendCanTakeQuestResponse(INVALIDREASON_DONT_HAVE_REQ);
- TC_LOG_DEBUG("misc", "SatisfyQuestConditions: Sent INVALIDREASON_DONT_HAVE_REQ (questId: %u) because player does not meet conditions.", qInfo->GetQuestId());
+ TC_LOG_DEBUG("misc", "Player::SatisfyQuestConditions: Sent INVALIDREASON_DONT_HAVE_REQ (QuestID: %u) because player '%s' (%s) doesn't meet conditions.",
+ qInfo->GetQuestId(), GetName().c_str(), GetGUID().ToString().c_str());
}
TC_LOG_DEBUG("condition", "Player::SatisfyQuestConditions: conditions not met for quest %u", qInfo->GetQuestId());
return false;
@@ -15356,14 +15381,15 @@ bool Player::SatisfyQuestConditions(Quest const* qInfo, bool msg)
return true;
}
-bool Player::SatisfyQuestTimed(Quest const* qInfo, bool msg)
+bool Player::SatisfyQuestTimed(Quest const* qInfo, bool msg) const
{
if (!m_timedquests.empty() && qInfo->HasSpecialFlag(QUEST_SPECIAL_FLAGS_TIMED))
{
if (msg)
{
SendCanTakeQuestResponse(INVALIDREASON_QUEST_ONLY_ONE_TIMED);
- TC_LOG_DEBUG("misc", "SatisfyQuestTimed: Sent INVALIDREASON_QUEST_ONLY_ONE_TIMED (questId: %u) because player is already on a timed quest.", qInfo->GetQuestId());
+ TC_LOG_DEBUG("misc", "Player::SatisfyQuestTimed: Sent INVALIDREASON_QUEST_ONLY_ONE_TIMED (QuestID: %u) because player '%s' (%s) is already on a timed quest.",
+ qInfo->GetQuestId(), GetName().c_str(), GetGUID().ToString().c_str());
}
return false;
}
@@ -15394,7 +15420,8 @@ bool Player::SatisfyQuestExclusiveGroup(Quest const* qInfo, bool msg)
if (msg)
{
SendCanTakeQuestResponse(INVALIDREASON_DONT_HAVE_REQ);
- TC_LOG_DEBUG("misc", "SatisfyQuestExclusiveGroup: Sent INVALIDREASON_DONT_HAVE_REQ (questId: %u) because player already did daily quests in exclusive group.", qInfo->GetQuestId());
+ TC_LOG_DEBUG("misc", "Player::SatisfyQuestExclusiveGroup: Sent INVALIDREASON_DONT_HAVE_REQ (QuestID: %u) because player '%s' (%s) already did daily quests in exclusive group.",
+ qInfo->GetQuestId(), GetName().c_str(), GetGUID().ToString().c_str());
}
return false;
@@ -15406,7 +15433,8 @@ bool Player::SatisfyQuestExclusiveGroup(Quest const* qInfo, bool msg)
if (msg)
{
SendCanTakeQuestResponse(INVALIDREASON_DONT_HAVE_REQ);
- TC_LOG_DEBUG("misc", "SatisfyQuestExclusiveGroup: Sent INVALIDREASON_DONT_HAVE_REQ (questId: %u) because player already did quest in exclusive group.", qInfo->GetQuestId());
+ TC_LOG_DEBUG("misc", "Player::SatisfyQuestExclusiveGroup: Sent INVALIDREASON_DONT_HAVE_REQ (QuestID: %u) because player '%s' (%s) already did quest in exclusive group.",
+ qInfo->GetQuestId(), GetName().c_str(), GetGUID().ToString().c_str());
}
return false;
}
@@ -15414,7 +15442,7 @@ bool Player::SatisfyQuestExclusiveGroup(Quest const* qInfo, bool msg)
return true;
}
-bool Player::SatisfyQuestNextChain(Quest const* qInfo, bool msg)
+bool Player::SatisfyQuestNextChain(Quest const* qInfo, bool msg) const
{
uint32 nextQuest = qInfo->GetNextQuestInChain();
if (!nextQuest)
@@ -15426,7 +15454,8 @@ bool Player::SatisfyQuestNextChain(Quest const* qInfo, bool msg)
if (msg)
{
SendCanTakeQuestResponse(INVALIDREASON_DONT_HAVE_REQ);
- TC_LOG_DEBUG("misc", "SatisfyQuestNextChain: Sent INVALIDREASON_DONT_HAVE_REQ (questId: %u) because player already did or started next quest in chain.", qInfo->GetQuestId());
+ TC_LOG_DEBUG("misc", "Player::SatisfyQuestNextChain: Sent INVALIDREASON_DONT_HAVE_REQ (QuestID: %u) because player '%s' (%s) already did or started next quest in chain.",
+ qInfo->GetQuestId(), GetName().c_str(), GetGUID().ToString().c_str());
}
return false;
}
@@ -15453,7 +15482,8 @@ bool Player::SatisfyQuestPrevChain(Quest const* qInfo, bool msg)
if (msg)
{
SendCanTakeQuestResponse(INVALIDREASON_DONT_HAVE_REQ);
- TC_LOG_DEBUG("misc", "SatisfyQuestNextChain: Sent INVALIDREASON_DONT_HAVE_REQ (questId: %u) because player already did or started next quest in chain.", qInfo->GetQuestId());
+ TC_LOG_DEBUG("misc", "Player::SatisfyQuestNextChain: Sent INVALIDREASON_DONT_HAVE_REQ (QuestID: %u) because player '%s' (%s) already did or started next quest in chain.",
+ qInfo->GetQuestId(), GetName().c_str(), GetGUID().ToString().c_str());
}
return false;
}
@@ -15468,14 +15498,14 @@ bool Player::SatisfyQuestPrevChain(Quest const* qInfo, bool msg)
return true;
}
-bool Player::SatisfyQuestDay(Quest const* qInfo, bool msg)
+bool Player::SatisfyQuestDay(Quest const* qInfo, bool msg) const
{
if (!qInfo->IsDaily() && !qInfo->IsDFQuest())
return true;
if (qInfo->IsDFQuest())
{
- if (!m_DFQuests.empty())
+ if (m_DFQuests.find(qInfo->GetQuestId()) != m_DFQuests.end())
return false;
return true;
@@ -15556,8 +15586,8 @@ bool Player::GiveQuestSourceItem(Quest const* quest)
// player already have max amount required item, just report success
else if (msg == EQUIP_ERR_CANT_CARRY_MORE_OF_THIS)
return true;
- else
- SendEquipError(msg, NULL, NULL, srcitem);
+
+ SendEquipError(msg, nullptr, nullptr, srcitem);
return false;
}
@@ -15586,7 +15616,7 @@ bool Player::TakeQuestSourceItem(uint32 questId, bool msg)
if (res != EQUIP_ERR_OK)
{
if (msg)
- SendEquipError(res, NULL, NULL, srcItemId);
+ SendEquipError(res, nullptr, nullptr, srcItemId);
return false;
}
@@ -15832,15 +15862,17 @@ QuestGiverStatus Player::GetQuestDialogStatus(Object* questgiver)
}
// not used in Trinity, but used in scripting code
-uint16 Player::GetReqKillOrCastCurrentCount(uint32 quest_id, int32 entry)
+uint16 Player::GetReqKillOrCastCurrentCount(uint32 quest_id, int32 entry) const
{
Quest const* qInfo = sObjectMgr->GetQuestTemplate(quest_id);
if (!qInfo)
return 0;
- for (uint8 j = 0; j < QUEST_OBJECTIVES_COUNT; ++j)
- if (qInfo->RequiredNpcOrGo[j] == entry)
- return m_QuestStatus[quest_id].CreatureOrGOCount[j];
+ auto itr = m_QuestStatus.find(quest_id);
+ if (itr != m_QuestStatus.end())
+ for (uint8 j = 0; j < QUEST_OBJECTIVES_COUNT; ++j)
+ if (qInfo->RequiredNpcOrGo[j] == entry)
+ return itr->second.CreatureOrGOCount[j];
return 0;
}
@@ -15963,7 +15995,7 @@ void Player::GroupEventHappens(uint32 questId, WorldObject const* pEventObject)
{
if (Group* group = GetGroup())
{
- for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
+ for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
{
Player* player = itr->GetSource();
@@ -16073,7 +16105,7 @@ void Player::KilledMonsterCredit(uint32 entry, ObjectGuid guid /*= ObjectGuid::E
{
uint16 addkillcount = 1;
uint32 real_entry = entry;
- Creature* killed = NULL;
+ Creature* killed = nullptr;
if (guid)
{
killed = GetMap()->GetCreature(guid);
@@ -16426,21 +16458,19 @@ bool Player::HasQuestForItem(uint32 itemid) const
return false;
}
-void Player::SendQuestComplete(uint32 quest_id)
+void Player::SendQuestComplete(uint32 quest_id) const
{
if (quest_id)
{
WorldPacket data(SMSG_QUESTUPDATE_COMPLETE, 4);
data << uint32(quest_id);
GetSession()->SendPacket(&data);
- TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTUPDATE_COMPLETE quest = %u", quest_id);
}
}
-void Player::SendQuestReward(Quest const* quest, uint32 XP)
+void Player::SendQuestReward(Quest const* quest, uint32 XP) const
{
uint32 questid = quest->GetQuestId();
- TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_QUEST_COMPLETE quest = %u", questid);
sGameEventMgr->HandleQuestComplete(questid);
WorldPacket data(SMSG_QUESTGIVER_QUEST_COMPLETE, (4+4+4+4+4));
data << uint32(questid);
@@ -16462,7 +16492,7 @@ void Player::SendQuestReward(Quest const* quest, uint32 XP)
GetSession()->SendPacket(&data);
}
-void Player::SendQuestFailed(uint32 questId, InventoryResult reason)
+void Player::SendQuestFailed(uint32 questId, InventoryResult reason) const
{
if (questId)
{
@@ -16470,11 +16500,10 @@ void Player::SendQuestFailed(uint32 questId, InventoryResult reason)
data << uint32(questId);
data << uint32(reason); // failed reason (valid reasons: 4, 16, 50, 17, 74, other values show default message)
GetSession()->SendPacket(&data);
- TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_QUEST_FAILED");
}
}
-void Player::SendQuestTimerFailed(uint32 quest_id)
+void Player::SendQuestTimerFailed(uint32 quest_id) const
{
if (quest_id)
{
@@ -16493,7 +16522,7 @@ void Player::SendCanTakeQuestResponse(QuestFailedReason msg) const
TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_QUEST_INVALID");
}
-void Player::SendQuestConfirmAccept(const Quest* quest, Player* pReceiver)
+void Player::SendQuestConfirmAccept(const Quest* quest, Player* pReceiver) const
{
if (pReceiver)
{
@@ -16514,7 +16543,7 @@ void Player::SendQuestConfirmAccept(const Quest* quest, Player* pReceiver)
}
}
-void Player::SendPushToPartyResponse(Player* player, uint8 msg)
+void Player::SendPushToPartyResponse(Player* player, uint8 msg) const
{
if (player)
{
@@ -16526,7 +16555,7 @@ void Player::SendPushToPartyResponse(Player* player, uint8 msg)
}
}
-void Player::SendQuestUpdateAddItem(Quest const* /*quest*/, uint32 /*item_idx*/, uint16 /*count*/)
+void Player::SendQuestUpdateAddItem(Quest const* /*quest*/, uint32 /*item_idx*/, uint16 /*count*/) const
{
WorldPacket data(SMSG_QUESTUPDATE_ADD_ITEM, 0);
TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTUPDATE_ADD_ITEM");
@@ -16563,7 +16592,6 @@ void Player::SendQuestUpdateAddPlayer(Quest const* quest, uint16 old_count, uint
ASSERT(old_count + add_count < 65536 && "player count store in 16 bits");
WorldPacket data(SMSG_QUESTUPDATE_ADD_PVP_KILL, (3*4));
- TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTUPDATE_ADD_PVP_KILL");
data << uint32(quest->GetQuestId());
data << uint32(old_count + add_count);
data << uint32(quest->GetPlayersSlain());
@@ -16771,22 +16799,22 @@ bool Player::IsLoading() const
bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
{
- //// 0 1 2 3 4 5 6 7 8 9 10 11
- //QueryResult* result = CharacterDatabase.PQuery("SELECT guid, account, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags, "
- // 12 13 14 15 16 17 18 19 20 21 22 23 24
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
+ //QueryResult* result = CharacterDatabase.PQuery("SELECT guid, account, name, race, class, gender, level, xp, money, skin, face, hairStyle, hairColor, facialStyle, bankSlots, restState, playerFlags, "
+ // 17 18 19 20 21 22 23 24 25 26 27 28 29
//"position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, "
- // 25 26 27 28 29 30 31 32 33 34 35 36 37 38
+ // 30 31 32 33 34 35 36 37 38 39 40 41 42 43
//"resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, instance_mode_mask, "
- // 39 40 41 42 43 44 45 46 47 48 49
+ // 44 45 46 47 48 49 50 51 52 53 54
//"arenaPoints, totalHonorPoints, todayHonorPoints, yesterdayHonorPoints, totalKills, todayKills, yesterdayKills, chosenTitle, knownCurrencies, watchedFaction, drunk, "
- // 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
+ // 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
//"health, power1, power2, power3, power4, power5, power6, power7, instance_id, talentGroupsCount, activeTalentGroup, exploredZones, equipmentCache, ammoId, knownTitles, actionBars, grantableLevels FROM characters WHERE guid = '%u'", guid);
PreparedQueryResult result = holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_FROM);
if (!result)
{
std::string name = "<unknown>";
sObjectMgr->GetPlayerNameByGUID(guid, name);
- TC_LOG_ERROR("entities.player", "Player %s %s not found in table `characters`, can't load. ", name.c_str(), guid.ToString().c_str());
+ TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player '%s' (%s) not found in table `characters`, can't load. ", name.c_str(), guid.ToString().c_str());
return false;
}
@@ -16798,13 +16826,13 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
// player should be able to load/delete character only with correct account!
if (dbAccountId != GetSession()->GetAccountId())
{
- TC_LOG_ERROR("entities.player", "Player %s loading from wrong account (is: %u, should be: %u)", guid.ToString().c_str(), GetSession()->GetAccountId(), dbAccountId);
+ TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) loading from wrong account (is: %u, should be: %u)", guid.ToString().c_str(), GetSession()->GetAccountId(), dbAccountId);
return false;
}
if (holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_BANNED))
{
- TC_LOG_ERROR("entities.player", "%s is banned, can't load.", guid.ToString().c_str());
+ TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) is banned, can't load.", guid.ToString().c_str());
return false;
}
@@ -16814,8 +16842,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
// check name limitations
if (ObjectMgr::CheckPlayerName(m_name, GetSession()->GetSessionDbcLocale()) != CHAR_NAME_SUCCESS ||
- (!GetSession()->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) &&
- sObjectMgr->IsReservedName(m_name)))
+ (!GetSession()->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(m_name)))
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
stmt->setUInt16(0, uint16(AT_LOGIN_RENAME));
@@ -16830,7 +16857,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
uint8 gender = fields[5].GetUInt8();
if (!IsValidGender(gender))
{
- TC_LOG_ERROR("entities.player", "Player %s has wrong gender (%u), can't be loaded.", guid.ToString().c_str(), gender);
+ TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) has wrong gender (%u), can't load.", guid.ToString().c_str(), gender);
return false;
}
@@ -16845,15 +16872,15 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(), getClass());
if (!info)
{
- TC_LOG_ERROR("entities.player", "Player %s has wrong race/class (%u/%u), can't be loaded.", guid.ToString().c_str(), getRace(), getClass());
+ TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) has wrong race/class (%u/%u), can't load.", guid.ToString().c_str(), getRace(), getClass());
return false;
}
SetUInt32Value(UNIT_FIELD_LEVEL, fields[6].GetUInt8());
SetUInt32Value(PLAYER_XP, fields[7].GetUInt32());
- _LoadIntoDataField(fields[61].GetCString(), PLAYER_EXPLORED_ZONES_1, PLAYER_EXPLORED_ZONES_SIZE);
- _LoadIntoDataField(fields[64].GetCString(), PLAYER__FIELD_KNOWN_TITLES, KNOWN_TITLES_SIZE*2);
+ _LoadIntoDataField(fields[66].GetString(), PLAYER_EXPLORED_ZONES_1, PLAYER_EXPLORED_ZONES_SIZE);
+ _LoadIntoDataField(fields[69].GetString(), PLAYER__FIELD_KNOWN_TITLES, KNOWN_TITLES_SIZE * 2);
SetObjectScale(1.0f);
SetFloatValue(UNIT_FIELD_HOVERHEIGHT, 1.0f);
@@ -16866,47 +16893,53 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
money = MAX_MONEY_AMOUNT;
SetMoney(money);
- SetUInt32Value(PLAYER_BYTES, fields[9].GetUInt32());
- SetUInt32Value(PLAYER_BYTES_2, fields[10].GetUInt32());
+ SetByteValue(PLAYER_BYTES, 0, fields[9].GetUInt8());
+ SetByteValue(PLAYER_BYTES, 1, fields[10].GetUInt8());
+ SetByteValue(PLAYER_BYTES, 2, fields[11].GetUInt8());
+ SetByteValue(PLAYER_BYTES, 3, fields[12].GetUInt8());
+ SetByteValue(PLAYER_BYTES_2, 0, fields[13].GetUInt8());
+ SetByteValue(PLAYER_BYTES_2, 2, fields[14].GetUInt8());
+ SetByteValue(PLAYER_BYTES_2, 3, fields[15].GetUInt8());
SetByteValue(PLAYER_BYTES_3, 0, fields[5].GetUInt8());
- SetByteValue(PLAYER_BYTES_3, 1, fields[49].GetUInt8());
+ SetByteValue(PLAYER_BYTES_3, 1, fields[54].GetUInt8());
if (!ValidateAppearance(
fields[3].GetUInt8(), // race
fields[4].GetUInt8(), // class
- gender, GetByteValue(PLAYER_BYTES, 2), // hair type
- GetByteValue(PLAYER_BYTES, 3), //hair color
- uint8(fields[9].GetUInt32() >> 8), // face
- GetByteValue(PLAYER_BYTES_2, 0), // facial hair
- GetByteValue(PLAYER_BYTES, 0))) // skin color
- {
- TC_LOG_ERROR("entities.player", "Player %s has wrong Appearance values (Hair/Skin/Color), can't be loaded.", guid.ToString().c_str());
+ gender,
+ GetByteValue(PLAYER_BYTES, 2),
+ GetByteValue(PLAYER_BYTES, 3),
+ GetByteValue(PLAYER_BYTES, 1),
+ GetByteValue(PLAYER_BYTES_2, 0),
+ GetByteValue(PLAYER_BYTES, 0)))
+ {
+ TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) has wrong Appearance values (Hair/Skin/Color), can't load.", guid.ToString().c_str());
return false;
}
- SetUInt32Value(PLAYER_FLAGS, fields[11].GetUInt32());
- SetInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, fields[48].GetUInt32());
+ SetUInt32Value(PLAYER_FLAGS, fields[16].GetUInt32());
+ SetInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, fields[53].GetUInt32());
- SetUInt64Value(PLAYER_FIELD_KNOWN_CURRENCIES, fields[47].GetUInt64());
+ SetUInt64Value(PLAYER_FIELD_KNOWN_CURRENCIES, fields[52].GetUInt64());
- SetUInt32Value(PLAYER_AMMO_ID, fields[63].GetUInt32());
+ SetUInt32Value(PLAYER_AMMO_ID, fields[68].GetUInt32());
// set which actionbars the client has active - DO NOT REMOVE EVER AGAIN (can be changed though, if it does change fieldwise)
- SetByteValue(PLAYER_FIELD_BYTES, 2, fields[65].GetUInt8());
+ SetByteValue(PLAYER_FIELD_BYTES, 2, fields[70].GetUInt8());
InitDisplayIds();
- // cleanup inventory related item value fields (its will be filled correctly in _LoadInventory)
+ // cleanup inventory related item value fields (it will be filled correctly in _LoadInventory)
for (uint8 slot = EQUIPMENT_SLOT_START; slot < EQUIPMENT_SLOT_END; ++slot)
{
SetGuidValue(PLAYER_FIELD_INV_SLOT_HEAD + (slot * 2), ObjectGuid::Empty);
- SetVisibleItemSlot(slot, NULL);
+ SetVisibleItemSlot(slot, nullptr);
delete m_items[slot];
- m_items[slot] = NULL;
+ m_items[slot] = nullptr;
}
- TC_LOG_DEBUG("entities.player.loading", "Load Basic value of player %s is: ", m_name.c_str());
+ TC_LOG_DEBUG("entities.player.loading", "Player::LoadFromDB: Load Basic value of player '%s' is: ", m_name.c_str());
outDebugValues();
//Need to call it to initialize m_team (m_team can be calculated from race)
@@ -16920,21 +16953,21 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
InitPrimaryProfessions(); // to max set before any spell loaded
// init saved position, and fix it later if problematic
- ObjectGuid::LowType transLowGUID = fields[30].GetUInt32();
- Relocate(fields[12].GetFloat(), fields[13].GetFloat(), fields[14].GetFloat(), fields[16].GetFloat());
- uint32 mapId = fields[15].GetUInt16();
- uint32 instanceId = fields[58].GetUInt32();
+ ObjectGuid::LowType transLowGUID = fields[35].GetUInt32();
+ Relocate(fields[17].GetFloat(), fields[18].GetFloat(), fields[19].GetFloat(), fields[21].GetFloat());
+ uint32 mapId = fields[20].GetUInt16();
+ uint32 instanceId = fields[63].GetUInt32();
- uint32 dungeonDiff = fields[38].GetUInt8() & 0x0F;
+ uint32 dungeonDiff = fields[43].GetUInt8() & 0x0F;
if (dungeonDiff >= MAX_DUNGEON_DIFFICULTY)
dungeonDiff = DUNGEON_DIFFICULTY_NORMAL;
- uint32 raidDiff = (fields[38].GetUInt8() >> 4) & 0x0F;
+ uint32 raidDiff = (fields[43].GetUInt8() >> 4) & 0x0F;
if (raidDiff >= MAX_RAID_DIFFICULTY)
raidDiff = RAID_DIFFICULTY_10MAN_NORMAL;
SetDungeonDifficulty(Difficulty(dungeonDiff)); // may be changed in _LoadGroup
SetRaidDifficulty(Difficulty(raidDiff)); // may be changed in _LoadGroup
- std::string taxi_nodes = fields[37].GetString();
+ std::string taxi_nodes = fields[42].GetString();
#define RelocateToHomebind(){ mapId = m_homebindMapId; instanceId = 0; Relocate(m_homebindX, m_homebindY, m_homebindZ); }
@@ -16942,7 +16975,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
_LoadArenaTeamInfo(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ARENA_INFO));
- SetArenaPoints(fields[39].GetUInt32());
+ SetArenaPoints(fields[44].GetUInt32());
// check arena teams integrity
for (uint32 arena_slot = 0; arena_slot < MAX_ARENA_SLOT; ++arena_slot)
@@ -16960,12 +16993,12 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
SetArenaTeamInfoField(arena_slot, ArenaTeamInfoType(j), 0);
}
- SetHonorPoints(fields[40].GetUInt32());
- SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, fields[41].GetUInt32());
- SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, fields[42].GetUInt32());
- SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, fields[43].GetUInt32());
- SetUInt16Value(PLAYER_FIELD_KILLS, 0, fields[44].GetUInt16());
- SetUInt16Value(PLAYER_FIELD_KILLS, 1, fields[45].GetUInt16());
+ SetHonorPoints(fields[45].GetUInt32());
+ SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, fields[46].GetUInt32());
+ SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, fields[47].GetUInt32());
+ SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, fields[48].GetUInt32());
+ SetUInt16Value(PLAYER_FIELD_KILLS, 0, fields[49].GetUInt16());
+ SetUInt16Value(PLAYER_FIELD_KILLS, 1, fields[50].GetUInt16());
_LoadBoundInstances(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_BOUND_INSTANCES));
_LoadInstanceTimeRestrictions(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_INSTANCE_LOCK_TIMES));
@@ -16975,14 +17008,14 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
MapEntry const* mapEntry = sMapStore.LookupEntry(mapId);
if (!mapEntry || !IsPositionValid())
{
- TC_LOG_ERROR("entities.player", "Player %s have invalid coordinates (MapId: %u X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.",
+ TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) has invalid coordinates (MapId: %u X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.",
guid.ToString().c_str(), mapId, GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation());
RelocateToHomebind();
}
// Player was saved in Arena or Bg
else if (mapEntry && mapEntry->IsBattlegroundOrArena())
{
- Battleground* currentBg = NULL;
+ Battleground* currentBg = nullptr;
if (m_bgData.bgInstanceID) //saved in Battleground
currentBg = sBattlegroundMgr->GetBattleground(m_bgData.bgInstanceID, BATTLEGROUND_TYPE_NONE);
@@ -17016,7 +17049,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
//if (mapId == MAPID_INVALID) -- code kept for reference
if (int16(mapId) == int16(-1)) // Battleground Entry Point not found (???)
{
- TC_LOG_ERROR("entities.player", "Player %s was in BG in database, but BG was not found, and entry point was invalid! Teleport to default race/class locations.",
+ TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) was in BG in database, but BG was not found and entry point was invalid! Teleport to default race/class locations.",
guid.ToString().c_str());
RelocateToHomebind();
}
@@ -17032,13 +17065,13 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
{
ObjectGuid transGUID(HighGuid::Mo_Transport, transLowGUID);
- Transport* transport = NULL;
+ Transport* transport = nullptr;
if (Transport* go = HashMapHolder<Transport>::Find(transGUID))
transport = go;
if (transport)
{
- float x = fields[26].GetFloat(), y = fields[27].GetFloat(), z = fields[28].GetFloat(), o = fields[29].GetFloat();
+ float x = fields[31].GetFloat(), y = fields[32].GetFloat(), z = fields[33].GetFloat(), o = fields[34].GetFloat();
m_movementInfo.transport.pos.Relocate(x, y, z, o);
transport->CalculatePassengerPosition(x, y, z, &o);
@@ -17048,7 +17081,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
std::fabs(m_movementInfo.transport.pos.GetPositionY()) > 250.0f ||
std::fabs(m_movementInfo.transport.pos.GetPositionZ()) > 250.0f)
{
- TC_LOG_ERROR("entities.player", "Player %s have invalid transport coordinates (X: %f Y: %f Z: %f O: %f). Teleport to bind location.",
+ TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) has invalid transport coordinates (X: %f Y: %f Z: %f O: %f). Teleport to bind location.",
guid.ToString().c_str(), x, y, z, o);
m_movementInfo.transport.Reset();
@@ -17065,7 +17098,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
}
else
{
- TC_LOG_ERROR("entities.player", "Player %s have problems with transport guid (%u). Teleport to bind location.",
+ TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) has problems with transport guid (%u). Teleport to bind location.",
guid.ToString().c_str(), transLowGUID);
RelocateToHomebind();
@@ -17085,18 +17118,18 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
else if (!m_taxi.LoadTaxiDestinationsFromString(taxi_nodes, GetTeam()))
{
// problems with taxi path loading
- TaxiNodesEntry const* nodeEntry = NULL;
+ TaxiNodesEntry const* nodeEntry = nullptr;
if (uint32 node_id = m_taxi.GetTaxiSource())
nodeEntry = sTaxiNodesStore.LookupEntry(node_id);
- if (!nodeEntry) // don't know taxi start node, to homebind
+ if (!nodeEntry) // don't know taxi start node, teleport to homebind
{
- TC_LOG_ERROR("entities.player", "Character %u have wrong data in taxi destination list, teleport to homebind.", GetGUID().GetCounter());
+ TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) has wrong data in taxi destination list, teleport to homebind.", GetGUID().ToString().c_str());
RelocateToHomebind();
}
- else // have start node, to it
+ else // has start node, teleport to it
{
- TC_LOG_ERROR("entities.player", "Character %u have too short taxi destination list, teleport to original node.", GetGUID().GetCounter());
+ TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) has too short taxi destination list, teleport to original node.", GetGUID().ToString().c_str());
mapId = nodeEntry->map_id;
Relocate(nodeEntry->x, nodeEntry->y, nodeEntry->z, 0.0f);
}
@@ -17125,7 +17158,8 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
{
if (GetSession()->Expansion() < mapEntry->Expansion())
{
- TC_LOG_DEBUG("entities.player.loading", "Player %s using client without required expansion tried login at non accessible map %u", GetName().c_str(), mapId);
+ TC_LOG_DEBUG("entities.player.loading", "Player::LoadFromDB: Player '%s' (%s) using client without required expansion tried login at non accessible map %u",
+ GetName().c_str(), GetGUID().ToString().c_str(), mapId);
RelocateToHomebind();
}
@@ -17139,7 +17173,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
// NOW player must have valid map
// load the player's map here if it's not already loaded
Map* map = sMapMgr->CreateMap(mapId, this, instanceId);
- AreaTrigger const* areaTrigger = NULL;
+ AreaTrigger const* areaTrigger = nullptr;
bool check = false;
if (!map)
@@ -17194,10 +17228,10 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
}
else
{
- TC_LOG_ERROR("entities.player", "Player %s %s Map: %u, X: %f, Y: %f, Z: %f, O: %f. Areatrigger not found.",
+ TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player '%s' (%s) Map: %u, X: %f, Y: %f, Z: %f, O: %f. Areatrigger not found.",
m_name.c_str(), guid.ToString().c_str(), mapId, GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation());
RelocateToHomebind();
- map = NULL;
+ map = nullptr;
}
}
@@ -17208,7 +17242,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
map = sMapMgr->CreateMap(mapId, this);
if (!map)
{
- TC_LOG_ERROR("entities.player", "Player %s %s Map: %u, X: %f, Y: %f, Z: %f, O: %f. Invalid default map coordinates or instance couldn't be created.",
+ TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player '%s' (%s) Map: %u, X: %f, Y: %f, Z: %f, O: %f. Invalid default map coordinates or instance couldn't be created.",
m_name.c_str(), guid.ToString().c_str(), mapId, GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation());
return false;
}
@@ -17223,12 +17257,12 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
// randomize first save time in range [CONFIG_INTERVAL_SAVE] around [CONFIG_INTERVAL_SAVE]
// this must help in case next save after mass player load after server startup
- m_nextSave = urand(m_nextSave/2, m_nextSave*3/2);
+ m_nextSave = urand(m_nextSave / 2, m_nextSave * 3 / 2);
SaveRecallPosition();
- time_t now = time(NULL);
- time_t logoutTime = time_t(fields[22].GetUInt32());
+ time_t now = time(nullptr);
+ time_t logoutTime = time_t(fields[27].GetUInt32());
// since last logout (in seconds)
uint32 time_diff = uint32(now - logoutTime); //uint64 is excessive for a time_diff in seconds.. uint32 allows for 136~ year difference.
@@ -17241,29 +17275,30 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
SetDrunkValue(newDrunkValue);
- m_cinematic = fields[18].GetUInt8();
- m_Played_time[PLAYED_TIME_TOTAL]= fields[19].GetUInt32();
- m_Played_time[PLAYED_TIME_LEVEL]= fields[20].GetUInt32();
+ m_cinematic = fields[23].GetUInt8();
+ m_Played_time[PLAYED_TIME_TOTAL] = fields[24].GetUInt32();
+ m_Played_time[PLAYED_TIME_LEVEL] = fields[25].GetUInt32();
- m_resetTalentsCost = fields[24].GetUInt32();
- m_resetTalentsTime = time_t(fields[25].GetUInt32());
+ m_resetTalentsCost = fields[29].GetUInt32();
+ m_resetTalentsTime = time_t(fields[30].GetUInt32());
- m_taxi.LoadTaxiMask(fields[17].GetString()); // must be before InitTaxiNodesForLevel
+ m_taxi.LoadTaxiMask(fields[22].GetString()); // must be before InitTaxiNodesForLevel
- uint32 extraflags = fields[31].GetUInt16();
+ uint32 extraflags = fields[36].GetUInt16();
- m_stableSlots = fields[32].GetUInt8();
+ m_stableSlots = fields[37].GetUInt8();
if (m_stableSlots > MAX_PET_STABLES)
{
- TC_LOG_ERROR("entities.player", "Player can have not more %u stable slots, but have in DB %u", MAX_PET_STABLES, uint32(m_stableSlots));
+ TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) can't have more stable slots than %u, but has %u in DB",
+ GetGUID().ToString().c_str(), MAX_PET_STABLES, uint32(m_stableSlots));
m_stableSlots = MAX_PET_STABLES;
}
- m_atLoginFlags = fields[33].GetUInt16();
+ m_atLoginFlags = fields[38].GetUInt16();
if (HasAtLoginFlag(AT_LOGIN_RENAME))
{
- TC_LOG_ERROR("entities.player", "Player (GUID: %u) tried to login while forced to rename, can't load.'", GetGUID().GetCounter());
+ TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) tried to login while forced to rename, can't load.'", GetGUID().ToString().c_str());
return false;
}
@@ -17272,7 +17307,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
m_lastHonorUpdateTime = logoutTime;
UpdateHonorFields();
- m_deathExpireTime = time_t(fields[36].GetUInt32());
+ m_deathExpireTime = time_t(fields[41].GetUInt32());
if (m_deathExpireTime > now + MAX_DEATH_COUNT * DEATH_EXPIRE_STEP)
m_deathExpireTime = now + MAX_DEATH_COUNT * DEATH_EXPIRE_STEP - 1;
@@ -17309,7 +17344,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
InitRunes();
// rest bonus can only be calculated after InitStatsForLevel()
- m_rest_bonus = fields[21].GetFloat();
+ m_rest_bonus = fields[26].GetFloat();
if (time_diff > 0)
{
@@ -17317,11 +17352,11 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
float bubble0 = 0.031f;
//speed collect rest bonus in offline, in logout, in tavern, city (section/in hour)
float bubble1 = 0.125f;
- float bubble = fields[23].GetUInt8() > 0
+ float bubble = fields[28].GetUInt8() > 0
? bubble1*sWorld->getRate(RATE_REST_OFFLINE_IN_TAVERN_OR_CITY)
: bubble0*sWorld->getRate(RATE_REST_OFFLINE_IN_WILDERNESS);
- SetRestBonus(GetRestBonus()+ time_diff*((float)GetUInt32Value(PLAYER_NEXT_LEVEL_XP)/72000)*bubble);
+ SetRestBonus(GetRestBonus() + time_diff*((float)GetUInt32Value(PLAYER_NEXT_LEVEL_XP) / 72000)*bubble);
}
// load skills after InitStatsForLevel because it triggering aura apply also
@@ -17333,14 +17368,15 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
//mails are loaded only when needed ;-) - when player in game click on mailbox.
//_LoadMail();
- m_specsCount = fields[59].GetUInt8();
- m_activeSpec = fields[60].GetUInt8();
+ m_specsCount = fields[64].GetUInt8();
+ m_activeSpec = fields[65].GetUInt8();
// sanity check
if (m_specsCount > MAX_TALENT_SPECS || m_activeSpec > MAX_TALENT_SPEC || m_specsCount < MIN_TALENT_SPECS)
{
+ TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player %s (%s) has invalid SpecCount = %u and/or invalid ActiveSpec = %u.",
+ GetName().c_str(), GetGUID().ToString().c_str(), uint32(m_specsCount), uint32(m_activeSpec));
m_activeSpec = 0;
- TC_LOG_ERROR("entities.player", "Player %s(GUID: %u) has SpecCount = %u and ActiveSpec = %u.", GetName().c_str(), GetGUID().GetCounter(), m_specsCount, m_activeSpec);
}
_LoadTalents(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_TALENTS));
@@ -17384,7 +17420,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
// check PLAYER_CHOSEN_TITLE compatibility with PLAYER__FIELD_KNOWN_TITLES
// note: PLAYER__FIELD_KNOWN_TITLES updated at quest status loaded
- uint32 curTitle = fields[46].GetUInt32();
+ uint32 curTitle = fields[51].GetUInt32();
if (curTitle && !HasTitle(curTitle))
curTitle = 0;
@@ -17407,15 +17443,15 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
UpdateAllStats();
// restore remembered power/health values (but not more max values)
- uint32 savedHealth = fields[50].GetUInt32();
+ uint32 savedHealth = fields[55].GetUInt32();
SetHealth(savedHealth > GetMaxHealth() ? GetMaxHealth() : savedHealth);
for (uint8 i = 0; i < MAX_POWERS; ++i)
{
- uint32 savedPower = fields[51+i].GetUInt32();
+ uint32 savedPower = fields[56 + i].GetUInt32();
SetPower(Powers(i), savedPower > GetMaxPower(Powers(i)) ? GetMaxPower(Powers(i)) : savedPower);
}
- TC_LOG_DEBUG("entities.player.loading", "The value of player %s after load item and aura is: ", m_name.c_str());
+ TC_LOG_DEBUG("entities.player.loading", "Player::LoadFromDB: The value of player '%s' after load item and aura is: ", m_name.c_str());
outDebugValues();
// GM state
@@ -17467,7 +17503,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
}
// RaF stuff.
- m_grantableLevels = fields[66].GetUInt8();
+ m_grantableLevels = fields[71].GetUInt8();
if (GetSession()->IsARecruiter() || (GetSession()->GetRecruiterId() != 0))
SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_REFER_A_FRIEND);
@@ -17550,9 +17586,10 @@ void Player::_LoadActions(PreparedQueryResult result)
ab->uState = ACTIONBUTTON_UNCHANGED;
else
{
- TC_LOG_ERROR("entities.player", " ...at loading, and will deleted in DB also");
+ TC_LOG_ERROR("entities.player", "Player::_LoadActions: Player '%s' (%s) has an invalid action button (Button: %u, Action: %u, Type: %u). It will be deleted at next save.",
+ GetName().c_str(), GetGUID().ToString().c_str(), button, action, type);
- // Will deleted in DB at next save (it can create data until save but marked as deleted)
+ // Will be deleted in DB at next save (it can create data until save but marked as deleted).
m_actionButtons[button].uState = ACTIONBUTTON_DELETED;
}
} while (result->NextRow());
@@ -17561,7 +17598,7 @@ void Player::_LoadActions(PreparedQueryResult result)
void Player::_LoadAuras(PreparedQueryResult result, uint32 timediff)
{
- TC_LOG_DEBUG("entities.player.loading", "Loading auras for player %u", GetGUID().GetCounter());
+ TC_LOG_DEBUG("entities.player.loading", "Player::_LoadAuras: Loading auras for %s", GetGUID().ToString().c_str());
/* 0 1 2 3 4 5 6 7 8 9 10
QueryResult* result = CharacterDatabase.PQuery("SELECT casterGuid, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2,
@@ -17594,7 +17631,8 @@ void Player::_LoadAuras(PreparedQueryResult result, uint32 timediff)
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellid);
if (!spellInfo)
{
- TC_LOG_ERROR("entities.player", "Unknown aura (spellid %u), ignore.", spellid);
+ TC_LOG_ERROR("entities.player", "Player::_LoadAuras: Player '%s' (%s) has an invalid aura (SpellID: %u), ignoring.",
+ GetName().c_str(), GetGUID().ToString().c_str(), spellid);
continue;
}
@@ -17618,7 +17656,7 @@ void Player::_LoadAuras(PreparedQueryResult result, uint32 timediff)
else
remaincharges = 0;
- if (Aura* aura = Aura::TryCreate(spellInfo, effmask, this, NULL, &baseDamage[0], NULL, caster_guid))
+ if (Aura* aura = Aura::TryCreate(spellInfo, effmask, this, nullptr, &baseDamage[0], nullptr, caster_guid))
{
if (!aura->CanBeSaved())
{
@@ -17628,7 +17666,8 @@ void Player::_LoadAuras(PreparedQueryResult result, uint32 timediff)
aura->SetLoadedState(maxduration, remaintime, remaincharges, stackcount, recalculatemask, &damage[0]);
aura->ApplyForTargets();
- TC_LOG_DEBUG("entities.player", "Added aura spellid %u, effectmask %u", spellInfo->Id, effmask);
+ TC_LOG_DEBUG("entities.player", "Player::_LoadAuras: Added aura (SpellID: %u, EffectMask: %u) to player '%s (%s)",
+ spellInfo->Id, effmask, GetName().c_str(), GetGUID().ToString().c_str());
}
}
while (result->NextRow());
@@ -17651,13 +17690,13 @@ void Player::_LoadGlyphAuras()
continue;
}
else
- TC_LOG_ERROR("entities.player", "Player %s has glyph with typeflags %u in slot with typeflags %u, removing.", m_name.c_str(), gp->TypeFlags, gs->TypeFlags);
+ TC_LOG_ERROR("entities.player", "Player::_LoadGlyphAuras: Player '%s' (%s) has glyph with typeflags %u in slot with typeflags %u, removing.", GetName().c_str(), GetGUID().ToString().c_str(), gp->TypeFlags, gs->TypeFlags);
}
else
- TC_LOG_ERROR("entities.player", "Player %s has not existing glyph slot entry %u on index %u", m_name.c_str(), GetGlyphSlot(i), i);
+ TC_LOG_ERROR("entities.player", "Player::_LoadGlyphAuras: Player '%s' (%s) has not existing glyph slot entry %u on index %u", GetName().c_str(), GetGUID().ToString().c_str(), GetGlyphSlot(i), i);
}
else
- TC_LOG_ERROR("entities.player", "Player %s has not existing glyph entry %u on index %u", m_name.c_str(), glyph, i);
+ TC_LOG_ERROR("entities.player", "Player::_LoadGlyphAuras: Player '%s' (%s) has not existing glyph entry %u on index %u", GetName().c_str(), GetGUID().ToString().c_str(), glyph, i);
// On any error remove glyph
SetGlyph(i, 0);
@@ -17716,7 +17755,7 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff)
// Item is not in bag
if (!bagGuid)
{
- item->SetContainer(NULL);
+ item->SetContainer(nullptr);
item->SetSlot(slot);
if (IsInventoryPos(INVENTORY_SLOT_BAG_0, slot))
@@ -17773,8 +17812,8 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff)
}
else
{
- TC_LOG_ERROR("entities.player", "Player::_LoadInventory: player (GUID: %u, name: '%s') has item (GUID: %u, entry: %u) which doesnt have a valid bag (Bag GUID: %u, slot: %u). Possible cheat?",
- GetGUID().GetCounter(), GetName().c_str(), item->GetGUID().GetCounter(), item->GetEntry(), bagGuid, slot);
+ TC_LOG_ERROR("entities.player", "Player::_LoadInventory: Player '%s' (%s) has item (%s, entry: %u) which doesnt have a valid bag (Bag %u, slot: %u). Possible cheat?",
+ GetName().c_str(), GetGUID().ToString().c_str(), item->GetGUID().ToString().c_str(), item->GetEntry(), bagGuid, slot);
item->DeleteFromInventoryDB(trans);
delete item;
continue;
@@ -17787,8 +17826,8 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff)
item->SetState(ITEM_UNCHANGED, this);
else
{
- TC_LOG_ERROR("entities.player", "Player::_LoadInventory: player (GUID: %u, name: '%s') has item (GUID: %u, entry: %u) which can't be loaded into inventory (Bag GUID: %u, slot: %u) by reason %u. Item will be sent by mail.",
- GetGUID().GetCounter(), GetName().c_str(), item->GetGUID().GetCounter(), item->GetEntry(), bagGuid, slot, err);
+ TC_LOG_ERROR("entities.player", "Player::_LoadInventory: Player '%s' (%s) has item (%s, entry: %u) which can't be loaded into inventory (Bag %u, slot: %u) by reason %u. Item will be sent by mail.",
+ GetName().c_str(), GetGUID().ToString().c_str(), item->GetGUID().ToString().c_str(), item->GetEntry(), bagGuid, slot, err);
item->DeleteFromInventoryDB(trans);
problematicItems.push_back(item);
}
@@ -17818,7 +17857,7 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff)
Item* Player::_LoadItem(SQLTransaction& trans, uint32 zoneId, uint32 timeDiff, Field* fields)
{
- Item* item = NULL;
+ Item* item = nullptr;
ObjectGuid::LowType itemGuid = fields[13].GetUInt32();
uint32 itemEntry = fields[14].GetUInt32();
if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemEntry))
@@ -17827,7 +17866,7 @@ Item* Player::_LoadItem(SQLTransaction& trans, uint32 zoneId, uint32 timeDiff, F
item = NewItemOrBag(proto);
if (item->LoadFromDB(itemGuid, GetGUID(), fields, itemEntry))
{
- PreparedStatement* stmt = NULL;
+ PreparedStatement* stmt;
// Do not allow to have item limited to another map/zone in alive state
if (IsAlive() && item->IsLimitedToAnotherMapOrZone(GetMapId(), zoneId))
@@ -17920,7 +17959,7 @@ Item* Player::_LoadItem(SQLTransaction& trans, uint32 zoneId, uint32 timeDiff, F
}
else
{
- TC_LOG_ERROR("entities.player", "Player::_LoadInventory: player (GUID: %u, name: '%s') has broken item (GUID: %u, entry: %u) in inventory. Deleting item.",
+ TC_LOG_ERROR("entities.player", "Player::_LoadInventory: player (GUID: %u, name: '%s') has a broken item (GUID: %u, entry: %u) in inventory. Deleting item.",
GetGUID().GetCounter(), GetName().c_str(), itemGuid, itemEntry);
remove = true;
}
@@ -17930,12 +17969,12 @@ Item* Player::_LoadItem(SQLTransaction& trans, uint32 zoneId, uint32 timeDiff, F
Item::DeleteFromInventoryDB(trans, itemGuid);
item->FSetState(ITEM_REMOVED);
item->SaveToDB(trans); // it also deletes item object!
- item = NULL;
+ item = nullptr;
}
}
else
{
- TC_LOG_ERROR("entities.player", "Player::_LoadInventory: player (GUID: %u, name: '%s') has unknown item (entry: %u) in inventory. Deleting item.",
+ TC_LOG_ERROR("entities.player", "Player::_LoadInventory: player (GUID: %u, name: '%s') has an unknown item (entry: %u) in inventory. Deleting item.",
GetGUID().GetCounter(), GetName().c_str(), itemEntry);
Item::DeleteFromInventoryDB(trans, itemGuid);
Item::DeleteFromDB(trans, itemGuid);
@@ -17966,7 +18005,8 @@ void Player::_LoadMailedItems(Mail* mail)
if (!proto)
{
- TC_LOG_ERROR("entities.player", "Player %u has unknown item_template (ProtoType) in mailed items(GUID: %u template: %u) in mail (%u), deleted.", GetGUID().GetCounter(), itemGuid, itemTemplate, mail->messageID);
+ TC_LOG_ERROR("entities.player", "Player '%s' (%s) has unknown item_template in mailed items (GUID: %u, Entry: %u) in mail (%u), deleted.",
+ GetName().c_str(), GetGUID().ToString().c_str(), itemGuid, itemTemplate, mail->messageID);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_MAIL_ITEM);
stmt->setUInt32(0, itemGuid);
@@ -17982,7 +18022,7 @@ void Player::_LoadMailedItems(Mail* mail)
if (!item->LoadFromDB(itemGuid, ObjectGuid(HighGuid::Player, fields[13].GetUInt32()), fields, itemTemplate))
{
- TC_LOG_ERROR("entities.player", "Player::_LoadMailedItems - Item in mail (%u) doesn't exist !!!! - item guid: %u, deleted from mail", mail->messageID, itemGuid);
+ TC_LOG_ERROR("entities.player", "Player::_LoadMailedItems: Item (GUID: %u) in mail (%u) doesn't exist, deleted from mail.", itemGuid, mail->messageID);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_ITEM);
stmt->setUInt32(0, itemGuid);
@@ -17990,7 +18030,7 @@ void Player::_LoadMailedItems(Mail* mail)
item->FSetState(ITEM_REMOVED);
- SQLTransaction temp = SQLTransaction(NULL);
+ SQLTransaction temp = SQLTransaction(nullptr);
item->SaveToDB(temp); // it also deletes item object !
continue;
}
@@ -18045,7 +18085,7 @@ void Player::_LoadMail()
if (m->mailTemplateId && !sMailTemplateStore.LookupEntry(m->mailTemplateId))
{
- TC_LOG_ERROR("entities.player", "Player::_LoadMail - Mail (%u) have not existed MailTemplateId (%u), remove at load", m->messageID, m->mailTemplateId);
+ TC_LOG_ERROR("entities.player", "Player::_LoadMail: Mail (%u) has nonexistent MailTemplateId (%u), remove at load", m->messageID, m->mailTemplateId);
m->mailTemplateId = 0;
}
@@ -18102,8 +18142,8 @@ void Player::_LoadQuestStatus(PreparedQueryResult result)
else
{
questStatusData.Status = QUEST_STATUS_INCOMPLETE;
- TC_LOG_ERROR("entities.player", "Player %s (GUID: %u) has invalid quest %d status (%u), replaced by QUEST_STATUS_INCOMPLETE(3).",
- GetName().c_str(), GetGUID().GetCounter(), quest_id, qstatus);
+ TC_LOG_ERROR("entities.player", "Player::_LoadQuestStatus: Player '%s' (%s) has invalid quest %d status (%u), replaced by QUEST_STATUS_INCOMPLETE(3).",
+ GetName().c_str(), GetGUID().ToString().c_str(), quest_id, qstatus);
}
questStatusData.Explored = (fields[2].GetUInt8() > 0);
@@ -18152,7 +18192,8 @@ void Player::_LoadQuestStatus(PreparedQueryResult result)
++slot;
}
- TC_LOG_DEBUG("entities.player.loading", "Quest status is {%u} for quest {%u} for player (GUID: %u)", questStatusData.Status, quest_id, GetGUID().GetCounter());
+
+ TC_LOG_DEBUG("entities.player.loading", "Player::_LoadQuestStatus: Quest status is {%u} for quest {%u} for player (%s)", questStatusData.Status, quest_id, GetGUID().ToString().c_str());
}
}
while (result->NextRow());
@@ -18226,7 +18267,7 @@ void Player::_LoadDailyQuestStatus(PreparedQueryResult result)
if (quest_daily_idx >= PLAYER_MAX_DAILY_QUESTS) // max amount with exist data in query
{
- TC_LOG_ERROR("entities.player", "Player (GUID: %u) have more 25 daily quest records in `charcter_queststatus_daily`", GetGUID().GetCounter());
+ TC_LOG_ERROR("entities.player", "Player (GUID: %u) has more than 25 daily quest records in `charcter_queststatus_daily`", GetGUID().GetCounter());
break;
}
@@ -18242,7 +18283,8 @@ void Player::_LoadDailyQuestStatus(PreparedQueryResult result)
SetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx, quest_id);
++quest_daily_idx;
- TC_LOG_DEBUG("entities.player.loading", "Daily quest (%u) cooldown for player (GUID: %u)", quest_id, GetGUID().GetCounter());
+ TC_LOG_DEBUG("entities.player.loading", "Player::_LoadDailyQuestStatus: Loaded daily quest cooldown (QuestID: %u) for player '%s' (%s)",
+ quest_id, GetName().c_str(), GetGUID().ToString().c_str());
}
while (result->NextRow());
}
@@ -18265,7 +18307,9 @@ void Player::_LoadWeeklyQuestStatus(PreparedQueryResult result)
continue;
m_weeklyquests.insert(quest_id);
- TC_LOG_DEBUG("entities.player.loading", "Weekly quest {%u} cooldown for player (GUID: %u)", quest_id, GetGUID().GetCounter());
+
+ TC_LOG_DEBUG("entities.player.loading", "Player::_LoadWeeklyQuestStatus: Loaded weekly quest cooldown (QuestID: %u) for player '%s' (%s)",
+ quest_id, GetName().c_str(), GetGUID().ToString().c_str());
}
while (result->NextRow());
}
@@ -18289,7 +18333,8 @@ void Player::_LoadSeasonalQuestStatus(PreparedQueryResult result)
continue;
m_seasonalquests[event_id].insert(quest_id);
- TC_LOG_DEBUG("entities.player.loading", "Seasonal quest {%u} cooldown for player (GUID: %u)", quest_id, GetGUID().GetCounter());
+ TC_LOG_DEBUG("entities.player.loading", "Player::_LoadSeasonalQuestStatus: Loaded seasonal quest cooldown (QuestID: %u) for player '%s' (%s)",
+ quest_id, GetName().c_str(), GetGUID().ToString().c_str());
}
while (result->NextRow());
}
@@ -18312,7 +18357,8 @@ void Player::_LoadMonthlyQuestStatus(PreparedQueryResult result)
continue;
m_monthlyquests.insert(quest_id);
- TC_LOG_DEBUG("entities.player.loading", "Monthly quest {%u} cooldown for player (GUID: %u)", quest_id, GetGUID().GetCounter());
+ TC_LOG_DEBUG("entities.player.loading", "Player::_LoadMonthlyQuestStatus: Loaded monthly quest cooldown (QuestID: %u) for player '%s' (%s)",
+ quest_id, GetName().c_str(), GetGUID().ToString().c_str());
}
while (result->NextRow());
}
@@ -18389,12 +18435,14 @@ void Player::_LoadBoundInstances(PreparedQueryResult result)
if (!mapEntry || !mapEntry->IsDungeon())
{
- TC_LOG_ERROR("entities.player", "_LoadBoundInstances: player %s(%d) has bind to not existed or not dungeon map %d (%s)", GetName().c_str(), GetGUID().GetCounter(), mapId, mapname.c_str());
+ TC_LOG_ERROR("entities.player", "Player::_LoadBoundInstances: Player '%s' (%s) has bind to not existed or not dungeon map %d (%s)",
+ GetName().c_str(), GetGUID().ToString().c_str(), mapId, mapname.c_str());
deleteInstance = true;
}
else if (difficulty >= MAX_DIFFICULTY)
{
- TC_LOG_ERROR("entities.player", "_LoadBoundInstances: player %s(%d) has bind to not existed difficulty %d instance for map %u (%s)", GetName().c_str(), GetGUID().GetCounter(), difficulty, mapId, mapname.c_str());
+ TC_LOG_ERROR("entities.player", "Player::_LoadBoundInstances: player '%s' (%s) has bind to not existed difficulty %d instance for map %u (%s)",
+ GetName().c_str(), GetGUID().ToString().c_str(), difficulty, mapId, mapname.c_str());
deleteInstance = true;
}
else
@@ -18402,12 +18450,14 @@ void Player::_LoadBoundInstances(PreparedQueryResult result)
MapDifficulty const* mapDiff = GetMapDifficultyData(mapId, Difficulty(difficulty));
if (!mapDiff)
{
- TC_LOG_ERROR("entities.player", "_LoadBoundInstances: player %s(%d) has bind to not existed difficulty %d instance for map %u (%s)", GetName().c_str(), GetGUID().GetCounter(), difficulty, mapId, mapname.c_str());
+ TC_LOG_ERROR("entities.player", "Player::_LoadBoundInstances: player '%s' (%s) has bind to not existed difficulty %d instance for map %u (%s)",
+ GetName().c_str(), GetGUID().ToString().c_str(), difficulty, mapId, mapname.c_str());
deleteInstance = true;
}
else if (!perm && group)
{
- TC_LOG_ERROR("entities.player", "_LoadBoundInstances: player %s(%d) is in group %d but has a non-permanent character bind to map %d (%s), %d, %d", GetName().c_str(), GetGUID().GetCounter(), group->GetLowGUID(), mapId, mapname.c_str(), instanceId, difficulty);
+ TC_LOG_ERROR("entities.player", "Player::_LoadBoundInstances: player '%s' (%s) is in group %s but has a non-permanent character bind to map %d (%s), %d, %d",
+ GetName().c_str(), GetGUID().ToString().c_str(), group->GetGUID().ToString().c_str(), mapId, mapname.c_str(), instanceId, difficulty);
deleteInstance = true;
}
}
@@ -18437,7 +18487,7 @@ InstancePlayerBind* Player::GetBoundInstance(uint32 mapid, Difficulty difficulty
// some instances only have one difficulty
MapDifficulty const* mapDiff = GetDownscaledMapDifficultyData(mapid, difficulty);
if (!mapDiff)
- return NULL;
+ return nullptr;
BoundInstancesMap::iterator itr = m_boundInstances[difficulty].find(mapid);
if (itr != m_boundInstances[difficulty].end())
@@ -18543,12 +18593,13 @@ InstancePlayerBind* Player::BindToInstance(InstanceSave* save, bool permanent, B
bind.perm = permanent;
bind.extendState = extendState;
if (!load)
- TC_LOG_DEBUG("maps", "Player::BindToInstance: %s(%d) is now bound to map %d, instance %d, difficulty %d", GetName().c_str(), GetGUID().GetCounter(), save->GetMapId(), save->GetInstanceId(), save->GetDifficulty());
- sScriptMgr->OnPlayerBindToInstance(this, save->GetDifficulty(), save->GetMapId(), permanent, uint8(extendState));
+ TC_LOG_DEBUG("maps", "Player::BindToInstance: Player '%s' (%s) is now bound to map (ID: %d, Instance: %d, Difficulty: %d)",
+ GetName().c_str(), GetGUID().ToString().c_str(), save->GetMapId(), save->GetInstanceId(), save->GetDifficulty());
+ sScriptMgr->OnPlayerBindToInstance(this, save->GetDifficulty(), save->GetMapId(), permanent, extendState);
return &bind;
}
- return NULL;
+ return nullptr;
}
void Player::BindToInstance()
@@ -18582,7 +18633,7 @@ void Player::SendRaidInfo()
size_t p_counter = data.wpos();
data << uint32(counter); // placeholder
- time_t now = time(NULL);
+ time_t now = time(nullptr);
for (uint8 i = 0; i < MAX_DIFFICULTY; ++i)
{
@@ -18805,7 +18856,8 @@ bool Player::_LoadHomeBind(PreparedQueryResult result)
PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(), getClass());
if (!info)
{
- TC_LOG_ERROR("entities.player", "Player (Name %s) has incorrect race/class pair. Can't be loaded.", GetName().c_str());
+ TC_LOG_ERROR("entities.player", "Player::_LoadHomeBind: Player '%s' (%s) has incorrect race/class (%u/%u) pair. Can't load.",
+ GetGUID().ToString().c_str(), GetName().c_str(), uint32(getRace()), uint32(getClass()));
return false;
}
@@ -18853,8 +18905,8 @@ bool Player::_LoadHomeBind(PreparedQueryResult result)
CharacterDatabase.Execute(stmt);
}
- TC_LOG_DEBUG("entities.player", "Setting player home position - mapid: %u, areaid: %u, X: %f, Y: %f, Z: %f",
- m_homebindMapId, m_homebindAreaId, m_homebindX, m_homebindY, m_homebindZ);
+ TC_LOG_DEBUG("entities.player", "Player::_LoadHomeBind: Setting home position (MapID: %u, AreaID: %u, X: %f, Y: %f, Z: %f) of player '%s' (%s)",
+ m_homebindMapId, m_homebindAreaId, m_homebindX, m_homebindY, m_homebindZ, GetName().c_str(), GetGUID().ToString().c_str());
return true;
}
@@ -18878,13 +18930,13 @@ void Player::SaveToDB(bool create /*=false*/)
// first save/honor gain after midnight will also update the player's honor fields
UpdateHonorFields();
- TC_LOG_DEBUG("entities.unit", "The value of player %s at save: ", m_name.c_str());
+ TC_LOG_DEBUG("entities.unit", "Player::SaveToDB: The value of player %s at save: ", m_name.c_str());
outDebugValues();
if (!create)
sScriptMgr->OnPlayerSave(this);
- PreparedStatement* stmt = NULL;
+ PreparedStatement* stmt;
uint8 index = 0;
if (create)
@@ -18901,8 +18953,13 @@ void Player::SaveToDB(bool create /*=false*/)
stmt->setUInt8(index++, getLevel());
stmt->setUInt32(index++, GetUInt32Value(PLAYER_XP));
stmt->setUInt32(index++, GetMoney());
- stmt->setUInt32(index++, GetUInt32Value(PLAYER_BYTES));
- stmt->setUInt32(index++, GetUInt32Value(PLAYER_BYTES_2));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, 0));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, 1));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, 2));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, 3));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_2, 0));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_2, 2));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_2, 3));
stmt->setUInt32(index++, GetUInt32Value(PLAYER_FLAGS));
stmt->setUInt16(index++, (uint16)GetMapId());
stmt->setUInt32(index++, (uint32)GetInstanceId());
@@ -18927,7 +18984,7 @@ void Player::SaveToDB(bool create /*=false*/)
stmt->setUInt32(index++, m_Played_time[PLAYED_TIME_TOTAL]);
stmt->setUInt32(index++, m_Played_time[PLAYED_TIME_LEVEL]);
stmt->setFloat(index++, finiteAlways(m_rest_bonus));
- stmt->setUInt32(index++, uint32(time(NULL)));
+ stmt->setUInt32(index++, uint32(time(nullptr)));
stmt->setUInt8(index++, (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) ? 1 : 0));
//save, far from tavern/city
//save, but in tavern/city
@@ -18993,7 +19050,7 @@ void Player::SaveToDB(bool create /*=false*/)
stmt->setString(index++, ss.str());
stmt->setUInt8(index++, GetByteValue(PLAYER_FIELD_BYTES, 2));
- stmt->setUInt32(index++, m_grantableLevels);
+ stmt->setUInt32(index, m_grantableLevels);
}
else
{
@@ -19006,8 +19063,13 @@ void Player::SaveToDB(bool create /*=false*/)
stmt->setUInt8(index++, getLevel());
stmt->setUInt32(index++, GetUInt32Value(PLAYER_XP));
stmt->setUInt32(index++, GetMoney());
- stmt->setUInt32(index++, GetUInt32Value(PLAYER_BYTES));
- stmt->setUInt32(index++, GetUInt32Value(PLAYER_BYTES_2));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, 0));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, 1));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, 2));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, 3));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_2, 0));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_2, 2));
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_2, 3));
stmt->setUInt32(index++, GetUInt32Value(PLAYER_FLAGS));
if (!IsBeingTeleported())
@@ -19047,7 +19109,7 @@ void Player::SaveToDB(bool create /*=false*/)
stmt->setUInt32(index++, m_Played_time[PLAYED_TIME_TOTAL]);
stmt->setUInt32(index++, m_Played_time[PLAYED_TIME_LEVEL]);
stmt->setFloat(index++, finiteAlways(m_rest_bonus));
- stmt->setUInt32(index++, uint32(time(NULL)));
+ stmt->setUInt32(index++, uint32(time(nullptr)));
stmt->setUInt8(index++, (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) ? 1 : 0));
//save, far from tavern/city
//save, but in tavern/city
@@ -19166,7 +19228,7 @@ void Player::SaveInventoryAndGoldToDB(SQLTransaction& trans)
SaveGoldToDB(trans);
}
-void Player::SaveGoldToDB(SQLTransaction& trans)
+void Player::SaveGoldToDB(SQLTransaction& trans) const
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_MONEY);
stmt->setUInt32(0, GetMoney());
@@ -19176,7 +19238,7 @@ void Player::SaveGoldToDB(SQLTransaction& trans)
void Player::_SaveActions(SQLTransaction& trans)
{
- PreparedStatement* stmt = NULL;
+ PreparedStatement* stmt;
for (ActionButtonList::iterator itr = m_actionButtons.begin(); itr != m_actionButtons.end();)
{
@@ -19280,7 +19342,7 @@ void Player::_SaveAuras(SQLTransaction& trans)
void Player::_SaveInventory(SQLTransaction& trans)
{
- PreparedStatement* stmt = NULL;
+ PreparedStatement* stmt;
// force items in buyback slots to new state
// and remove those that aren't already
for (uint8 i = BUYBACK_SLOT_START; i < BUYBACK_SLOT_END; ++i)
@@ -19318,7 +19380,8 @@ void Player::_SaveInventory(SQLTransaction& trans)
}
else
{
- TC_LOG_ERROR("entities.player", "Can't find %s but is in refundable storage for player %u ! Removing.", itr->ToString().c_str(), GetGUID().GetCounter());
+ TC_LOG_ERROR("entities.player", "Player::_SaveInventory: Can't find item (%s) in refundable storage for player '%s' (%s), removing.",
+ itr->ToString().c_str(), GetName().c_str(), GetGUID().ToString().c_str());
m_refundableItems.erase(itr);
}
}
@@ -19344,12 +19407,14 @@ void Player::_SaveInventory(SQLTransaction& trans)
if (item->GetState() != ITEM_REMOVED)
{
Item* test = GetItemByPos(item->GetBagSlot(), item->GetSlot());
- if (test == NULL)
+ if (test == nullptr)
{
ObjectGuid::LowType bagTestGUID = 0;
if (Item* test2 = GetItemByPos(INVENTORY_SLOT_BAG_0, item->GetBagSlot()))
bagTestGUID = test2->GetGUID().GetCounter();
- TC_LOG_ERROR("entities.player", "Player(GUID: %u Name: %s)::_SaveInventory - the bag(%u) and slot(%u) values for the item with guid %u (state %d) are incorrect, the player doesn't have an item at that position!", lowGuid, GetName().c_str(), item->GetBagSlot(), item->GetSlot(), item->GetGUID().GetCounter(), (int32)item->GetState());
+
+ TC_LOG_ERROR("entities.player", "Player::_SaveInventory: Player '%s' (%s) has incorrect values (Bag: %u, Slot: %u) for the item (%s, State: %d). The player doesn't have an item at that position.",
+ GetName().c_str(), GetGUID().ToString().c_str(), item->GetBagSlot(), item->GetSlot(), item->GetGUID().ToString().c_str(), (int32)item->GetState());
// according to the test that was just performed nothing should be in this slot, delete
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_INVENTORY_BY_BAG_SLOT);
stmt->setUInt32(0, bagTestGUID);
@@ -19365,9 +19430,10 @@ void Player::_SaveInventory(SQLTransaction& trans)
}
else if (test != item)
{
- TC_LOG_ERROR("entities.player", "Player(GUID: %u Name: %s)::_SaveInventory - the bag(%u) and slot(%u) values for the item with guid %u are incorrect, the item with guid %u is there instead!", lowGuid, GetName().c_str(), item->GetBagSlot(), item->GetSlot(), item->GetGUID().GetCounter(), test->GetGUID().GetCounter());
+ TC_LOG_ERROR("entities.player", "Player::_SaveInventory: Player '%s' (%s) has incorrect values (Bag: %u, Slot: %u) for the item (%s). %s is there instead!",
+ GetName().c_str(), GetGUID().ToString().c_str(), item->GetBagSlot(), item->GetSlot(), item->GetGUID().ToString().c_str(), test->GetGUID().ToString().c_str());
// save all changes to the item...
- if (item->GetState() != ITEM_NEW) // only for existing items, no dupes
+ if (item->GetState() != ITEM_NEW) // only for existing items, no duplicates
item->SaveToDB(trans);
// ...but do not save position in invntory
continue;
@@ -19404,7 +19470,7 @@ void Player::_SaveMail(SQLTransaction& trans)
if (!m_mailsLoaded)
return;
- PreparedStatement* stmt = NULL;
+ PreparedStatement* stmt;
for (PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end(); ++itr)
{
@@ -19480,7 +19546,7 @@ void Player::_SaveQuestStatus(SQLTransaction& trans)
QuestStatusSaveMap::iterator saveItr;
QuestStatusMap::iterator statusItr;
- PreparedStatement* stmt = NULL;
+ PreparedStatement* stmt;
bool keepAbandoned = !(sWorld->GetCleaningFlags() & CharacterDatabaseCleaner::CLEANING_FLAG_QUESTSTATUS);
@@ -19662,7 +19728,7 @@ void Player::_SaveMonthlyQuestStatus(SQLTransaction& trans)
void Player::_SaveSkills(SQLTransaction& trans)
{
- PreparedStatement* stmt = NULL;
+ PreparedStatement* stmt;
// we don't need transactions here.
for (SkillStatusMap::iterator itr = mSkillStatus.begin(); itr != mSkillStatus.end();)
{
@@ -19718,7 +19784,7 @@ void Player::_SaveSkills(SQLTransaction& trans)
void Player::_SaveSpells(SQLTransaction& trans)
{
- PreparedStatement* stmt = NULL;
+ PreparedStatement* stmt;
for (PlayerSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end();)
{
@@ -19756,13 +19822,13 @@ void Player::_SaveSpells(SQLTransaction& trans)
// save player stats -- only for external usage
// real stats will be recalculated on player login
-void Player::_SaveStats(SQLTransaction& trans)
+void Player::_SaveStats(SQLTransaction& trans) const
{
// check if stat saving is enabled and if char level is high enough
if (!sWorld->getIntConfig(CONFIG_MIN_LEVEL_STAT_SAVE) || getLevel() < sWorld->getIntConfig(CONFIG_MIN_LEVEL_STAT_SAVE))
return;
- PreparedStatement* stmt = NULL;
+ PreparedStatement* stmt;
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_STATS);
stmt->setUInt32(0, GetGUID().GetCounter());
@@ -19826,7 +19892,7 @@ void Player::UpdateSpeakTime()
if (GetSession()->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHAT_SPAM))
return;
- time_t current = time (NULL);
+ time_t current = time(nullptr);
if (m_speakTime > current)
{
uint32 max_count = sWorld->getIntConfig(CONFIG_CHATFLOOD_MESSAGE_COUNT);
@@ -19852,14 +19918,14 @@ void Player::UpdateSpeakTime()
bool Player::CanSpeak() const
{
- return GetSession()->m_muteTime <= time (NULL);
+ return GetSession()->m_muteTime <= time (nullptr);
}
/*********************************************************/
/*** LOW LEVEL FUNCTIONS:Notifiers ***/
/*********************************************************/
-void Player::SendAttackSwingNotInRange()
+void Player::SendAttackSwingNotInRange() const
{
WorldPacket data(SMSG_ATTACKSWING_NOTINRANGE, 0);
GetSession()->SendPacket(&data);
@@ -19893,48 +19959,38 @@ void Player::SetUInt32ValueInArray(Tokenizer& tokens, uint16 index, uint32 value
void Player::Customize(CharacterCustomizeInfo const* customizeInfo, SQLTransaction& trans)
{
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PLAYERBYTES2);
- stmt->setUInt32(0, customizeInfo->Guid.GetCounter());
- PreparedQueryResult result = CharacterDatabase.Query(stmt);
-
- if (!result)
- return;
-
- Field* fields = result->Fetch();
-
- uint32 playerBytes2 = fields[0].GetUInt32();
- playerBytes2 &= ~0xFF;
- playerBytes2 |= customizeInfo->FacialHair;
-
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GENDER_PLAYERBYTES);
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GENDER_AND_APPEARANCE);
stmt->setUInt8(0, customizeInfo->Gender);
- stmt->setUInt32(1, customizeInfo->Skin | (customizeInfo->Face << 8) | (customizeInfo->HairStyle << 16) | (customizeInfo->HairColor << 24));
- stmt->setUInt32(2, playerBytes2);
- stmt->setUInt32(3, customizeInfo->Guid.GetCounter());
+ stmt->setUInt8(1, customizeInfo->Skin);
+ stmt->setUInt8(2, customizeInfo->Face);
+ stmt->setUInt8(3, customizeInfo->HairStyle);
+ stmt->setUInt8(4, customizeInfo->HairColor);
+ stmt->setUInt8(5, customizeInfo->FacialHair);
+ stmt->setUInt32(6, customizeInfo->Guid.GetCounter());
CharacterDatabase.ExecuteOrAppend(trans, stmt);
}
-void Player::SendAttackSwingDeadTarget()
+void Player::SendAttackSwingDeadTarget() const
{
WorldPacket data(SMSG_ATTACKSWING_DEADTARGET, 0);
GetSession()->SendPacket(&data);
}
-void Player::SendAttackSwingCantAttack()
+void Player::SendAttackSwingCantAttack() const
{
WorldPacket data(SMSG_ATTACKSWING_CANT_ATTACK, 0);
GetSession()->SendPacket(&data);
}
-void Player::SendAttackSwingCancelAttack()
+void Player::SendAttackSwingCancelAttack() const
{
WorldPacket data(SMSG_CANCEL_COMBAT, 0);
GetSession()->SendPacket(&data);
}
-void Player::SendAttackSwingBadFacingAttack()
+void Player::SendAttackSwingBadFacingAttack() const
{
WorldPacket data(SMSG_ATTACKSWING_BADFACING, 0);
GetSession()->SendPacket(&data);
@@ -19947,7 +20003,7 @@ void Player::SendAutoRepeatCancel(Unit* target)
SendMessageToSet(&data, false);
}
-void Player::SendExplorationExperience(uint32 Area, uint32 Experience)
+void Player::SendExplorationExperience(uint32 Area, uint32 Experience) const
{
WorldPacket data(SMSG_EXPLORATION_EXPERIENCE, 8);
data << uint32(Area);
@@ -19955,7 +20011,7 @@ void Player::SendExplorationExperience(uint32 Area, uint32 Experience)
GetSession()->SendPacket(&data);
}
-void Player::SendDungeonDifficulty(bool IsInGroup)
+void Player::SendDungeonDifficulty(bool IsInGroup) const
{
uint8 val = 0x00000001;
WorldPacket data(MSG_SET_DUNGEON_DIFFICULTY, 12);
@@ -19965,7 +20021,7 @@ void Player::SendDungeonDifficulty(bool IsInGroup)
GetSession()->SendPacket(&data);
}
-void Player::SendRaidDifficulty(bool IsInGroup, int32 forcedDifficulty)
+void Player::SendRaidDifficulty(bool IsInGroup, int32 forcedDifficulty) const
{
uint8 val = 0x00000001;
WorldPacket data(MSG_SET_RAID_DIFFICULTY, 12);
@@ -19975,7 +20031,7 @@ void Player::SendRaidDifficulty(bool IsInGroup, int32 forcedDifficulty)
GetSession()->SendPacket(&data);
}
-void Player::SendResetFailedNotify(uint32 mapid)
+void Player::SendResetFailedNotify(uint32 mapid) const
{
WorldPacket data(SMSG_RESET_FAILED_NOTIFY, 4);
data << uint32(mapid);
@@ -20031,14 +20087,14 @@ void Player::ResetInstances(uint8 method, bool isRaid)
}
}
-void Player::SendResetInstanceSuccess(uint32 MapId)
+void Player::SendResetInstanceSuccess(uint32 MapId) const
{
WorldPacket data(SMSG_INSTANCE_RESET, 4);
data << uint32(MapId);
GetSession()->SendPacket(&data);
}
-void Player::SendResetInstanceFailed(uint32 reason, uint32 MapId)
+void Player::SendResetInstanceFailed(uint32 reason, uint32 MapId) const
{
/*reasons for instance reset failure:
// 0: There are players inside the instance.
@@ -20116,22 +20172,22 @@ Pet* Player::GetPet() const
if (ObjectGuid pet_guid = GetPetGUID())
{
if (!pet_guid.IsPet())
- return NULL;
+ return nullptr;
Pet* pet = ObjectAccessor::GetPet(*this, pet_guid);
if (!pet)
- return NULL;
+ return nullptr;
if (IsInWorld() && pet)
return pet;
- //there may be a guardian in slot
- //TC_LOG_ERROR("entities.player", "Player::GetPet: Pet %u not exist.", GUID_LOPART(pet_guid));
+ // there may be a guardian in this slot
+ //TC_LOG_ERROR("entities.player", "Player::GetPet: Pet %u does not exist.", GUID_LOPART(pet_guid));
//const_cast<Player*>(this)->SetPetGUID(0);
}
- return NULL;
+ return nullptr;
}
void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent)
@@ -20141,7 +20197,8 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent)
if (pet)
{
- TC_LOG_DEBUG("entities.pet", "RemovePet %u, %u, %u", pet->GetEntry(), mode, returnreagent);
+ TC_LOG_DEBUG("entities.pet", "Player::RemovePet: Player '%s' (%s), Pet (Entry: %u, Mode: %u, ReturnReagent: %u)",
+ GetName().c_str(), GetGUID().ToString().c_str(), pet->GetEntry(), mode, returnreagent);
if (pet->m_removed)
return;
@@ -20226,7 +20283,7 @@ void Player::StopCastingCharm()
if (charm->GetTypeId() == TYPEID_UNIT)
{
if (charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_PUPPET))
- ((Puppet*)charm)->UnSummon();
+ static_cast<Puppet*>(charm)->UnSummon();
else if (charm->IsVehicle())
ExitVehicle();
}
@@ -20235,14 +20292,14 @@ void Player::StopCastingCharm()
if (GetCharmGUID())
{
- TC_LOG_FATAL("entities.player", "Player %s (%s) is not able to uncharm unit (%s)", GetName().c_str(), GetGUID().ToString().c_str(), GetCharmGUID().ToString().c_str());
- if (charm->GetCharmerGUID())
+ TC_LOG_FATAL("entities.player", "Player::StopCastingCharm: Player '%s' (%s) is not able to uncharm unit (%s)", GetName().c_str(), GetGUID().ToString().c_str(), GetCharmGUID().ToString().c_str());
+ if (!charm->GetCharmerGUID().IsEmpty())
{
- TC_LOG_FATAL("entities.player", "Charmed unit has charmer %s", charm->GetCharmerGUID().ToString().c_str());
+ TC_LOG_FATAL("entities.player", "Player::StopCastingCharm: Charmed unit has charmer %s", charm->GetCharmerGUID().ToString().c_str());
ABORT();
}
- else
- SetCharm(charm, false);
+
+ SetCharm(charm, false);
}
}
@@ -20330,7 +20387,7 @@ bool Player::RemoveMItem(uint32 id)
return mMitems.erase(id) ? true : false;
}
-void Player::SendOnCancelExpectedVehicleRideAura()
+void Player::SendOnCancelExpectedVehicleRideAura() const
{
WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0);
GetSession()->SendPacket(&data);
@@ -20395,7 +20452,7 @@ void Player::PossessSpellInitialize()
if (!charmInfo)
{
- TC_LOG_ERROR("entities.player", "Player::PossessSpellInitialize(): charm (%s) has no charminfo!", charm->GetGUID().ToString().c_str());
+ TC_LOG_ERROR("entities.player", "Player::PossessSpellInitialize: charm (%s) has no charminfo!", charm->GetGUID().ToString().c_str());
return;
}
@@ -20442,7 +20499,8 @@ void Player::VehicleSpellInitialize()
if (!sConditionMgr->IsObjectMeetingVehicleSpellConditions(vehicle->GetEntry(), spellId, this, vehicle))
{
- TC_LOG_DEBUG("condition", "VehicleSpellInitialize: conditions not met for Vehicle entry %u spell %u", vehicle->ToCreature()->GetEntry(), spellId);
+ TC_LOG_DEBUG("condition", "Player::VehicleSpellInitialize: Player '%s' (%s) doesn't meet conditions for vehicle (Entry: %u, Spell: %u)",
+ GetName().c_str(), GetGUID().ToString().c_str(), vehicle->ToCreature()->GetEntry(), spellId);
data << uint16(0) << uint8(0) << uint8(i+8);
continue;
}
@@ -20472,7 +20530,8 @@ void Player::CharmSpellInitialize()
CharmInfo* charmInfo = charm->GetCharmInfo();
if (!charmInfo)
{
- TC_LOG_ERROR("entities.player", "Player::CharmSpellInitialize(): the player's charm (%s) has no charminfo!", charm->GetGUID().ToString().c_str());
+ TC_LOG_ERROR("entities.player", "Player::CharmSpellInitialize(): Player '%s' (%s) has a charm (%s) but no no charminfo!",
+ GetName().c_str(), GetGUID().ToString().c_str(), charm->GetGUID().ToString().c_str());
return;
}
@@ -20517,14 +20576,14 @@ void Player::CharmSpellInitialize()
GetSession()->SendPacket(&data);
}
-void Player::SendRemoveControlBar()
+void Player::SendRemoveControlBar() const
{
WorldPacket data(SMSG_PET_SPELLS, 8);
data << uint64(0);
GetSession()->SendPacket(&data);
}
-bool Player::IsAffectedBySpellmod(SpellInfo const* spellInfo, SpellModifier* mod, Spell* spell)
+bool Player::IsAffectedBySpellmod(SpellInfo const* spellInfo, SpellModifier* mod, Spell* spell) const
{
if (!mod || !spellInfo)
return false;
@@ -20542,7 +20601,7 @@ bool Player::IsAffectedBySpellmod(SpellInfo const* spellInfo, SpellModifier* mod
void Player::AddSpellMod(SpellModifier* mod, bool apply)
{
- TC_LOG_DEBUG("spells", "Player::AddSpellMod %d", mod->spellId);
+ TC_LOG_DEBUG("spells", "Player::AddSpellMod: Player '%s' (%s), SpellID: %d", GetName().c_str(), GetGUID().ToString().c_str(), mod->spellId);
uint16 Opcode = (mod->type == SPELLMOD_FLAT) ? SMSG_SET_FLAT_SPELL_MODIFIER : SMSG_SET_PCT_SPELL_MODIFIER;
int i = 0;
@@ -20713,7 +20772,7 @@ void Player::SetSpellModTakingSpell(Spell* spell, bool apply)
}
// send Proficiency
-void Player::SendProficiency(ItemClass itemClass, uint32 itemSubclassMask)
+void Player::SendProficiency(ItemClass itemClass, uint32 itemSubclassMask) const
{
WorldPacket data(SMSG_SET_PROFICIENCY, 1 + 4);
data << uint8(itemClass) << uint32(itemSubclassMask);
@@ -20959,7 +21018,7 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc
uint32 firstcost = 0;
uint32 prevnode = sourcenode;
- uint32 lastnode = 0;
+ uint32 lastnode;
for (uint32 i = 1; i < nodes.size(); ++i)
{
@@ -20992,7 +21051,7 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc
// only one mount ID for both sides. Probably not good to use 315 in case DBC nodes
// change but I couldn't find a suitable alternative. OK to use class because only DK
// can use this taxi.
- uint32 mount_display_id = sObjectMgr->GetTaxiMountDisplayId(sourcenode, GetTeam(), npc == NULL || (sourcenode == 315 && getClass() == CLASS_DEATH_KNIGHT));
+ uint32 mount_display_id = sObjectMgr->GetTaxiMountDisplayId(sourcenode, GetTeam(), npc == nullptr || (sourcenode == 315 && getClass() == CLASS_DEATH_KNIGHT));
// in spell case allow 0 model
if ((mount_display_id == 0 && spellid == 0) || sourcepath == 0)
@@ -21052,7 +21111,7 @@ bool Player::ActivateTaxiPathTo(uint32 taxi_path_id, uint32 spellid /*= 0*/)
nodes[0] = entry->from;
nodes[1] = entry->to;
- return ActivateTaxiPathTo(nodes, NULL, spellid);
+ return ActivateTaxiPathTo(nodes, nullptr, spellid);
}
void Player::CleanupAfterTaxiFlight()
@@ -21063,13 +21122,13 @@ void Player::CleanupAfterTaxiFlight()
getHostileRefManager().setOnlineOfflineState(true);
}
-void Player::ContinueTaxiFlight()
+void Player::ContinueTaxiFlight() const
{
uint32 sourceNode = m_taxi.GetTaxiSource();
if (!sourceNode)
return;
- TC_LOG_DEBUG("entities.unit", "WORLD: Restart character %u taxi flight", GetGUID().GetCounter());
+ TC_LOG_DEBUG("entities.unit", "Player::ContinueTaxiFlight: Restart %s taxi flight", GetGUID().ToString().c_str());
uint32 mountDisplayId = sObjectMgr->GetTaxiMountDisplayId(sourceNode, GetTeam(), true);
if (!mountDisplayId)
@@ -21082,7 +21141,7 @@ void Player::ContinueTaxiFlight()
TaxiPathNodeList const& nodeList = sTaxiPathNodesByPath[path];
- float distPrev = MAP_SIZE*MAP_SIZE;
+ float distPrev;
float distNext =
(nodeList[0]->LocX - GetPositionX())*(nodeList[0]->LocX - GetPositionX()) +
(nodeList[0]->LocY - GetPositionY())*(nodeList[0]->LocY - GetPositionY()) +
@@ -21171,7 +21230,7 @@ void Player::InitDisplayIds()
PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(), getClass());
if (!info)
{
- TC_LOG_ERROR("entities.player", "Player %s (%s) has incorrect race/class pair. Can't init display ids.", GetName().c_str(), GetGUID().ToString().c_str());
+ TC_LOG_ERROR("entities.player", "Player::InitDisplayIds: Player '%s' (%s) has incorrect race/class pair. Can't init display ids.", GetName().c_str(), GetGUID().ToString().c_str());
return;
}
@@ -21187,7 +21246,7 @@ void Player::InitDisplayIds()
SetNativeDisplayId(info->displayId_m);
break;
default:
- TC_LOG_ERROR("entities.player", "Player %s (%s) has invalid gender %u", GetName().c_str(), GetGUID().ToString().c_str(), gender);
+ TC_LOG_ERROR("entities.player", "Player::InitDisplayIds: Player '%s' (%s) has invalid gender %u", GetName().c_str(), GetGUID().ToString().c_str(), gender);
}
}
@@ -21200,7 +21259,7 @@ inline bool Player::_StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 c
CanEquipNewItem(slot, uiDest, item, false);
if (msg != EQUIP_ERR_OK)
{
- SendEquipError(msg, NULL, NULL, item);
+ SendEquipError(msg, nullptr, nullptr, item);
return false;
}
@@ -21270,13 +21329,13 @@ bool Player::BuyItemFromVendorSlot(ObjectGuid vendorguid, uint32 vendorslot, uin
ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item);
if (!pProto)
{
- SendBuyError(BUY_ERR_CANT_FIND_ITEM, NULL, item, 0);
+ SendBuyError(BUY_ERR_CANT_FIND_ITEM, nullptr, item, 0);
return false;
}
if (!(pProto->AllowableClass & getClassMask()) && pProto->Bonding == BIND_WHEN_PICKED_UP && !IsGameMaster())
{
- SendBuyError(BUY_ERR_CANT_FIND_ITEM, NULL, item, 0);
+ SendBuyError(BUY_ERR_CANT_FIND_ITEM, nullptr, item, 0);
return false;
}
@@ -21286,14 +21345,16 @@ bool Player::BuyItemFromVendorSlot(ObjectGuid vendorguid, uint32 vendorslot, uin
Creature* creature = GetNPCIfCanInteractWith(vendorguid, UNIT_NPC_FLAG_VENDOR);
if (!creature)
{
- TC_LOG_DEBUG("network", "WORLD: BuyItemFromVendor - %s not found or you can't interact with him.", vendorguid.ToString().c_str());
- SendBuyError(BUY_ERR_DISTANCE_TOO_FAR, NULL, item, 0);
+ TC_LOG_DEBUG("network", "Player::BuyItemFromVendorSlot: Vendor (%s) not found or player '%s' (%s) can't interact with him.",
+ vendorguid.ToString().c_str(), GetName().c_str(), GetGUID().ToString().c_str());
+ SendBuyError(BUY_ERR_DISTANCE_TOO_FAR, nullptr, item, 0);
return false;
}
if (!sConditionMgr->IsObjectMeetingVendorItemConditions(creature->GetEntry(), item, this, creature))
{
- TC_LOG_DEBUG("condition", "BuyItemFromVendor: conditions not met for creature entry %u item %u", creature->GetEntry(), item);
+ TC_LOG_DEBUG("condition", "Player::BuyItemFromVendorSlot: Player '%s' (%s) doesn't meed conditions for creature (Entry: %u, Item: %u)",
+ GetName().c_str(), GetGUID().ToString().c_str(), creature->GetEntry(), item);
SendBuyError(BUY_ERR_CANT_FIND_ITEM, creature, item, 0);
return false;
}
@@ -21340,21 +21401,21 @@ bool Player::BuyItemFromVendorSlot(ObjectGuid vendorguid, uint32 vendorslot, uin
ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(crItem->ExtendedCost);
if (!iece)
{
- TC_LOG_ERROR("entities.player", "Item %u have wrong ExtendedCost field value %u", pProto->ItemId, crItem->ExtendedCost);
+ TC_LOG_ERROR("entities.player", "Player::BuyItemFromVendorSlot: Item %u has wrong ExtendedCost field value %u", pProto->ItemId, crItem->ExtendedCost);
return false;
}
// honor points price
if (GetHonorPoints() < (iece->reqhonorpoints * count))
{
- SendEquipError(EQUIP_ERR_NOT_ENOUGH_HONOR_POINTS, NULL, NULL);
+ SendEquipError(EQUIP_ERR_NOT_ENOUGH_HONOR_POINTS, nullptr, nullptr);
return false;
}
// arena points price
if (GetArenaPoints() < (iece->reqarenapoints * count))
{
- SendEquipError(EQUIP_ERR_NOT_ENOUGH_ARENA_POINTS, NULL, NULL);
+ SendEquipError(EQUIP_ERR_NOT_ENOUGH_ARENA_POINTS, nullptr, nullptr);
return false;
}
@@ -21363,7 +21424,7 @@ bool Player::BuyItemFromVendorSlot(ObjectGuid vendorguid, uint32 vendorslot, uin
{
if (iece->reqitem[i] && !HasItemCount(iece->reqitem[i], (iece->reqitemcount[i] * count)))
{
- SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL);
+ SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, nullptr, nullptr);
return false;
}
}
@@ -21372,7 +21433,7 @@ bool Player::BuyItemFromVendorSlot(ObjectGuid vendorguid, uint32 vendorslot, uin
if (GetMaxPersonalArenaRatingRequirement(iece->reqarenaslot) < iece->reqpersonalarenarating)
{
// probably not the proper equip err
- SendEquipError(EQUIP_ERR_CANT_EQUIP_RANK, NULL, NULL);
+ SendEquipError(EQUIP_ERR_CANT_EQUIP_RANK, nullptr, nullptr);
return false;
}
}
@@ -21383,7 +21444,8 @@ bool Player::BuyItemFromVendorSlot(ObjectGuid vendorguid, uint32 vendorslot, uin
uint32 maxCount = MAX_MONEY_AMOUNT / pProto->BuyPrice;
if ((uint32)count > maxCount)
{
- TC_LOG_ERROR("entities.player", "Player %s tried to buy %u item id %u, causing overflow", GetName().c_str(), (uint32)count, pProto->ItemId);
+ TC_LOG_ERROR("entities.player", "Player::BuyItemFromVendorSlot: Player '%s' (%s) tried to buy item (ItemID: %u, Count: %u), causing overflow",
+ GetName().c_str(), GetGUID().ToString().c_str(), pProto->ItemId, (uint32)count);
count = (uint8)maxCount;
}
price = pProto->BuyPrice * count; //it should not exceed MAX_MONEY_AMOUNT
@@ -21407,7 +21469,7 @@ bool Player::BuyItemFromVendorSlot(ObjectGuid vendorguid, uint32 vendorslot, uin
{
if (pProto->BuyCount * count != 1)
{
- SendEquipError(EQUIP_ERR_ITEM_CANT_BE_EQUIPPED, NULL, NULL);
+ SendEquipError(EQUIP_ERR_ITEM_CANT_BE_EQUIPPED, nullptr, nullptr);
return false;
}
if (!_StoreOrEquipNewItem(vendorslot, item, count, bag, slot, price, pProto, creature, crItem, false))
@@ -21415,7 +21477,7 @@ bool Player::BuyItemFromVendorSlot(ObjectGuid vendorguid, uint32 vendorslot, uin
}
else
{
- SendEquipError(EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, NULL, NULL);
+ SendEquipError(EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, nullptr, nullptr);
return false;
}
@@ -21477,7 +21539,8 @@ void Player::UpdateHomebindTime(uint32 time)
data << uint32(m_HomebindTimer);
data << uint32(1);
GetSession()->SendPacket(&data);
- TC_LOG_DEBUG("maps", "PLAYER: Player '%s' (GUID: %u) will be teleported to homebind in 60 seconds", GetName().c_str(), GetGUID().GetCounter());
+ TC_LOG_DEBUG("maps", "Player::UpdateHomebindTime: Player '%s' (%s) will be teleported to homebind in 60 seconds",
+ GetName().c_str(), GetGUID().ToString().c_str());
}
}
@@ -21513,7 +21576,7 @@ void Player::UpdatePvPState(bool onlyFFA)
else // in friendly area
{
if (IsPvP() && !HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP) && !pvpInfo.EndTimer)
- pvpInfo.EndTimer = time(NULL); // start toggle-off
+ pvpInfo.EndTimer = time(nullptr); // start toggle-off
}
}
@@ -21533,7 +21596,7 @@ void Player::UpdatePvP(bool state, bool _override)
}
else
{
- pvpInfo.EndTimer = time(NULL);
+ pvpInfo.EndTimer = time(nullptr);
SetPvP(state);
}
}
@@ -21547,7 +21610,7 @@ void Player::UpdatePotionCooldown(Spell* spell)
// Call not from spell cast, send cooldown event for item spells if no in combat
if (!spell)
{
- // spell/item pair let set proper cooldown (except not existed charged spell cooldown spellmods for potions)
+ // spell/item pair let set proper cooldown (except non-existing charged spell cooldown spellmods for potions)
if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(m_lastPotionId))
for (uint8 idx = 0; idx < MAX_ITEM_PROTO_SPELLS; ++idx)
if (proto->Spells[idx].SpellId && proto->Spells[idx].SpellTrigger == ITEM_SPELLTRIGGER_ON_USE)
@@ -21561,26 +21624,19 @@ void Player::UpdatePotionCooldown(Spell* spell)
m_lastPotionId = 0;
}
-void Player::setResurrectRequestData(ObjectGuid guid, uint32 mapId, float X, float Y, float Z, uint32 health, uint32 mana)
+void Player::SetResurrectRequestData(Unit* caster, uint32 health, uint32 mana, uint32 appliedAura)
{
- m_resurrectGUID = guid;
- m_resurrectMap = mapId;
- m_resurrectX = X;
- m_resurrectY = Y;
- m_resurrectZ = Z;
- m_resurrectHealth = health;
- m_resurrectMana = mana;
+ ASSERT(!IsResurrectRequested());
+ _resurrectionData.reset(new ResurrectionData());
+ _resurrectionData->GUID = caster->GetGUID();
+ _resurrectionData->Location.WorldRelocate(*caster);
+ _resurrectionData->Health = health;
+ _resurrectionData->Mana = mana;
+ _resurrectionData->Aura = appliedAura;
}
-void Player::clearResurrectRequestData()
-{
- setResurrectRequestData(ObjectGuid::Empty, 0, 0.0f, 0.0f, 0.0f, 0, 0);
-
- m_ghoulResurrectPlayerGUID = ObjectGuid::Empty;
- m_ghoulResurrectGhoulGUID = ObjectGuid::Empty;
-}
//slot to be excluded while counting
-bool Player::EnchantmentFitsRequirements(uint32 enchantmentcondition, int8 slot)
+bool Player::EnchantmentFitsRequirements(uint32 enchantmentcondition, int8 slot) const
{
if (!enchantmentcondition)
return true;
@@ -21659,7 +21715,8 @@ bool Player::EnchantmentFitsRequirements(uint32 enchantmentcondition, int8 slot)
}
}
- TC_LOG_DEBUG("entities.player.items", "Checking Condition %u, there are %u Meta Gems, %u Red Gems, %u Yellow Gems and %u Blue Gems, Activate:%s", enchantmentcondition, curcount[0], curcount[1], curcount[2], curcount[3], activate ? "yes" : "no");
+ TC_LOG_DEBUG("entities.player.items", "Player::EnchantmentFitsRequirements: Checking Condition %u, there are %u Meta Gems, %u Red Gems, %u Yellow Gems and %u Blue Gems, Activate:%s",
+ enchantmentcondition, curcount[0], curcount[1], curcount[2], curcount[3], activate ? "yes" : "no");
return activate;
}
@@ -21771,7 +21828,7 @@ void Player::SetBattlegroundEntryPoint()
if (const WorldSafeLocsEntry* entry = sObjectMgr->GetClosestGraveYard(GetPositionX(), GetPositionY(), GetPositionZ(), GetMapId(), GetTeam()))
m_bgData.joinPos = WorldLocation(entry->map_id, entry->x, entry->y, entry->z, 0.0f);
else
- TC_LOG_ERROR("entities.player", "SetBattlegroundEntryPoint: Dungeon map %u has no linked graveyard, setting home location as entry point.", GetMapId());
+ TC_LOG_ERROR("entities.player", "Player::SetBattlegroundEntryPoint: Dungeon (MapID: %u) has no linked graveyard, setting home location as entry point.", GetMapId());
}
// If new entry point is not BG or arena set it
else if (!GetMap()->IsBattlegroundOrArena())
@@ -21982,7 +22039,7 @@ template<>
inline void BeforeVisibilityDestroy<Creature>(Creature* t, Player* p)
{
if (p->GetPetGUID() == t->GetGUID() && t->IsPet())
- ((Pet*)t)->Remove(PET_SAVE_NOT_IN_SLOT, true);
+ t->ToPet()->Remove(PET_SAVE_NOT_IN_SLOT, true);
}
void Player::UpdateVisibilityOf(WorldObject* target)
@@ -22016,7 +22073,7 @@ void Player::UpdateVisibilityOf(WorldObject* target)
// target aura duration for caster show only if target exist at caster client
// send data at target visibility change (adding to client)
if (target->isType(TYPEMASK_UNIT))
- SendInitialVisiblePackets((Unit*)target);
+ SendInitialVisiblePackets(static_cast<Unit*>(target));
}
}
}
@@ -22063,7 +22120,7 @@ void Player::UpdateTriggerVisibility()
GetSession()->SendPacket(&packet);
}
-void Player::SendInitialVisiblePackets(Unit* target)
+void Player::SendInitialVisiblePackets(Unit* target) const
{
SendAurasForTarget(target);
if (target->IsAlive())
@@ -22152,7 +22209,7 @@ bool Player::ModifyMoney(int32 amount, bool sendError /*= true*/)
sScriptMgr->OnPlayerMoneyLimit(this, amount);
if (sendError)
- SendEquipError(EQUIP_ERR_TOO_MUCH_GOLD, NULL, NULL);
+ SendEquipError(EQUIP_ERR_TOO_MUCH_GOLD, nullptr, nullptr);
return false;
}
}
@@ -22183,14 +22240,14 @@ Unit* Player::GetSelectedUnit() const
{
if (ObjectGuid selectionGUID = GetTarget())
return ObjectAccessor::GetUnit(*this, selectionGUID);
- return NULL;
+ return nullptr;
}
Player* Player::GetSelectedPlayer() const
{
if (ObjectGuid selectionGUID = GetTarget())
return ObjectAccessor::GetPlayer(*this, selectionGUID);
- return NULL;
+ return nullptr;
}
void Player::SendComboPoints()
@@ -22281,7 +22338,7 @@ void Player::ClearComboPoints()
void Player::SetGroup(Group* group, int8 subgroup)
{
- if (group == NULL)
+ if (group == nullptr)
m_group.unlink();
else
{
@@ -22421,7 +22478,7 @@ void Player::SendUpdateToOutOfRangeGroupMembers()
pet->ResetAuraUpdateMaskForRaid();
}
-void Player::SendTransferAborted(uint32 mapid, TransferAbortReason reason, uint8 arg)
+void Player::SendTransferAborted(uint32 mapid, TransferAbortReason reason, uint8 arg) const
{
WorldPacket data(SMSG_TRANSFER_ABORTED, 4+2);
data << uint32(mapid);
@@ -22440,7 +22497,7 @@ void Player::SendTransferAborted(uint32 mapid, TransferAbortReason reason, uint8
GetSession()->SendPacket(&data);
}
-void Player::SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time, bool welcome)
+void Player::SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time, bool welcome) const
{
// type of warning, based on the time remaining until reset
uint32 type;
@@ -22564,7 +22621,8 @@ void Player::LearnCustomSpells()
for (PlayerCreateInfoSpells::const_iterator itr = info->customSpells.begin(); itr != info->customSpells.end(); ++itr)
{
uint32 tspell = *itr;
- TC_LOG_DEBUG("entities.player.loading", "PLAYER (Class: %u Race: %u): Adding initial spell, id = %u", uint32(getClass()), uint32(getRace()), tspell);
+ TC_LOG_DEBUG("entities.player.loading", "Player::LearnCustomSpells: Player '%s' (%s, Class: %u Race: %u): Adding initial spell (SpellID: %u)",
+ GetName().c_str(), GetGUID().ToString().c_str(), 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
@@ -22736,7 +22794,7 @@ void Player::LearnSkillRewardedSpells(uint32 skillId, uint32 skillValue)
}
}
-void Player::SendAurasForTarget(Unit* target)
+void Player::SendAurasForTarget(Unit* target) const
{
if (!target || target->GetVisibleAuras()->empty()) // speedup things
return;
@@ -22777,7 +22835,7 @@ void Player::SetDailyQuestStatus(uint32 quest_id)
if (!GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx))
{
SetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx, quest_id);
- m_lastDailyQuestTime = time(NULL); // last daily quest time
+ m_lastDailyQuestTime = time(nullptr); // last daily quest time
m_DailyQuestChanged = true;
break;
}
@@ -22785,7 +22843,7 @@ void Player::SetDailyQuestStatus(uint32 quest_id)
} else
{
m_DFQuests.insert(quest_id);
- m_lastDailyQuestTime = time(NULL);
+ m_lastDailyQuestTime = time(nullptr);
m_DailyQuestChanged = true;
}
}
@@ -22858,7 +22916,7 @@ void Player::ResetMonthlyQuestStatus()
Battleground* Player::GetBattleground() const
{
if (GetBattlegroundId() == 0)
- return NULL;
+ return nullptr;
return sBattlegroundMgr->GetBattleground(GetBattlegroundId(), m_bgData.bgTypeID);
}
@@ -22917,7 +22975,7 @@ uint32 Player::AddBattlegroundQueueId(BattlegroundQueueTypeId val)
return PLAYER_MAX_BATTLEGROUND_QUEUES;
}
-bool Player::HasFreeBattlegroundQueueId()
+bool Player::HasFreeBattlegroundQueueId() const
{
for (uint8 i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
if (m_bgBattlegroundQueueID[i].bgQueueTypeId == BATTLEGROUND_QUEUE_NONE)
@@ -23105,7 +23163,7 @@ void Player::UpdateForQuestWorldObjects()
void Player::SetSummonPoint(uint32 mapid, float x, float y, float z)
{
- m_summon_expire = time(NULL) + MAX_PLAYER_SUMMON_DELAY;
+ m_summon_expire = time(nullptr) + MAX_PLAYER_SUMMON_DELAY;
m_summon_mapid = mapid;
m_summon_x = x;
m_summon_y = y;
@@ -23121,7 +23179,7 @@ void Player::SummonIfPossible(bool agree)
}
// expire and auto declined
- if (m_summon_expire < time(NULL))
+ if (m_summon_expire < time(nullptr))
return;
// stop taxi flight at summon
@@ -23242,7 +23300,7 @@ bool Player::HasItemFitToSpellRequirements(SpellInfo const* spellInfo, Item cons
break;
}
default:
- TC_LOG_ERROR("entities.player", "HasItemFitToSpellRequirements: Not handled spell requirement for item class %u", spellInfo->EquippedItemClass);
+ TC_LOG_ERROR("entities.player", "Player::HasItemFitToSpellRequirements: Not handled spell requirement for item class %u", spellInfo->EquippedItemClass);
break;
}
@@ -23368,7 +23426,7 @@ bool Player::GetsRecruitAFriendBonus(bool forXP)
{
if (Group* group = this->GetGroup())
{
- for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
+ for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
{
Player* player = itr->GetSource();
if (!player)
@@ -23417,7 +23475,7 @@ void Player::RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject* pRewar
// prepare data for near group iteration
if (Group* group = GetGroup())
{
- for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
+ for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
{
Player* player = itr->GetSource();
if (!player)
@@ -23483,8 +23541,14 @@ void Player::ResurrectUsingRequestData()
{
RemoveGhoul();
+ if (uint32 aura = _resurrectionData->Aura)
+ {
+ CastSpell(this, aura, true, nullptr, nullptr, _resurrectionData->GUID);
+ return;
+ }
+
/// Teleport before resurrecting by player, otherwise the player might get attacked from creatures near his corpse
- TeleportTo(m_resurrectMap, m_resurrectX, m_resurrectY, m_resurrectZ, GetOrientation());
+ TeleportTo(_resurrectionData->Location);
if (IsBeingTeleported())
{
@@ -23492,15 +23556,20 @@ void Player::ResurrectUsingRequestData()
return;
}
+ ResurrectUsingRequestDataImpl();
+}
+
+void Player::ResurrectUsingRequestDataImpl()
+{
ResurrectPlayer(0.0f, false);
- if (GetMaxHealth() > m_resurrectHealth)
- SetHealth(m_resurrectHealth);
+ if (GetMaxHealth() > _resurrectionData->Health)
+ SetHealth(_resurrectionData->Health);
else
SetFullHealth();
- if (GetMaxPower(POWER_MANA) > m_resurrectMana)
- SetPower(POWER_MANA, m_resurrectMana);
+ if (GetMaxPower(POWER_MANA) > _resurrectionData->Mana)
+ SetPower(POWER_MANA, _resurrectionData->Mana);
else
SetPower(POWER_MANA, GetMaxPower(POWER_MANA));
@@ -23527,7 +23596,7 @@ void Player::SetClientControl(Unit* target, bool allowMove)
void Player::SetMover(Unit* target)
{
- m_mover->m_movedPlayer = NULL;
+ m_mover->m_movedPlayer = nullptr;
m_mover = target;
m_mover->m_movedPlayer = this;
}
@@ -23572,7 +23641,7 @@ uint32 Player::GetCorpseReclaimDelay(bool pvp) const
else if (!sWorld->getBoolConfig(CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVE))
return 0;
- time_t now = time(NULL);
+ time_t now = time(nullptr);
// 0..2 full period
// should be ceil(x)-1 but not floor(x)
uint64 count = (now < m_deathExpireTime - 1) ? (m_deathExpireTime - 1 - now) / DEATH_EXPIRE_STEP : 0;
@@ -23587,7 +23656,7 @@ void Player::UpdateCorpseReclaimDelay()
(!pvp && !sWorld->getBoolConfig(CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVE)))
return;
- time_t now = time(NULL);
+ time_t now = time(nullptr);
if (now < m_deathExpireTime)
{
@@ -23603,7 +23672,7 @@ void Player::UpdateCorpseReclaimDelay()
m_deathExpireTime = now + DEATH_EXPIRE_STEP;
}
-int32 Player::CalculateCorpseReclaimDelay(bool load)
+int32 Player::CalculateCorpseReclaimDelay(bool load) const
{
Corpse* corpse = GetCorpse();
@@ -23631,7 +23700,7 @@ int32 Player::CalculateCorpseReclaimDelay(bool load)
}
time_t expected_time = corpse->GetGhostTime() + copseReclaimDelay[count];
- time_t now = time(NULL);
+ time_t now = time(nullptr);
if (now >= expected_time)
return -1;
@@ -23644,7 +23713,7 @@ int32 Player::CalculateCorpseReclaimDelay(bool load)
return delay * IN_MILLISECONDS;
}
-void Player::SendCorpseReclaimDelay(uint32 delay)
+void Player::SendCorpseReclaimDelay(uint32 delay) const
{
WorldPacket data(SMSG_CORPSE_RECLAIM_DELAY, 4);
data << uint32(delay);
@@ -23655,12 +23724,12 @@ Player* Player::GetNextRandomRaidMember(float radius)
{
Group* group = GetGroup();
if (!group)
- return NULL;
+ return nullptr;
std::vector<Player*> nearMembers;
nearMembers.reserve(group->GetMembersCount());
- for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
+ for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
{
Player* Target = itr->GetSource();
@@ -23671,7 +23740,7 @@ Player* Player::GetNextRandomRaidMember(float radius)
}
if (nearMembers.empty())
- return NULL;
+ return nullptr;
uint32 randTarget = urand(0, nearMembers.size()-1);
return nearMembers[randTarget];
@@ -23703,7 +23772,7 @@ PartyResult Player::CanUninviteFromGroup(ObjectGuid guidMember) const
return ERR_PARTY_LFG_BOOT_LOOT_ROLLS;
/// @todo Should also be sent when anyone has recently left combat, with an aprox ~5 seconds timer.
- for (GroupReference const* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
+ for (GroupReference const* itr = grp->GetFirstMember(); itr != nullptr; itr = itr->next())
if (itr->GetSource() && itr->GetSource()->IsInCombat())
return ERR_PARTY_LFG_BOOT_IN_COMBAT;
@@ -23727,12 +23796,12 @@ PartyResult Player::CanUninviteFromGroup(ObjectGuid guidMember) const
return ERR_PARTY_RESULT_OK;
}
-bool Player::isUsingLfg()
+bool Player::isUsingLfg() const
{
return sLFGMgr->GetState(GetGUID()) != lfg::LFG_STATE_NONE;
}
-bool Player::inRandomLfgDungeon()
+bool Player::inRandomLfgDungeon() const
{
if (sLFGMgr->selectedRandomLfgDungeon(GetGUID()))
{
@@ -23762,12 +23831,12 @@ void Player::RemoveFromBattlegroundOrBattlefieldRaid()
m_group.link(group, this);
m_group.setSubGroup(GetOriginalSubGroup());
}
- SetOriginalGroup(NULL);
+ SetOriginalGroup(nullptr);
}
void Player::SetOriginalGroup(Group* group, int8 subgroup)
{
- if (group == NULL)
+ if (group == nullptr)
m_originalGroup.unlink();
else
{
@@ -23788,7 +23857,7 @@ void Player::UpdateUnderwaterState(Map* m, float x, float y, float z)
if (_lastLiquid && _lastLiquid->SpellId)
RemoveAurasDueToSpell(_lastLiquid->SpellId);
- _lastLiquid = NULL;
+ _lastLiquid = nullptr;
return;
}
@@ -23814,7 +23883,7 @@ void Player::UpdateUnderwaterState(Map* m, float x, float y, float z)
else if (_lastLiquid && _lastLiquid->SpellId)
{
RemoveAurasDueToSpell(_lastLiquid->SpellId);
- _lastLiquid = NULL;
+ _lastLiquid = nullptr;
}
@@ -23869,7 +23938,7 @@ void Player::SetCanBlock(bool value)
UpdateBlockPercentage();
}
-bool ItemPosCount::isContainedIn(ItemPosCountVec const& vec) const
+bool ItemPosCount::isContainedIn(std::vector<ItemPosCount> const& vec) const
{
for (ItemPosCountVec::const_iterator itr = vec.begin(); itr != vec.end(); ++itr)
if (itr->pos == pos)
@@ -23877,15 +23946,15 @@ bool ItemPosCount::isContainedIn(ItemPosCountVec const& vec) const
return false;
}
-void Player::StopCastingBindSight()
+void Player::StopCastingBindSight() const
{
if (WorldObject* target = GetViewpoint())
{
if (target->isType(TYPEMASK_UNIT))
{
- ((Unit*)target)->RemoveAurasByType(SPELL_AURA_BIND_SIGHT, GetGUID());
- ((Unit*)target)->RemoveAurasByType(SPELL_AURA_MOD_POSSESS, GetGUID());
- ((Unit*)target)->RemoveAurasByType(SPELL_AURA_MOD_POSSESS_PET, GetGUID());
+ static_cast<Unit*>(target)->RemoveAurasByType(SPELL_AURA_BIND_SIGHT, GetGUID());
+ static_cast<Unit*>(target)->RemoveAurasByType(SPELL_AURA_MOD_POSSESS, GetGUID());
+ static_cast<Unit*>(target)->RemoveAurasByType(SPELL_AURA_MOD_POSSESS_PET, GetGUID());
}
}
}
@@ -23894,11 +23963,12 @@ void Player::SetViewpoint(WorldObject* target, bool apply)
{
if (apply)
{
- TC_LOG_DEBUG("maps", "Player::CreateViewpoint: Player %s create seer %u (TypeId: %u).", GetName().c_str(), target->GetEntry(), target->GetTypeId());
+ TC_LOG_DEBUG("maps", "Player::CreateViewpoint: Player '%s' (%s) creates seer (Entry: %u, TypeId: %u).",
+ GetName().c_str(), GetGUID().ToString().c_str(), target->GetEntry(), target->GetTypeId());
if (!AddGuidValue(PLAYER_FARSIGHT, target->GetGUID()))
{
- TC_LOG_FATAL("entities.player", "Player::CreateViewpoint: Player %s cannot add new viewpoint!", GetName().c_str());
+ TC_LOG_FATAL("entities.player", "Player::CreateViewpoint: Player '%s' (%s) cannot add new viewpoint!", GetName().c_str(), GetGUID().ToString().c_str());
return;
}
@@ -23906,20 +23976,20 @@ void Player::SetViewpoint(WorldObject* target, bool apply)
UpdateVisibilityOf(target);
if (target->isType(TYPEMASK_UNIT) && target != GetVehicleBase())
- ((Unit*)target)->AddPlayerToVision(this);
+ static_cast<Unit*>(target)->AddPlayerToVision(this);
}
else
{
- TC_LOG_DEBUG("maps", "Player::CreateViewpoint: Player %s remove seer", GetName().c_str());
+ TC_LOG_DEBUG("maps", "Player::CreateViewpoint: Player %s removed seer", GetName().c_str());
if (!RemoveGuidValue(PLAYER_FARSIGHT, target->GetGUID()))
{
- TC_LOG_FATAL("entities.player", "Player::CreateViewpoint: Player %s cannot remove current viewpoint!", GetName().c_str());
+ TC_LOG_FATAL("entities.player", "Player::CreateViewpoint: Player '%s' (%s) cannot remove current viewpoint!", GetName().c_str(), GetGUID().ToString().c_str());
return;
}
if (target->isType(TYPEMASK_UNIT) && target != GetVehicleBase())
- ((Unit*)target)->RemovePlayerFromVision(this);
+ static_cast<Unit*>(target)->RemovePlayerFromVision(this);
//must immediately set seer back otherwise may crash
m_seer = this;
@@ -23957,11 +24027,11 @@ void Player::SetViewpoint(WorldObject* target, bool apply)
WorldObject* Player::GetViewpoint() const
{
if (ObjectGuid guid = GetGuidValue(PLAYER_FARSIGHT))
- return (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*this, guid, TYPEMASK_SEER);
- return NULL;
+ return static_cast<WorldObject*>(ObjectAccessor::GetObjectByTypeMask(*this, guid, TYPEMASK_SEER));
+ return nullptr;
}
-bool Player::CanUseBattlegroundObject(GameObject* gameobject)
+bool Player::CanUseBattlegroundObject(GameObject* gameobject) const
{
// It is possible to call this method with a null pointer, only skipping faction check.
if (gameobject)
@@ -23980,14 +24050,14 @@ bool Player::CanUseBattlegroundObject(GameObject* gameobject)
IsAlive()); // Alive
}
-bool Player::CanCaptureTowerPoint()
+bool Player::CanCaptureTowerPoint() const
{
return (!HasStealthAura() && // not stealthed
!HasInvisibilityAura() && // not invisible
IsAlive()); // live player
}
-uint32 Player::GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair, BarberShopStyleEntry const* newSkin)
+uint32 Player::GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair, BarberShopStyleEntry const* newSkin) const
{
uint8 level = getLevel();
@@ -24055,7 +24125,7 @@ void Player::SetGlyph(uint8 slot, uint32 glyph)
SetUInt32Value(PLAYER_FIELD_GLYPHS_1 + slot, glyph);
}
-bool Player::isTotalImmune()
+bool Player::isTotalImmune() const
{
AuraEffectList const& immune = GetAuraEffectsByType(SPELL_AURA_SCHOOL_IMMUNITY);
@@ -24105,7 +24175,7 @@ void Player::SetTitle(CharTitlesEntry const* title, bool lost)
GetSession()->SendPacket(&data);
}
-bool Player::isTotalImmunity()
+bool Player::isTotalImmunity() const
{
AuraEffectList const& immune = GetAuraEffectsByType(SPELL_AURA_SCHOOL_IMMUNITY);
@@ -24129,38 +24199,6 @@ bool Player::isTotalImmunity()
return false;
}
-void Player::UpdateCharmedAI()
-{
- //This should only called in Player::Update
- Creature* charmer = GetCharmer()->ToCreature();
-
- //kill self if charm aura has infinite duration
- if (charmer->IsInEvadeMode())
- {
- AuraEffectList const& auras = GetAuraEffectsByType(SPELL_AURA_MOD_CHARM);
- for (AuraEffectList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter)
- if ((*iter)->GetCasterGUID() == charmer->GetGUID() && (*iter)->GetBase()->IsPermanent())
- {
- charmer->DealDamage(this, GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
- return;
- }
- }
-
- if (!charmer->IsInCombat())
- GetMotionMaster()->MoveFollow(charmer, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
-
- Unit* target = GetVictim();
- if (!target || !charmer->IsValidAttackTarget(target))
- {
- target = charmer->SelectNearestTarget();
- if (!target)
- return;
-
- GetMotionMaster()->MoveChase(target);
- Attack(target, true);
- }
-}
-
uint32 Player::GetRuneBaseCooldown(uint8 index)
{
uint8 rune = GetBaseRune(index);
@@ -24213,7 +24251,7 @@ void Player::RemoveRunesByAuraEffect(AuraEffect const* aura)
if (m_runes->runes[i].ConvertAura == aura)
{
ConvertRune(i, GetBaseRune(i));
- SetRuneConvertAura(i, NULL);
+ SetRuneConvertAura(i, nullptr);
}
}
}
@@ -24221,11 +24259,11 @@ void Player::RemoveRunesByAuraEffect(AuraEffect const* aura)
void Player::RestoreBaseRune(uint8 index)
{
AuraEffect const* aura = m_runes->runes[index].ConvertAura;
- // If rune was converted by a non-pasive aura that still active we should keep it converted
+ // If rune was converted by a non-passive aura that still active we should keep it converted
if (aura && !aura->GetSpellInfo()->HasAttribute(SPELL_ATTR0_PASSIVE))
return;
ConvertRune(index, GetBaseRune(index));
- SetRuneConvertAura(index, NULL);
+ SetRuneConvertAura(index, nullptr);
// Don't drop passive talents providing rune convertion
if (!aura || aura->GetAuraType() != SPELL_AURA_CONVERT_RUNE)
return;
@@ -24247,7 +24285,7 @@ void Player::ConvertRune(uint8 index, RuneType newType)
GetSession()->SendPacket(&data);
}
-void Player::ResyncRunes(uint8 count)
+void Player::ResyncRunes(uint8 count) const
{
WorldPacket data(SMSG_RESYNC_RUNES, 4 + count * 2);
data << uint32(count);
@@ -24259,7 +24297,7 @@ void Player::ResyncRunes(uint8 count)
GetSession()->SendPacket(&data);
}
-void Player::AddRunePower(uint8 index)
+void Player::AddRunePower(uint8 index) const
{
WorldPacket data(SMSG_ADD_RUNE_POWER, 4);
data << uint32(1 << index); // mask (0x00-0x3F probably)
@@ -24293,7 +24331,7 @@ void Player::InitRunes()
SetRuneCooldown(i, 0); // reset cooldowns
SetRuneTimer(i, 0xFFFFFFFF); // Reset rune flags
SetLastRuneGraceTimer(i, 0);
- SetRuneConvertAura(i, NULL);
+ SetRuneConvertAura(i, nullptr);
m_runes->SetRuneState(i);
}
@@ -24328,7 +24366,7 @@ void Player::AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore cons
msg = CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, lootItem->itemid, lootItem->count);
if (msg != EQUIP_ERR_OK)
{
- SendEquipError(msg, NULL, NULL, lootItem->itemid);
+ SendEquipError(msg, nullptr, nullptr, lootItem->itemid);
continue;
}
@@ -24339,15 +24377,15 @@ void Player::AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore cons
void Player::StoreLootItem(uint8 lootSlot, Loot* loot)
{
- QuestItem* qitem = NULL;
- QuestItem* ffaitem = NULL;
- QuestItem* conditem = NULL;
+ QuestItem* qitem = nullptr;
+ QuestItem* ffaitem = nullptr;
+ QuestItem* conditem = nullptr;
LootItem* item = loot->LootItemInSlot(lootSlot, this, &qitem, &ffaitem, &conditem);
if (!item)
{
- SendEquipError(EQUIP_ERR_ALREADY_LOOTED, NULL, NULL);
+ SendEquipError(EQUIP_ERR_ALREADY_LOOTED, nullptr, nullptr);
return;
}
@@ -24414,7 +24452,7 @@ void Player::StoreLootItem(uint8 lootSlot, Loot* loot)
}
else
- SendEquipError(msg, NULL, NULL, item->itemid);
+ SendEquipError(msg, nullptr, nullptr, item->itemid);
}
uint32 Player::CalculateTalentsPoints() const
@@ -24467,8 +24505,8 @@ void Player::_LoadSkills(PreparedQueryResult result)
SkillRaceClassInfoEntry const* rcEntry = GetSkillRaceClassInfo(skill, getRace(), getClass());
if (!rcEntry)
{
- TC_LOG_ERROR("entities.player", "Character: %s (GUID: %u Race: %u Class: %u) has skill %u not allowed for his race/class combination",
- GetName().c_str(), GetGUID().GetCounter(), uint32(getRace()), uint32(getClass()), skill);
+ TC_LOG_ERROR("entities.player", "Player::_LoadSkills: Player '%s' (%s, Race: %u, Class: %u) has forbidden skill %u for his race/class combination",
+ GetName().c_str(), GetGUID().ToString().c_str(), uint32(getRace()), uint32(getClass()), skill);
mSkillStatus.insert(SkillStatusMap::value_type(skill, SkillStatusData(0, SKILL_DELETED)));
continue;
@@ -24491,7 +24529,8 @@ void Player::_LoadSkills(PreparedQueryResult result)
if (value == 0)
{
- TC_LOG_ERROR("entities.player", "Character %u has skill %u with value 0. Will be deleted.", GetGUID().GetCounter(), skill);
+ TC_LOG_ERROR("entities.player", "Player::_LoadSkills: Player '%s' (%s) has skill %u with value 0, deleted.",
+ GetName().c_str(), GetGUID().ToString().c_str(), skill);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHARACTER_SKILL);
@@ -24528,7 +24567,8 @@ void Player::_LoadSkills(PreparedQueryResult result)
if (count >= PLAYER_MAX_SKILLS) // client limit
{
- TC_LOG_ERROR("entities.player", "Character %u has more than %u skills.", GetGUID().GetCounter(), PLAYER_MAX_SKILLS);
+ TC_LOG_ERROR("entities.player", "Player::_LoadSkills: Player '%s' (%s) has more than %u skills.",
+ GetName().c_str(), GetGUID().ToString().c_str(), PLAYER_MAX_SKILLS);
break;
}
}
@@ -24795,30 +24835,13 @@ void Player::LearnTalent(uint32 talentId, uint32 talentRank)
uint32 tTab = talentInfo->TalentTab;
if (talentInfo->Row > 0)
- {
- uint32 numRows = sTalentStore.GetNumRows();
- for (uint32 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
- {
+ for (uint32 i = 0; i < sTalentStore.GetNumRows(); i++) // Loop through all talents.
+ if (const TalentEntry* tmpTalent = sTalentStore.LookupEntry(i)) // the way talents are tracked
if (tmpTalent->TalentTab == tTab)
- {
for (uint8 rank = 0; rank < MAX_TALENT_RANK; rank++)
- {
if (tmpTalent->RankID[rank] != 0)
- {
if (HasSpell(tmpTalent->RankID[rank]))
- {
spentPoints += (rank + 1);
- }
- }
- }
- }
- }
- }
- }
// not have required min points spent in talent tree
if (spentPoints < (talentInfo->Row * MAX_TALENT_RANK))
@@ -24828,7 +24851,7 @@ void Player::LearnTalent(uint32 talentId, uint32 talentRank)
uint32 spellid = talentInfo->RankID[talentRank];
if (spellid == 0)
{
- TC_LOG_ERROR("entities.player", "Talent.dbc have for talent: %u Rank: %u spell id = 0", talentId, talentRank);
+ TC_LOG_ERROR("entities.player", "Player::LearnTalent: Talent.dbc has no spellInfo for talent: %u (spell id = 0)", talentId);
return;
}
@@ -24840,7 +24863,7 @@ void Player::LearnTalent(uint32 talentId, uint32 talentRank)
LearnSpell(spellid, false);
AddTalent(spellid, m_activeSpec, true);
- TC_LOG_DEBUG("entities.player", "TalentID: %u Rank: %u Spell: %u Spec: %u\n", talentId, talentRank, spellid, m_activeSpec);
+ TC_LOG_DEBUG("misc", "Player::LearnTalent: TalentID: %u Spell: %u Group: %u\n", talentId, spellid, uint32(m_activeSpec));
// update free talent points
SetFreeTalentPoints(CurTalentPoints - (talentRank - curtalent_maxrank + 1));
@@ -24965,7 +24988,7 @@ void Player::LearnPetTalent(ObjectGuid petGuid, uint32 talentId, uint32 talentRa
uint32 spellid = talentInfo->RankID[talentRank];
if (spellid == 0)
{
- TC_LOG_ERROR("entities.player", "Talent.dbc have for talent: %u Rank: %u spell id = 0", talentId, talentRank);
+ TC_LOG_ERROR("entities.player", "Talent.dbc contains talent: %u Rank: %u spell id = 0", talentId, talentRank);
return;
}
@@ -25292,7 +25315,8 @@ void Player::SetEquipmentSet(uint32 index, EquipmentSet eqset)
if (!found) // something wrong...
{
- TC_LOG_ERROR("entities.player", "Player %s tried to save equipment set " UI64FMTD " (index %u), but that equipment set not found!", GetName().c_str(), eqset.Guid, index);
+ TC_LOG_ERROR("entities.player", "Player::SetEquipmentSet: Player '%s' (%s) tried to save nonexistent equipment set " UI64FMTD " (index: %u)",
+ GetName().c_str(), GetGUID().ToString().c_str(), eqset.Guid, index);
return;
}
}
@@ -25322,7 +25346,7 @@ void Player::_SaveEquipmentSets(SQLTransaction& trans)
{
uint32 index = itr->first;
EquipmentSet& eqset = itr->second;
- PreparedStatement* stmt = NULL;
+ PreparedStatement* stmt = nullptr;
uint8 j = 0;
switch (eqset.state)
{
@@ -25460,7 +25484,7 @@ void Player::_LoadGlyphs(PreparedQueryResult result)
while (result->NextRow());
}
-void Player::_SaveGlyphs(SQLTransaction& trans)
+void Player::_SaveGlyphs(SQLTransaction& trans) const
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_GLYPHS);
stmt->setUInt32(0, GetGUID().GetCounter());
@@ -25544,7 +25568,7 @@ void Player::UpdateSpecCount(uint8 count)
ActivateSpec(0);
SQLTransaction trans = CharacterDatabase.BeginTransaction();
- PreparedStatement* stmt = NULL;
+ PreparedStatement* stmt;
// Copy spec data
if (count > curCount)
@@ -25635,7 +25659,7 @@ void Player::ActivateSpec(uint8 spec)
for (int8 rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
{
- // skip non-existant talent ranks
+ // skip non-existing talent ranks
if (talentInfo->RankID[rank] == 0)
continue;
RemoveSpell(talentInfo->RankID[rank], true); // removes the talent, and all dependant, learned, and chained spells..
@@ -25679,7 +25703,7 @@ void Player::ActivateSpec(uint8 spec)
// learn highest talent rank that exists in newly activated spec
for (int8 rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
{
- // skip non-existant talent ranks
+ // skip non-existing talent ranks
if (talentInfo->RankID[rank] == 0)
continue;
// if the talent can be found in the newly activated PlayerTalentMap
@@ -25752,7 +25776,7 @@ uint32 Player::GetReputation(uint32 factionentry) const
return GetReputationMgr().GetReputation(sFactionStore.LookupEntry(factionentry));
}
-std::string const& Player::GetGuildName()
+std::string const& Player::GetGuildName() const
{
return sGuildMgr->GetGuildById(GetGuildId())->GetName();
}
@@ -25960,7 +25984,7 @@ void Player::SendItemRetrievalMail(uint32 itemEntry, uint32 count)
MailDraft draft("Recovered Item", "We recovered a lost item in the twisting nether and noted that it was yours.$B$BPlease find said object enclosed."); // This is the text used in Cataclysm, it probably wasn't changed.
SQLTransaction trans = CharacterDatabase.BeginTransaction();
- if (Item* item = Item::CreateItem(itemEntry, count, 0))
+ if (Item* item = Item::CreateItem(itemEntry, count, nullptr))
{
item->SaveToDB(trans);
draft.AddItem(item);
@@ -25991,7 +26015,7 @@ void Player::_LoadRandomBGStatus(PreparedQueryResult result)
m_IsBGRandomWinner = true;
}
-float Player::GetAverageItemLevel()
+float Player::GetAverageItemLevel() const
{
float sum = 0;
uint32 count = 0;
@@ -26169,7 +26193,7 @@ float Player::GetCollisionHeight(bool mounted) const
}
}
-std::string Player::GetMapAreaAndZoneString()
+std::string Player::GetMapAreaAndZoneString() const
{
uint32 areaId = GetAreaId();
std::string areaName = "Unknown";
@@ -26187,7 +26211,7 @@ std::string Player::GetMapAreaAndZoneString()
return str.str();
}
-std::string Player::GetCoordsMapAreaAndZoneString()
+std::string Player::GetCoordsMapAreaAndZoneString() const
{
std::ostringstream str;
str << Position::ToString() << " " << GetMapAreaAndZoneString();
@@ -26222,31 +26246,31 @@ Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetTy
if (duration > 0)
pet->SetDuration(duration);
- return NULL;
+ return nullptr;
}
// petentry == 0 for hunter "call pet" (current pet summoned if any)
if (!entry)
{
delete pet;
- return NULL;
+ return nullptr;
}
pet->Relocate(x, y, z, ang);
if (!pet->IsPositionValid())
{
- TC_LOG_ERROR("misc", "Pet (guidlow %d, entry %d) not summoned. Suggested coordinates isn't valid (X: %f Y: %f)", pet->GetGUID().GetCounter(), pet->GetEntry(), pet->GetPositionX(), pet->GetPositionY());
+ TC_LOG_ERROR("misc", "Player::SummonPet: Pet (%s, Entry: %d) not summoned. Suggested coordinates aren't valid (X: %f Y: %f)", pet->GetGUID().ToString().c_str(), pet->GetEntry(), pet->GetPositionX(), pet->GetPositionY());
delete pet;
- return NULL;
+ return nullptr;
}
Map* map = GetMap();
uint32 pet_number = sObjectMgr->GeneratePetNumber();
if (!pet->Create(map->GenerateLowGuid<HighGuid::Pet>(), map, GetPhaseMask(), entry, pet_number))
{
- TC_LOG_ERROR("misc", "no such creature entry %u", entry);
+ TC_LOG_ERROR("misc", "Player::SummonPet: No such creature entry %u", entry);
delete pet;
- return NULL;
+ return nullptr;
}
pet->SetCreatorGUID(GetGUID());
@@ -26269,7 +26293,7 @@ Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetTy
pet->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, 1000);
pet->SetFullHealth();
pet->SetPower(POWER_MANA, pet->GetMaxPower(POWER_MANA));
- pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(NULL))); // cast can't be helped in this case
+ pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(nullptr))); // cast can't be helped in this case
break;
default:
break;
@@ -26313,7 +26337,7 @@ Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetTy
return pet;
}
-void Player::SendSupercededSpell(uint32 oldSpell, uint32 newSpell)
+void Player::SendSupercededSpell(uint32 oldSpell, uint32 newSpell) const
{
WorldPacket data(SMSG_SUPERCEDED_SPELL, 8);
data << uint32(oldSpell) << uint32(newSpell);
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 2388cf9d0c7..ced588d295f 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -54,6 +54,7 @@ class PlayerMenu;
class PlayerSocial;
class SpellCastTargets;
class UpdateMask;
+class PlayerAI;
struct CharacterCustomizeInfo;
@@ -116,7 +117,7 @@ struct PlayerTalent
// Spell modifier (used for modify other spells)
struct SpellModifier
{
- SpellModifier(Aura* _ownerAura = NULL) : op(SPELLMOD_DAMAGE), type(SPELLMOD_FLAT), charges(0), value(0), mask(), spellId(0), ownerAura(_ownerAura) { }
+ SpellModifier(Aura* _ownerAura = nullptr) : op(SPELLMOD_DAMAGE), type(SPELLMOD_FLAT), charges(0), value(0), mask(), spellId(0), ownerAura(_ownerAura) { }
SpellModOp op : 8;
SpellModType type : 8;
int16 charges : 16;
@@ -255,7 +256,7 @@ typedef std::list<PlayerCreateInfoSkill> PlayerCreateInfoSkills;
struct PlayerInfo
{
// existence checked by displayId != 0
- PlayerInfo() : mapId(0), areaId(0), positionX(0.0f), positionY(0.0f), positionZ(0.0f), orientation(0.0f), displayId_m(0), displayId_f(0), levelInfo(NULL) { }
+ PlayerInfo() : mapId(0), areaId(0), positionX(0.0f), positionY(0.0f), positionZ(0.0f), orientation(0.0f), displayId_m(0), displayId_f(0), levelInfo(nullptr) { }
uint32 mapId;
uint32 areaId;
@@ -286,7 +287,7 @@ struct PvPInfo
struct DuelInfo
{
- DuelInfo() : initiator(NULL), opponent(NULL), startTimer(0), startTime(0), outOfBound(0), isMounted(false) { }
+ DuelInfo() : initiator(nullptr), opponent(nullptr), startTimer(0), startTime(0), outOfBound(0), isMounted(false) { }
Player* initiator;
Player* opponent;
@@ -348,7 +349,7 @@ struct Runes
struct EnchantDuration
{
- EnchantDuration() : item(NULL), slot(MAX_ENCHANTMENT_SLOT), leftduration(0) { }
+ EnchantDuration() : item(nullptr), slot(MAX_ENCHANTMENT_SLOT), leftduration(0) { }
EnchantDuration(Item* _item, EnchantmentSlot _slot, uint32 _leftduration) : item(_item), slot(_slot),
leftduration(_leftduration){ ASSERT(item); }
@@ -832,7 +833,7 @@ enum PlayerDelayedOperations
// Player summoning auto-decline time (in secs)
#define MAX_PLAYER_SUMMON_DELAY (2*MINUTE)
// Maximum money amount : 2^31 - 1
-extern uint32 const MAX_MONEY_AMOUNT;
+TC_GAME_API extern uint32 const MAX_MONEY_AMOUNT;
enum BindExtensionState
{
@@ -854,7 +855,7 @@ struct InstancePlayerBind
EXTENDED - won't be promoted to EXPIRED at next reset period, will instead be promoted to NORMAL */
BindExtensionState extendState;
- InstancePlayerBind() : save(NULL), perm(false), extendState(EXTEND_STATE_NORMAL) { }
+ InstancePlayerBind() : save(nullptr), perm(false), extendState(EXTEND_STATE_NORMAL) { }
};
struct AccessRequirement
@@ -918,7 +919,7 @@ enum PlayerCommandStates
CHEAT_WATERWALK = 0x10
};
-class PlayerTaxi
+class TC_GAME_API PlayerTaxi
{
public:
PlayerTaxi();
@@ -1013,7 +1014,18 @@ struct TradeStatusInfo
uint8 Slot;
};
-class Player : public Unit, public GridObject<Player>
+struct ResurrectionData
+{
+ ObjectGuid GUID;
+ WorldLocation Location;
+ uint32 Health;
+ uint32 Mana;
+ uint32 Aura;
+};
+
+#define SPELL_DK_RAISE_ALLY 46619
+
+class TC_GAME_API Player : public Unit, public GridObject<Player>
{
friend class WorldSession;
friend void Item::AddToUpdateQueueOf(Player* player);
@@ -1022,6 +1034,8 @@ class Player : public Unit, public GridObject<Player>
explicit Player(WorldSession* session);
~Player();
+ PlayerAI* AI() const { return reinterpret_cast<PlayerAI*>(i_AI); }
+
void CleanupsBeforeDelete(bool finalCleanup = true) override;
void AddToWorld() override;
@@ -1058,12 +1072,12 @@ class Player : public Unit, public GridObject<Player>
void SendInitialPacketsBeforeAddToMap();
void SendInitialPacketsAfterAddToMap();
- void SendSupercededSpell(uint32 oldSpell, uint32 newSpell);
- void SendTransferAborted(uint32 mapid, TransferAbortReason reason, uint8 arg = 0);
- void SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time, bool welcome);
+ void SendSupercededSpell(uint32 oldSpell, uint32 newSpell) const;
+ void SendTransferAborted(uint32 mapid, TransferAbortReason reason, uint8 arg = 0) const;
+ void SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time, bool welcome) const;
- bool CanInteractWithQuestGiver(Object* questGiver);
- Creature* GetNPCIfCanInteractWith(ObjectGuid const& guid, uint32 npcflagmask);
+ bool CanInteractWithQuestGiver(Object* questGiver) const;
+ Creature* GetNPCIfCanInteractWith(ObjectGuid const& guid, uint32 npcflagmask) const;
GameObject* GetGameObjectIfCanInteractWith(ObjectGuid const& guid) const;
GameObject* GetGameObjectIfCanInteractWith(ObjectGuid const& guid, GameobjectTypes type) const;
@@ -1074,16 +1088,16 @@ class Player : public Unit, public GridObject<Player>
uint8 GetChatTag() const;
std::string autoReplyMsg;
- uint32 GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair, BarberShopStyleEntry const* newSkin=NULL);
+ uint32 GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair, BarberShopStyleEntry const* newSkin = nullptr) const;
- PlayerSocial *GetSocial() { return m_social; }
+ PlayerSocial *GetSocial() const { return m_social; }
PlayerTaxi m_taxi;
void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(getRace(), getClass(), getLevel()); }
- bool ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc = NULL, uint32 spellid = 0);
+ bool ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc = nullptr, uint32 spellid = 0);
bool ActivateTaxiPathTo(uint32 taxi_path_id, uint32 spellid = 0);
void CleanupAfterTaxiFlight();
- void ContinueTaxiFlight();
+ void ContinueTaxiFlight() const;
// mount_id can be used in scripting calls
bool isAcceptWhispers() const { return (m_ExtraFlags & PLAYER_EXTRA_ACCEPT_WHISPERS) != 0; }
void SetAcceptWhispers(bool on) { if (on) m_ExtraFlags |= PLAYER_EXTRA_ACCEPT_WHISPERS; else m_ExtraFlags &= ~PLAYER_EXTRA_ACCEPT_WHISPERS; }
@@ -1150,8 +1164,8 @@ class Player : public Unit, public GridObject<Player>
void SetVirtualItemSlot(uint8 i, Item* item);
void SetSheath(SheathState sheathed) override; // overwrite Unit version
uint8 FindEquipSlot(ItemTemplate const* proto, uint32 slot, bool swap) const;
- uint32 GetItemCount(uint32 item, bool inBankAlso = false, Item* skipItem = NULL) const;
- uint32 GetItemCountWithLimitCategory(uint32 limitCategory, Item* skipItem = NULL) const;
+ uint32 GetItemCount(uint32 item, bool inBankAlso = false, Item* skipItem = nullptr) const;
+ uint32 GetItemCountWithLimitCategory(uint32 limitCategory, Item* skipItem = nullptr) const;
Item* GetItemByGuid(ObjectGuid guid) const;
Item* GetItemByEntry(uint32 entry) const;
Item* GetItemByPos(uint16 pos) const;
@@ -1169,18 +1183,18 @@ class Player : public Unit, public GridObject<Player>
static bool IsBagPos(uint16 pos);
static bool IsBankPos(uint16 pos) { return IsBankPos(pos >> 8, pos & 255); }
static bool IsBankPos(uint8 bag, uint8 slot);
- bool IsValidPos(uint16 pos, bool explicit_pos) { return IsValidPos(pos >> 8, pos & 255, explicit_pos); }
- bool IsValidPos(uint8 bag, uint8 slot, bool explicit_pos);
+ bool IsValidPos(uint16 pos, bool explicit_pos) const { return IsValidPos(pos >> 8, pos & 255, explicit_pos); }
+ bool IsValidPos(uint8 bag, uint8 slot, bool explicit_pos) const;
uint8 GetBankBagSlotCount() const { return GetByteValue(PLAYER_BYTES_2, 2); }
void SetBankBagSlotCount(uint8 count) { SetByteValue(PLAYER_BYTES_2, 2, count); }
bool HasItemCount(uint32 item, uint32 count = 1, bool inBankAlso = false) const;
- bool HasItemFitToSpellRequirements(SpellInfo const* spellInfo, Item const* ignoreItem = NULL) const;
+ bool HasItemFitToSpellRequirements(SpellInfo const* spellInfo, Item const* ignoreItem = nullptr) const;
bool CanNoReagentCast(SpellInfo const* spellInfo) const;
bool HasItemOrGemWithIdEquipped(uint32 item, uint32 count, uint8 except_slot = NULL_SLOT) const;
bool HasItemOrGemWithLimitCategoryEquipped(uint32 limitCategory, uint32 count, uint8 except_slot = NULL_SLOT) const;
InventoryResult CanTakeMoreSimilarItems(Item* pItem, uint32* itemLimitCategory = NULL) const { return CanTakeMoreSimilarItems(pItem->GetEntry(), pItem->GetCount(), pItem, NULL, itemLimitCategory); }
InventoryResult CanTakeMoreSimilarItems(uint32 entry, uint32 count, uint32* itemLimitCategory = NULL) const { return CanTakeMoreSimilarItems(entry, count, NULL, NULL, itemLimitCategory); }
- InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 item, uint32 count, uint32* no_space_count = NULL) const;
+ InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 item, uint32 count, uint32* no_space_count = nullptr) const;
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, Item* pItem, bool swap = false) const;
InventoryResult CanStoreItems(Item** items, int count, uint32* itemLimitCategory) const;
InventoryResult CanEquipNewItem(uint8 slot, uint16& dest, uint32 item, bool swap) const;
@@ -1207,7 +1221,7 @@ class Player : public Unit, public GridObject<Player>
void StoreLootItem(uint8 lootSlot, Loot* loot);
InventoryResult CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count = NULL, uint32* itemLimitCategory = NULL) const;
- InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 entry, uint32 count, Item* pItem = NULL, bool swap = false, uint32* no_space_count = NULL) const;
+ InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 entry, uint32 count, Item* pItem = nullptr, bool swap = false, uint32* no_space_count = nullptr) const;
void AddRefundReference(ObjectGuid it);
void DeleteRefundReference(ObjectGuid it);
@@ -1238,9 +1252,9 @@ class Player : public Unit, public GridObject<Player>
Item* GetItemFromBuyBackSlot(uint32 slot);
void RemoveItemFromBuyBackSlot(uint32 slot, bool del);
uint32 GetMaxKeyringSize() const { return KEYRING_SLOT_END-KEYRING_SLOT_START; }
- void SendEquipError(InventoryResult msg, Item* pItem, Item* pItem2 = NULL, uint32 itemid = 0);
- void SendBuyError(BuyResult msg, Creature* creature, uint32 item, uint32 param);
- void SendSellError(SellResult msg, Creature* creature, ObjectGuid guid, uint32 param);
+ void SendEquipError(InventoryResult msg, Item* pItem, Item* pItem2 = nullptr, uint32 itemid = 0) const;
+ void SendBuyError(BuyResult msg, Creature* creature, uint32 item, uint32 param) const;
+ void SendSellError(SellResult msg, Creature* creature, ObjectGuid guid, uint32 param) const;
void AddWeaponProficiency(uint32 newflag) { m_WeaponProficiency |= newflag; }
void AddArmorProficiency(uint32 newflag) { m_ArmorProficiency |= newflag; }
uint32 GetWeaponProficiency() const { return m_WeaponProficiency; }
@@ -1302,10 +1316,10 @@ class Player : public Unit, public GridObject<Player>
void PrepareQuestMenu(ObjectGuid guid);
void SendPreparedQuest(ObjectGuid guid);
bool IsActiveQuest(uint32 quest_id) const;
- Quest const* GetNextQuest(ObjectGuid guid, Quest const* quest);
+ Quest const* GetNextQuest(ObjectGuid guid, Quest const* quest) const;
bool CanSeeStartQuest(Quest const* quest);
bool CanTakeQuest(Quest const* quest, bool msg);
- bool CanAddQuest(Quest const* quest, bool msg);
+ bool CanAddQuest(Quest const* quest, bool msg) const;
bool CanCompleteQuest(uint32 quest_id);
bool CanCompleteRepeatableQuest(Quest const* quest);
bool CanRewardQuest(Quest const* quest, bool msg);
@@ -1317,19 +1331,19 @@ class Player : public Unit, public GridObject<Player>
void RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, bool announce = true);
void FailQuest(uint32 quest_id);
bool SatisfyQuestSkill(Quest const* qInfo, bool msg) const;
- bool SatisfyQuestLevel(Quest const* qInfo, bool msg);
- bool SatisfyQuestLog(bool msg);
+ bool SatisfyQuestLevel(Quest const* qInfo, bool msg) const;
+ bool SatisfyQuestLog(bool msg) const;
bool SatisfyQuestPreviousQuest(Quest const* qInfo, bool msg);
bool SatisfyQuestClass(Quest const* qInfo, bool msg) const;
- bool SatisfyQuestRace(Quest const* qInfo, bool msg);
+ bool SatisfyQuestRace(Quest const* qInfo, bool msg) const;
bool SatisfyQuestReputation(Quest const* qInfo, bool msg);
- bool SatisfyQuestStatus(Quest const* qInfo, bool msg);
+ bool SatisfyQuestStatus(Quest const* qInfo, bool msg) const;
bool SatisfyQuestConditions(Quest const* qInfo, bool msg);
- bool SatisfyQuestTimed(Quest const* qInfo, bool msg);
+ bool SatisfyQuestTimed(Quest const* qInfo, bool msg) const;
bool SatisfyQuestExclusiveGroup(Quest const* qInfo, bool msg);
- bool SatisfyQuestNextChain(Quest const* qInfo, bool msg);
+ bool SatisfyQuestNextChain(Quest const* qInfo, bool msg) const;
bool SatisfyQuestPrevChain(Quest const* qInfo, bool msg);
- bool SatisfyQuestDay(Quest const* qInfo, bool msg);
+ bool SatisfyQuestDay(Quest const* qInfo, bool msg) const;
bool SatisfyQuestWeek(Quest const* qInfo, bool msg);
bool SatisfyQuestMonth(Quest const* qInfo, bool msg);
bool SatisfyQuestSeasonal(Quest const* qInfo, bool msg);
@@ -1364,7 +1378,7 @@ class Player : public Unit, public GridObject<Player>
void SetQuestSlotTimer(uint16 slot, uint32 timer);
void SwapQuestSlot(uint16 slot1, uint16 slot2);
- uint16 GetReqKillOrCastCurrentCount(uint32 quest_id, int32 entry);
+ uint16 GetReqKillOrCastCurrentCount(uint32 quest_id, int32 entry) const;
void AreaExploredOrEventHappens(uint32 questId);
void GroupEventHappens(uint32 questId, WorldObject const* pEventObject);
void ItemAddedQuestCheck(uint32 entry, uint32 count);
@@ -1382,14 +1396,14 @@ class Player : public Unit, public GridObject<Player>
void UpdateForQuestWorldObjects();
bool CanShareQuest(uint32 questId) const;
- void SendQuestComplete(uint32 questId);
- void SendQuestReward(Quest const* quest, uint32 XP);
- void SendQuestFailed(uint32 questId, InventoryResult reason = EQUIP_ERR_OK);
- void SendQuestTimerFailed(uint32 questId);
+ void SendQuestComplete(uint32 questId) const;
+ void SendQuestReward(Quest const* quest, uint32 XP) const;
+ void SendQuestFailed(uint32 questId, InventoryResult reason = EQUIP_ERR_OK) const;
+ void SendQuestTimerFailed(uint32 questId) const;
void SendCanTakeQuestResponse(QuestFailedReason msg) const;
- void SendQuestConfirmAccept(Quest const* quest, Player* pReceiver);
- void SendPushToPartyResponse(Player* player, uint8 msg);
- void SendQuestUpdateAddItem(Quest const* quest, uint32 itemIdx, uint16 count);
+ void SendQuestConfirmAccept(Quest const* quest, Player* pReceiver) const;
+ void SendPushToPartyResponse(Player* player, uint8 msg) const;
+ void SendQuestUpdateAddItem(Quest const* quest, uint32 itemIdx, uint16 count) const;
void SendQuestUpdateAddCreatureOrGo(Quest const* quest, ObjectGuid guid, uint32 creatureOrGOIdx, uint16 oldCount, uint16 addCount);
void SendQuestUpdateAddPlayer(Quest const* quest, uint16 oldCount, uint16 addCount);
@@ -1427,10 +1441,9 @@ class Player : public Unit, public GridObject<Player>
void SaveToDB(bool create = false);
void SaveInventoryAndGoldToDB(SQLTransaction& trans); // fast save function for item/money cheating preventing
- void SaveGoldToDB(SQLTransaction& trans);
+ void SaveGoldToDB(SQLTransaction& trans) const;
static void SetUInt32ValueInArray(Tokenizer& data, uint16 index, uint32 value);
- static void SetFloatValueInArray(Tokenizer& data, uint16 index, float value);
static void Customize(CharacterCustomizeInfo const* customizeInfo, SQLTransaction& trans);
static void SavePositionInDB(WorldLocation const& loc, uint16 zoneId, ObjectGuid guid, SQLTransaction& trans);
@@ -1441,10 +1454,9 @@ class Player : public Unit, public GridObject<Player>
bool m_mailsLoaded;
bool m_mailsUpdated;
- void SetBindPoint(ObjectGuid guid);
- void SendTalentWipeConfirm(ObjectGuid guid);
+ void SetBindPoint(ObjectGuid guid) const;
+ void SendTalentWipeConfirm(ObjectGuid guid) const;
void ResetPetTalents();
- void CalcRage(uint32 damage, bool attacker);
void RegenerateAll();
void Regenerate(Powers power);
void RegenerateHealth();
@@ -1472,13 +1484,13 @@ class Player : public Unit, public GridObject<Player>
uint8 GetComboPoints() const { return m_comboPoints; }
ObjectGuid GetComboTarget() const { return m_comboTarget; }
- void AddComboPoints(Unit* target, int8 count, Spell* spell = NULL);
+ void AddComboPoints(Unit* target, int8 count, Spell* spell = nullptr);
void GainSpellComboPoints(int8 count);
void ClearComboPoints();
void SendComboPoints();
- void SendMailResult(uint32 mailId, MailResponseType mailAction, MailResponseResult mailError, uint32 equipError = 0, ObjectGuid::LowType item_guid = 0, uint32 item_count = 0);
- void SendNewMail();
+ void SendMailResult(uint32 mailId, MailResponseType mailAction, MailResponseResult mailError, uint32 equipError = 0, ObjectGuid::LowType item_guid = 0, uint32 item_count = 0) const;
+ void SendNewMail() const;
void UpdateNextMailTimeAndUnreads();
void AddNewMailDeliverTime(time_t deliver_time);
bool IsMailsLoaded() const { return m_mailsLoaded; }
@@ -1509,19 +1521,19 @@ class Player : public Unit, public GridObject<Player>
void AddMItem(Item* it);
bool RemoveMItem(uint32 id);
- void SendOnCancelExpectedVehicleRideAura();
+ void SendOnCancelExpectedVehicleRideAura() const;
void PetSpellInitialize();
void CharmSpellInitialize();
void PossessSpellInitialize();
void VehicleSpellInitialize();
- void SendRemoveControlBar();
+ void SendRemoveControlBar() const;
bool HasSpell(uint32 spell) const override;
bool HasActiveSpell(uint32 spell) const; // show in spellbook
TrainerSpellState GetTrainerSpellState(TrainerSpell const* trainer_spell) const;
bool IsSpellFitByClassAndRace(uint32 spell_id) const;
bool IsNeedCastPassiveSpellAtLearn(SpellInfo const* spellInfo) const;
- void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask);
+ void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask) const;
void SendInitialSpells();
bool AddSpell(uint32 spellId, bool active, bool learning, bool dependent, bool disabled, bool loading = false, uint32 fromSkill = 0);
void LearnSpell(uint32 spell_id, bool dependent, uint32 fromSkill = 0);
@@ -1537,7 +1549,7 @@ class Player : public Unit, public GridObject<Player>
void RemoveTemporarySpell(uint32 spellId);
void SetReputation(uint32 factionentry, uint32 value);
uint32 GetReputation(uint32 factionentry) const;
- std::string const& GetGuildName();
+ std::string const& GetGuildName() const;
uint32 GetFreeTalentPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS1); }
void SetFreeTalentPoints(uint32 points);
bool ResetTalents(bool no_cost = false);
@@ -1576,26 +1588,39 @@ class Player : public Unit, public GridObject<Player>
PlayerSpellMap & GetSpellMap() { return m_spells; }
void AddSpellMod(SpellModifier* mod, bool apply);
- bool IsAffectedBySpellmod(SpellInfo const* spellInfo, SpellModifier* mod, Spell* spell = NULL);
- template <class T> T ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell* spell = NULL);
+ bool IsAffectedBySpellmod(SpellInfo const* spellInfo, SpellModifier* mod, Spell* spell = nullptr) const;
+ template <class T> T ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell* spell = nullptr);
void RemoveSpellMods(Spell* spell);
- void RestoreSpellMods(Spell* spell, uint32 ownerAuraId = 0, Aura* aura = NULL);
- void RestoreAllSpellMods(uint32 ownerAuraId = 0, Aura* aura = NULL);
+ void RestoreSpellMods(Spell* spell, uint32 ownerAuraId = 0, Aura* aura = nullptr);
+ void RestoreAllSpellMods(uint32 ownerAuraId = 0, Aura* aura = nullptr);
void DropModCharge(SpellModifier* mod, Spell* spell);
void SetSpellModTakingSpell(Spell* spell, bool apply);
void RemoveArenaSpellCooldowns(bool removeActivePetCooldowns = false);
uint32 GetLastPotionId() const { return m_lastPotionId; }
void SetLastPotionId(uint32 item_id) { m_lastPotionId = item_id; }
- void UpdatePotionCooldown(Spell* spell = NULL);
+ void UpdatePotionCooldown(Spell* spell = nullptr);
- void setResurrectRequestData(ObjectGuid guid, uint32 mapId, float X, float Y, float Z, uint32 health, uint32 mana);
- void clearResurrectRequestData();
- bool isResurrectRequestedBy(ObjectGuid guid) const { return !m_resurrectGUID.IsEmpty() && m_resurrectGUID == guid; }
- bool isResurrectRequested() const { return !m_resurrectGUID.IsEmpty(); }
+ void SetResurrectRequestData(Unit* caster, uint32 health, uint32 mana, uint32 appliedAura);
+
+ void ClearResurrectRequestData()
+ {
+ _resurrectionData.reset();
+ }
+
+ bool IsResurrectRequestedBy(ObjectGuid const& guid) const
+ {
+ if (!IsResurrectRequested())
+ return false;
+
+ return !_resurrectionData->GUID.IsEmpty() && _resurrectionData->GUID == guid;
+ }
+
+ bool IsResurrectRequested() const { return _resurrectionData.get() != nullptr; }
void ResurrectUsingRequestData();
+ void ResurrectUsingRequestDataImpl();
- uint8 getCinematic() { return m_cinematic; }
+ uint8 getCinematic() const { return m_cinematic; }
void setCinematic(uint8 cine) { m_cinematic = cine; }
ActionButton* addActionButton(uint8 button, uint32 action, uint8 type);
@@ -1603,11 +1628,11 @@ class Player : public Unit, public GridObject<Player>
ActionButton const* GetActionButton(uint8 button);
void SendInitialActionButtons() const { SendActionButtons(1); }
void SendActionButtons(uint32 state) const;
- bool IsActionButtonDataValid(uint8 button, uint32 action, uint8 type);
+ bool IsActionButtonDataValid(uint8 button, uint32 action, uint8 type) const;
PvPInfo pvpInfo;
void UpdatePvPState(bool onlyFFA = false);
- void SetPvP(bool state);
+ void SetPvP(bool state) override;
void UpdatePvP(bool state, bool override=false);
void UpdateZone(uint32 newZone, uint32 newArea);
void UpdateArea(uint32 newArea);
@@ -1633,7 +1658,7 @@ class Player : public Unit, public GridObject<Player>
bool IsInSameGroupWith(Player const* p) const;
bool IsInSameRaidWith(Player const* p) const;
void UninviteFromGroup();
- static void RemoveFromGroup(Group* group, ObjectGuid guid, RemoveMethod method = GROUP_REMOVEMETHOD_DEFAULT, ObjectGuid kicker = ObjectGuid::Empty, const char* reason = NULL);
+ static void RemoveFromGroup(Group* group, ObjectGuid guid, RemoveMethod method = GROUP_REMOVEMETHOD_DEFAULT, ObjectGuid kicker = ObjectGuid::Empty, const char* reason = nullptr);
void RemoveFromGroup(RemoveMethod method = GROUP_REMOVEMETHOD_DEFAULT) { RemoveFromGroup(GetGroup(), GetGUID(), method); }
void SendUpdateToOutOfRangeGroupMembers();
@@ -1700,13 +1725,13 @@ class Player : public Unit, public GridObject<Player>
void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) override;
void UpdateDefenseBonusesMod();
- inline void RecalculateRating(CombatRating cr) { ApplyRatingMod(cr, 0, true);}
- float GetMeleeCritFromAgility();
- void GetDodgeFromAgility(float &diminishing, float &nondiminishing);
+ void RecalculateRating(CombatRating cr) { ApplyRatingMod(cr, 0, true);}
+ float GetMeleeCritFromAgility() const;
+ void GetDodgeFromAgility(float &diminishing, float &nondiminishing) const;
float GetMissPercentageFromDefence() const;
- float GetSpellCritFromIntellect();
- float OCTRegenHPPerSpirit();
- float OCTRegenMPPerSpirit();
+ float GetSpellCritFromIntellect() const;
+ float OCTRegenHPPerSpirit() const;
+ float OCTRegenMPPerSpirit() const;
float GetRatingMultiplier(CombatRating cr) const;
float GetRatingBonusValue(CombatRating cr) const;
uint32 GetBaseSpellPowerBonus() const { return m_baseSpellPower; }
@@ -1744,26 +1769,26 @@ class Player : public Unit, public GridObject<Player>
void BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const override;
void DestroyForPlayer(Player* target, bool onDeath = false) const override;
- void SendLogXPGain(uint32 GivenXP, Unit* victim, uint32 BonusXP, bool recruitAFriend = false, float group_rate=1.0f);
+ void SendLogXPGain(uint32 GivenXP, Unit* victim, uint32 BonusXP, bool recruitAFriend = false, float group_rate=1.0f) const;
// notifiers
- void SendAttackSwingCantAttack();
- void SendAttackSwingCancelAttack();
- void SendAttackSwingDeadTarget();
- void SendAttackSwingNotInRange();
- void SendAttackSwingBadFacingAttack();
+ void SendAttackSwingCantAttack() const;
+ void SendAttackSwingCancelAttack() const;
+ void SendAttackSwingDeadTarget() const;
+ void SendAttackSwingNotInRange() const;
+ void SendAttackSwingBadFacingAttack() const;
void SendAutoRepeatCancel(Unit* target);
- void SendExplorationExperience(uint32 Area, uint32 Experience);
+ void SendExplorationExperience(uint32 Area, uint32 Experience) const;
- void SendDungeonDifficulty(bool IsInGroup);
- void SendRaidDifficulty(bool IsInGroup, int32 forcedDifficulty = -1);
+ void SendDungeonDifficulty(bool IsInGroup) const;
+ void SendRaidDifficulty(bool IsInGroup, int32 forcedDifficulty = -1) const;
void ResetInstances(uint8 method, bool isRaid);
- void SendResetInstanceSuccess(uint32 MapId);
- void SendResetInstanceFailed(uint32 reason, uint32 MapId);
- void SendResetFailedNotify(uint32 mapid);
+ void SendResetInstanceSuccess(uint32 MapId) const;
+ void SendResetInstanceFailed(uint32 reason, uint32 MapId) const;
+ void SendResetFailedNotify(uint32 mapid) const;
- virtual bool UpdatePosition(float x, float y, float z, float orientation, bool teleport = false) override;
- bool UpdatePosition(const Position &pos, bool teleport = false) { return UpdatePosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teleport); }
+ bool UpdatePosition(float x, float y, float z, float orientation, bool teleport = false) override;
+ bool UpdatePosition(const Position &pos, bool teleport = false) override { return UpdatePosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teleport); }
void UpdateUnderwaterState(Map* m, float x, float y, float z) override;
void SendMessageToSet(WorldPacket* data, bool self) override { SendMessageToSetInRange(data, GetVisibilityRange(), self); }
@@ -1784,14 +1809,7 @@ class Player : public Unit, public GridObject<Player>
void ResurrectPlayer(float restore_percent, bool applySickness = false);
void BuildPlayerRepop();
void RepopAtGraveyard();
- void SendGhoulResurrectRequest(Player* target);
- bool IsValidGhoulResurrectRequest(ObjectGuid guid)
- {
- return !m_ghoulResurrectPlayerGUID.IsEmpty() && m_ghoulResurrectPlayerGUID == guid;
- }
- void GhoulResurrect();
- void SetGhoulResurrectGhoulGUID(ObjectGuid guid) { m_ghoulResurrectGhoulGUID = guid; }
- ObjectGuid GetGhoulResurrectGhoulGUID() { return m_ghoulResurrectGhoulGUID; }
+
void RemoveGhoul();
void DurabilityLossAll(double percent, bool inventory);
@@ -1804,11 +1822,11 @@ class Player : public Unit, public GridObject<Player>
void UpdateMirrorTimers();
void StopMirrorTimers();
- bool IsMirrorTimerActive(MirrorTimerType type);
+ bool IsMirrorTimerActive(MirrorTimerType type) const;
void SetMovement(PlayerMovementType pType);
- bool CanJoinConstantChannelInZone(ChatChannelsEntry const* channel, AreaTableEntry const* zone);
+ bool CanJoinConstantChannelInZone(ChatChannelsEntry const* channel, AreaTableEntry const* zone) const;
void JoinedChannel(Channel* c);
void LeftChannel(Channel* c);
@@ -1899,8 +1917,8 @@ class Player : public Unit, public GridObject<Player>
uint32 GetDeathTimer() const { return m_deathTimer; }
uint32 GetCorpseReclaimDelay(bool pvp) const;
void UpdateCorpseReclaimDelay();
- int32 CalculateCorpseReclaimDelay(bool load = false);
- void SendCorpseReclaimDelay(uint32 delay);
+ int32 CalculateCorpseReclaimDelay(bool load = false) const;
+ void SendCorpseReclaimDelay(uint32 delay) const;
uint32 GetShieldBlockValue() const override; // overwrite Unit version (virtual)
bool CanParry() const { return m_canParry; }
@@ -1933,7 +1951,7 @@ class Player : public Unit, public GridObject<Player>
void _ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply, bool only_level_scale = false);
void _ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingStatValuesEntry const* ssv, bool apply);
void _ApplyAmmoBonuses();
- bool EnchantmentFitsRequirements(uint32 enchantmentcondition, int8 slot);
+ bool EnchantmentFitsRequirements(uint32 enchantmentcondition, int8 slot) const;
void ToggleMetaGemsActive(uint8 exceptslot, bool apply);
void CorrectMetaGemEnchants(uint8 slot, bool apply);
void InitDataForForm(bool reapplyMods = false);
@@ -1950,21 +1968,21 @@ class Player : public Unit, public GridObject<Player>
void DeleteEquipmentSet(uint64 setGuid);
void SendInitWorldStates(uint32 zone, uint32 area);
- void SendUpdateWorldState(uint32 Field, uint32 Value);
- void SendDirectMessage(WorldPacket* data);
- void SendBGWeekendWorldStates();
- void SendBattlefieldWorldStates();
+ void SendUpdateWorldState(uint32 Field, uint32 Value) const;
+ void SendDirectMessage(WorldPacket const* data) const;
+ void SendBGWeekendWorldStates() const;
+ void SendBattlefieldWorldStates() const;
- void SendAurasForTarget(Unit* target);
+ void SendAurasForTarget(Unit* target) const;
PlayerMenu* PlayerTalkClass;
std::vector<ItemSetEffect*> ItemSetEff;
void SendLoot(ObjectGuid guid, LootType loot_type);
- void SendLootError(ObjectGuid guid, LootError error);
- void SendLootRelease(ObjectGuid guid);
- void SendNotifyLootItemRemoved(uint8 lootSlot);
- void SendNotifyLootMoneyRemoved();
+ void SendLootError(ObjectGuid guid, LootError error) const;
+ void SendLootRelease(ObjectGuid guid) const;
+ void SendNotifyLootItemRemoved(uint8 lootSlot) const;
+ void SendNotifyLootMoneyRemoved() const;
/*********************************************************/
/*** BATTLEGROUND SYSTEM ***/
@@ -1985,7 +2003,7 @@ class Player : public Unit, public GridObject<Player>
void SetBattlegroundId(uint32 val, BattlegroundTypeId bgTypeId);
uint32 AddBattlegroundQueueId(BattlegroundQueueTypeId val);
- bool HasFreeBattlegroundQueueId();
+ bool HasFreeBattlegroundQueueId() const;
void RemoveBattlegroundQueueId(BattlegroundQueueTypeId val);
void SetInviteForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId, uint32 instanceId);
bool IsInvitedForBattlegroundInstance(uint32 instanceId) const;
@@ -2002,10 +2020,10 @@ class Player : public Unit, public GridObject<Player>
void ClearAfkReports() { m_bgData.bgAfkReporter.clear(); }
bool GetBGAccessByLevel(BattlegroundTypeId bgTypeId) const;
- bool isTotalImmunity();
- bool CanUseBattlegroundObject(GameObject* gameobject);
- bool isTotalImmune();
- bool CanCaptureTowerPoint();
+ bool isTotalImmunity() const;
+ bool CanUseBattlegroundObject(GameObject* gameobject) const;
+ bool isTotalImmune() const;
+ bool CanCaptureTowerPoint() const;
bool GetRandomWinner() const { return m_IsBGRandomWinner; }
void SetRandomWinner(bool isWinner);
@@ -2016,13 +2034,13 @@ class Player : public Unit, public GridObject<Player>
OutdoorPvP* GetOutdoorPvP() const;
// returns true if the player is in active state for outdoor pvp objective capturing, false otherwise
- bool IsOutdoorPvPActive();
+ bool IsOutdoorPvPActive() const;
/*********************************************************/
/*** ENVIROMENTAL SYSTEM ***/
/*********************************************************/
- bool IsImmuneToEnvironmentalDamage();
+ bool IsImmuneToEnvironmentalDamage() const;
uint32 EnvironmentalDamage(EnviromentalDamage type, uint32 damage);
/*********************************************************/
@@ -2052,7 +2070,7 @@ class Player : public Unit, public GridObject<Player>
void SetViewpoint(WorldObject* target, bool apply);
WorldObject* GetViewpoint() const;
void StopCastingCharm();
- void StopCastingBindSight();
+ void StopCastingBindSight() const;
uint32 GetSaveTimer() const { return m_nextSave; }
void SetSaveTimer(uint32 timer) { m_nextSave = timer; }
@@ -2085,7 +2103,7 @@ class Player : public Unit, public GridObject<Player>
bool IsVisibleGloballyFor(Player const* player) const;
- void SendInitialVisiblePackets(Unit* target);
+ void SendInitialVisiblePackets(Unit* target) const;
void UpdateObjectVisibility(bool forced = true) override;
void UpdateVisibilityForPlayer();
void UpdateVisibilityOf(WorldObject* target);
@@ -2100,8 +2118,8 @@ class Player : public Unit, public GridObject<Player>
void SetAtLoginFlag(AtLoginFlags f) { m_atLoginFlags |= f; }
void RemoveAtLoginFlag(AtLoginFlags flags, bool persist = false);
- bool isUsingLfg();
- bool inRandomLfgDungeon();
+ bool isUsingLfg() const;
+ bool inRandomLfgDungeon() const;
typedef std::set<uint32> DFQuestsDoneList;
DFQuestsDoneList m_DFQuests;
@@ -2113,8 +2131,8 @@ class Player : public Unit, public GridObject<Player>
void ResummonPetTemporaryUnSummonedIfAny();
bool IsPetNeedBeTemporaryUnsummoned() const;
- void SendCinematicStart(uint32 CinematicSequenceId);
- void SendMovieStart(uint32 MovieId);
+ void SendCinematicStart(uint32 CinematicSequenceId) const;
+ void SendMovieStart(uint32 MovieId) const;
/*********************************************************/
/*** INSTANCE SYSTEM ***/
@@ -2152,10 +2170,10 @@ class Player : public Unit, public GridObject<Player>
/*** GROUP SYSTEM ***/
/*********************************************************/
- Group* GetGroupInvite() { return m_groupInvite; }
+ Group* GetGroupInvite() const { return m_groupInvite; }
void SetGroupInvite(Group* group) { m_groupInvite = group; }
Group* GetGroup() { return m_group.getTarget(); }
- const Group* GetGroup() const { return (const Group*)m_group.getTarget(); }
+ Group const* GetGroup() const { return const_cast<Group const*>(m_group.getTarget()); }
GroupReference& GetGroupRef() { return m_group; }
void SetGroup(Group* group, int8 subgroup = -1);
uint8 GetSubGroup() const { return m_group.getSubGroup(); }
@@ -2169,7 +2187,7 @@ class Player : public Unit, public GridObject<Player>
// Battleground / Battlefield Group System
void SetBattlegroundOrBattlefieldRaid(Group* group, int8 subgroup = -1);
void RemoveFromBattlegroundOrBattlefieldRaid();
- Group* GetOriginalGroup() { return m_originalGroup.getTarget(); }
+ Group* GetOriginalGroup() const { return m_originalGroup.getTarget(); }
GroupReference& GetOriginalGroupRef() { return m_originalGroup; }
uint8 GetOriginalSubGroup() const { return m_originalGroup.getSubGroup(); }
void SetOriginalGroup(Group* group, int8 subgroup = -1);
@@ -2202,8 +2220,8 @@ class Player : public Unit, public GridObject<Player>
void RemoveRunesByAuraEffect(AuraEffect const* aura);
void RestoreBaseRune(uint8 index);
void ConvertRune(uint8 index, RuneType newType);
- void ResyncRunes(uint8 count);
- void AddRunePower(uint8 index);
+ void ResyncRunes(uint8 count) const;
+ void AddRunePower(uint8 index) const;
void InitRunes();
void SendRespondInspectAchievements(Player* player) const;
@@ -2227,7 +2245,7 @@ class Player : public Unit, public GridObject<Player>
void SetChampioningFaction(uint32 faction) { m_ChampioningFaction = faction; }
Spell* m_spellModTakingSpell;
- float GetAverageItemLevel();
+ float GetAverageItemLevel() const;
bool isDebugAreaTriggers;
void ClearWhisperWhiteList() { WhisperList.clear(); }
@@ -2246,8 +2264,8 @@ class Player : public Unit, public GridObject<Player>
//! Return collision height sent to client
float GetCollisionHeight(bool mounted) const;
- std::string GetMapAreaAndZoneString();
- std::string GetCoordsMapAreaAndZoneString();
+ std::string GetMapAreaAndZoneString() const;
+ std::string GetCoordsMapAreaAndZoneString() const;
protected:
// Gamemaster whisper whitelist
@@ -2338,9 +2356,9 @@ class Player : public Unit, public GridObject<Player>
void _SaveSpells(SQLTransaction& trans);
void _SaveEquipmentSets(SQLTransaction& trans);
void _SaveBGData(SQLTransaction& trans);
- void _SaveGlyphs(SQLTransaction& trans);
+ void _SaveGlyphs(SQLTransaction& trans) const;
void _SaveTalents(SQLTransaction& trans);
- void _SaveStats(SQLTransaction& trans);
+ void _SaveStats(SQLTransaction& trans) const;
void _SaveInstanceTimeRestrictions(SQLTransaction& trans);
/*********************************************************/
@@ -2350,7 +2368,7 @@ class Player : public Unit, public GridObject<Player>
void SendMirrorTimer(MirrorTimerType Type, uint32 MaxValue, uint32 CurrentValue, int32 Regen);
void StopMirrorTimer(MirrorTimerType Type);
void HandleDrowning(uint32 time_diff);
- int32 getMaxTimer(MirrorTimerType timer);
+ int32 getMaxTimer(MirrorTimerType timer) const;
/*********************************************************/
/*** HONOR SYSTEM ***/
@@ -2421,13 +2439,7 @@ class Player : public Unit, public GridObject<Player>
void ResetTimeSync();
void SendTimeSync();
- ObjectGuid m_resurrectGUID;
- uint32 m_resurrectMap;
- float m_resurrectX, m_resurrectY, m_resurrectZ;
- uint32 m_resurrectHealth, m_resurrectMana;
-
- ObjectGuid m_ghoulResurrectPlayerGUID;
- ObjectGuid m_ghoulResurrectGhoulGUID;
+ std::unique_ptr<ResurrectionData> _resurrectionData;
WorldSession* m_session;
@@ -2533,8 +2545,6 @@ class Player : public Unit, public GridObject<Player>
MapReference m_mapRef;
- void UpdateCharmedAI();
-
uint32 m_lastFallTime;
float m_lastFallZ;
@@ -2584,8 +2594,8 @@ class Player : public Unit, public GridObject<Player>
WorldLocation _corpseLocation;
};
-void AddItemsSetItem(Player* player, Item* item);
-void RemoveItemsSetItem(Player* player, ItemTemplate const* proto);
+TC_GAME_API void AddItemsSetItem(Player* player, Item* item);
+TC_GAME_API void RemoveItemsSetItem(Player* player, ItemTemplate const* proto);
// "the bodies of template functions must be made available in a header file"
template <class T> T Player::ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell* spell)
diff --git a/src/server/game/Entities/Player/SocialMgr.cpp b/src/server/game/Entities/Player/SocialMgr.cpp
index ffb2d8a7dd8..809bdd0bf6f 100644
--- a/src/server/game/Entities/Player/SocialMgr.cpp
+++ b/src/server/game/Entities/Player/SocialMgr.cpp
@@ -195,6 +195,12 @@ SocialMgr::SocialMgr() { }
SocialMgr::~SocialMgr() { }
+SocialMgr* SocialMgr::instance()
+{
+ static SocialMgr instance;
+ return &instance;
+}
+
void SocialMgr::GetFriendInfo(Player* player, ObjectGuid::LowType friendGUID, FriendInfo &friendInfo)
{
if (!player)
diff --git a/src/server/game/Entities/Player/SocialMgr.h b/src/server/game/Entities/Player/SocialMgr.h
index 8f8ed04b5fb..803301b95c7 100644
--- a/src/server/game/Entities/Player/SocialMgr.h
+++ b/src/server/game/Entities/Player/SocialMgr.h
@@ -99,7 +99,7 @@ enum FriendsResult
#define SOCIALMGR_FRIEND_LIMIT 50
#define SOCIALMGR_IGNORE_LIMIT 50
-class PlayerSocial
+class TC_GAME_API PlayerSocial
{
friend class SocialMgr;
public:
@@ -128,11 +128,7 @@ class SocialMgr
~SocialMgr();
public:
- static SocialMgr* instance()
- {
- static SocialMgr instance;
- return &instance;
- }
+ static SocialMgr* instance();
// Misc
void RemovePlayerSocial(ObjectGuid::LowType guid) { m_socialMap.erase(guid); }
diff --git a/src/server/game/Entities/Player/TradeData.h b/src/server/game/Entities/Player/TradeData.h
index 276e6f3db1c..396d784fee7 100644
--- a/src/server/game/Entities/Player/TradeData.h
+++ b/src/server/game/Entities/Player/TradeData.h
@@ -31,7 +31,7 @@ enum TradeSlots
class Item;
class Player;
-class TradeData
+class TC_GAME_API TradeData
{
public:
TradeData(Player* player, Player* trader) :
diff --git a/src/server/game/Entities/Totem/Totem.h b/src/server/game/Entities/Totem/Totem.h
index bbe7943f4b6..42be4525a0c 100644
--- a/src/server/game/Entities/Totem/Totem.h
+++ b/src/server/game/Entities/Totem/Totem.h
@@ -32,7 +32,7 @@ enum TotemType
#define SENTRY_TOTEM_ENTRY 3968
-class Totem : public Minion
+class TC_GAME_API Totem : public Minion
{
public:
Totem(SummonPropertiesEntry const* properties, Unit* owner);
diff --git a/src/server/game/Entities/Transport/Transport.h b/src/server/game/Entities/Transport/Transport.h
index 987fbf70739..4cd20c8b613 100644
--- a/src/server/game/Entities/Transport/Transport.h
+++ b/src/server/game/Entities/Transport/Transport.h
@@ -25,7 +25,7 @@
struct CreatureData;
-class Transport : public GameObject, public TransportBase
+class TC_GAME_API Transport : public GameObject, public TransportBase
{
friend Transport* TransportMgr::CreateTransport(uint32, ObjectGuid::LowType, Map*);
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index c21301c27b2..96ccc2c87d6 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -45,6 +45,7 @@
#include "PetAI.h"
#include "Pet.h"
#include "Player.h"
+#include "PlayerAI.h"
#include "QuestDef.h"
#include "ReputationMgr.h"
#include "SpellAuraEffects.h"
@@ -3748,6 +3749,77 @@ void Unit::RemoveAura(Aura* aura, AuraRemoveMode mode)
RemoveAura(aurApp, mode);
}
+void Unit::RemoveAppliedAuras(std::function<bool(AuraApplication const*)> const& check)
+{
+ for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
+ {
+ if (check(iter->second))
+ {
+ RemoveAura(iter);
+ continue;
+ }
+ ++iter;
+ }
+}
+
+void Unit::RemoveOwnedAuras(std::function<bool(Aura const*)> const& check)
+{
+ for (AuraMap::iterator iter = m_ownedAuras.begin(); iter != m_ownedAuras.end();)
+ {
+ if (check(iter->second))
+ {
+ RemoveOwnedAura(iter);
+ continue;
+ }
+ ++iter;
+ }
+}
+
+void Unit::RemoveAppliedAuras(uint32 spellId, std::function<bool(AuraApplication const*)> const& check)
+{
+ for (AuraApplicationMap::iterator iter = m_appliedAuras.lower_bound(spellId); iter != m_appliedAuras.upper_bound(spellId);)
+ {
+ if (check(iter->second))
+ {
+ RemoveAura(iter);
+ continue;
+ }
+ ++iter;
+ }
+}
+
+void Unit::RemoveOwnedAuras(uint32 spellId, std::function<bool(Aura const*)> const& check)
+{
+ for (AuraMap::iterator iter = m_ownedAuras.lower_bound(spellId); iter != m_ownedAuras.upper_bound(spellId);)
+ {
+ if (check(iter->second))
+ {
+ RemoveOwnedAura(iter);
+ continue;
+ }
+ ++iter;
+ }
+}
+
+void Unit::RemoveAurasByType(AuraType auraType, std::function<bool(AuraApplication const*)> const& check)
+{
+ for (AuraEffectList::iterator iter = m_modAuras[auraType].begin(); iter != m_modAuras[auraType].end();)
+ {
+ Aura* aura = (*iter)->GetBase();
+ AuraApplication * aurApp = aura->GetApplicationOfTarget(GetGUID());
+ ASSERT(aurApp);
+
+ ++iter;
+ if (check(aurApp))
+ {
+ uint32 removedAuras = m_removedAurasCount;
+ RemoveAura(aurApp);
+ if (m_removedAurasCount > removedAuras + 1)
+ iter = m_modAuras[auraType].begin();
+ }
+ }
+}
+
void Unit::RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID, uint8 reqEffMask, AuraRemoveMode removeMode)
{
for (AuraApplicationMap::iterator iter = m_appliedAuras.lower_bound(spellId); iter != m_appliedAuras.upper_bound(spellId);)
@@ -8980,10 +9052,10 @@ bool Unit::Attack(Unit* victim, bool meleeAttack)
if (GetTypeId() == TYPEID_UNIT && !IsPet())
{
// should not let player enter combat by right clicking target - doesn't helps
+ AddThreat(victim, 0.0f);
SetInCombatWith(victim);
if (victim->GetTypeId() == TYPEID_PLAYER)
victim->SetInCombatWith(this);
- AddThreat(victim, 0.0f);
ToCreature()->SendAIReaction(AI_REACTION_HOSTILE);
ToCreature()->CallAssistance();
@@ -9227,7 +9299,7 @@ Unit* Unit::GetCharmer() const
if (ObjectGuid charmerGUID = GetCharmerGUID())
return ObjectAccessor::GetUnit(*this, charmerGUID);
- return NULL;
+ return nullptr;
}
Player* Unit::GetCharmerOrOwnerPlayerOrPlayerItself() const
@@ -12341,7 +12413,7 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced)
if (Creature* creature = ToCreature())
{
uint32 immuneMask = creature->GetCreatureTemplate()->MechanicImmuneMask;
- if (immuneMask & (1 << MECHANIC_SNARE) || immuneMask & (1 << MECHANIC_DAZE))
+ if (immuneMask & (1 << (MECHANIC_SNARE - 1)) || immuneMask & (1 << (MECHANIC_DAZE - 1)))
break;
}
@@ -12433,6 +12505,7 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
return;
}
+ data << GetPackGUID();
BuildMovementPacket(&data);
data << float(GetSpeed(mtype));
SendMessageToSet(&data, true);
@@ -12492,6 +12565,11 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
}
}
+bool Unit::IsGhouled() const
+{
+ return HasAura(SPELL_DK_RAISE_ALLY);
+}
+
void Unit::setDeathState(DeathState s)
{
// Death state needs to be updated before RemoveAllAurasOnDeath() is called, to prevent entering combat
@@ -13652,28 +13730,76 @@ void Unit::CleanupsBeforeDelete(bool finalCleanup)
void Unit::UpdateCharmAI()
{
- if (GetTypeId() == TYPEID_PLAYER)
- return;
-
- if (i_disabledAI) // disabled AI must be primary AI
+ switch (GetTypeId())
{
- if (!IsCharmed())
- {
- delete i_AI;
- i_AI = i_disabledAI;
- i_disabledAI = NULL;
- }
- }
- else
- {
- if (IsCharmed())
+ case TYPEID_UNIT:
+ if (i_disabledAI) // disabled AI must be primary AI
+ {
+ if (!IsCharmed())
+ {
+ delete i_AI;
+ i_AI = i_disabledAI;
+ i_disabledAI = nullptr;
+ }
+ }
+ else
+ {
+ if (IsCharmed())
+ {
+ i_disabledAI = i_AI;
+ if (isPossessed() || IsVehicle())
+ i_AI = new PossessedAI(ToCreature());
+ else
+ i_AI = new PetAI(ToCreature());
+ }
+ }
+ break;
+ case TYPEID_PLAYER:
{
- i_disabledAI = i_AI;
- if (isPossessed() || IsVehicle())
- i_AI = new PossessedAI(ToCreature());
+ if (IsCharmed()) // if we are currently being charmed, then we should apply charm AI
+ {
+ i_disabledAI = i_AI;
+
+ UnitAI* newAI = nullptr;
+ // first, we check if the creature's own AI specifies an override playerai for its owned players
+ if (Unit* charmer = GetCharmer())
+ {
+ if (Creature* creatureCharmer = charmer->ToCreature())
+ {
+ if (PlayerAI* charmAI = creatureCharmer->IsAIEnabled ? creatureCharmer->AI()->GetAIForCharmedPlayer(ToPlayer()) : nullptr)
+ newAI = charmAI;
+ }
+ else
+ {
+ TC_LOG_ERROR("misc", "Attempt to assign charm AI to player %s who is charmed by non-creature %s.", GetGUID().ToString().c_str(), GetCharmerGUID().ToString().c_str());
+ }
+ }
+ if (!newAI) // otherwise, we default to the generic one
+ newAI = new SimpleCharmedPlayerAI(ToPlayer());
+ i_AI = newAI;
+ }
else
- i_AI = new PetAI(ToCreature());
+ {
+ if (i_AI)
+ {
+ // we allow the charmed PlayerAI to clean up
+ i_AI->OnCharmed(false);
+ // then delete it
+ delete i_AI;
+ }
+ else
+ {
+ TC_LOG_ERROR("misc", "Attempt to remove charm AI from player %s who doesn't currently have charm AI.", GetGUID().ToString().c_str());
+ }
+ // and restore our previous PlayerAI (if we had one)
+ i_AI = i_disabledAI;
+ i_disabledAI = nullptr;
+ // IsAIEnabled gets handled in the caller
+ }
+ break;
}
+ default:
+ TC_LOG_ERROR("misc", "Attempt to update charm AI for unit %s, which is neither player nor creature.", GetGUID().ToString().c_str());
}
}
@@ -15902,11 +16028,17 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au
ToCreature()->AI()->OnCharmed(true);
GetMotionMaster()->MoveIdle();
}
- else
+ else if (Player* player = ToPlayer())
{
- Player* player = ToPlayer();
if (player->isAFK())
player->ToggleAFK();
+
+ if (charmer->GetTypeId() == TYPEID_UNIT) // we are charmed by a creature
+ {
+ // change AI to charmed AI on next Update tick
+ NeedChangeAI = true;
+ IsAIEnabled = false;
+ }
player->SetClientControl(this, false);
}
@@ -16064,7 +16196,14 @@ void Unit::RemoveCharmedBy(Unit* charmer)
}
if (Player* player = ToPlayer())
+ {
+ if (charmer->GetTypeId() == TYPEID_UNIT) // charmed by a creature, this means we had PlayerAI
+ {
+ NeedChangeAI = true;
+ IsAIEnabled = false;
+ }
player->SetClientControl(this, true);
+ }
// a guardian should always have charminfo
if (playerCharmer && this != charmer->GetFirstControlled())
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 4565160dc93..d82b2cd8422 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -533,8 +533,8 @@ enum UnitMoveType
#define MAX_MOVE_TYPE 9
-extern float baseMoveSpeed[MAX_MOVE_TYPE];
-extern float playerBaseMoveSpeed[MAX_MOVE_TYPE];
+TC_GAME_API extern float baseMoveSpeed[MAX_MOVE_TYPE];
+TC_GAME_API extern float playerBaseMoveSpeed[MAX_MOVE_TYPE];
enum WeaponAttackType
{
@@ -586,7 +586,7 @@ enum DamageEffectType
};
// Value masks for UNIT_FIELD_FLAGS
-enum UnitFlags
+enum UnitFlags : uint32
{
UNIT_FLAG_SERVER_CONTROLLED = 0x00000001, // set only when unit movement is controlled by server - by SPLINE/MONSTER_MOVE packets, together with UNIT_FLAG_STUNNED; only set to units controlled by client; client function CGUnit_C::IsClientControlled returns false when set for owner
UNIT_FLAG_NON_ATTACKABLE = 0x00000002, // not attackable
@@ -826,7 +826,7 @@ struct CleanDamage
struct CalcDamageInfo;
-class DamageInfo
+class TC_GAME_API DamageInfo
{
private:
Unit* const m_attacker;
@@ -889,7 +889,7 @@ public:
SpellSchoolMask GetSchoolMask() const { return _schoolMask; };
};
-class ProcEventInfo
+class TC_GAME_API ProcEventInfo
{
public:
ProcEventInfo(Unit* actor, Unit* actionTarget, Unit* procTarget, uint32 typeMask,
@@ -947,7 +947,7 @@ struct CalcDamageInfo
};
// Spell damage info structure based on structure sending in SMSG_SPELLNONMELEEDAMAGELOG opcode
-struct SpellNonMeleeDamage
+struct TC_GAME_API SpellNonMeleeDamage
{
SpellNonMeleeDamage(Unit* _attacker, Unit* _target, uint32 _SpellID, uint32 _schoolMask)
: target(_target), attacker(_attacker), SpellID(_SpellID), damage(0), overkill(0), schoolMask(_schoolMask),
@@ -1108,7 +1108,7 @@ enum ActionBarIndex
#define MAX_UNIT_ACTION_BAR_INDEX (ACTION_BAR_INDEX_END-ACTION_BAR_INDEX_START)
-struct CharmInfo
+struct TC_GAME_API CharmInfo
{
public:
explicit CharmInfo(Unit* unit);
@@ -1210,7 +1210,7 @@ enum PlayerTotemType
struct SpellProcEventEntry; // used only privately
-class Unit : public WorldObject
+class TC_GAME_API Unit : public WorldObject
{
public:
typedef std::set<Unit*> AttackerSet;
@@ -1383,7 +1383,8 @@ class Unit : public WorldObject
bool IsContestedGuard() const;
bool IsPvP() const { return HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP); }
bool IsFFAPvP() const { return HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); }
- void SetPvP(bool state);
+ virtual void SetPvP(bool state);
+
uint32 GetCreatureType() const;
uint32 GetCreatureTypeMask() const;
@@ -1561,7 +1562,7 @@ class Unit : public WorldObject
void SendTeleportPacket(Position& pos);
virtual bool UpdatePosition(float x, float y, float z, float ang, bool teleport = false);
// returns true if unit's position really changed
- bool UpdatePosition(const Position &pos, bool teleport = false);
+ virtual bool UpdatePosition(const Position &pos, bool teleport = false);
void UpdateOrientation(float orientation);
void UpdateHeight(float newZ);
@@ -1601,7 +1602,7 @@ class Unit : public WorldObject
bool IsAlive() const { return (m_deathState == ALIVE); }
bool isDying() const { return (m_deathState == JUST_DIED); }
bool isDead() const { return (m_deathState == DEAD || m_deathState == CORPSE); }
- bool IsGhouled() const { return HasAura(46619 /*SPELL_DK_RAISE_ALLY*/); }
+ bool IsGhouled() const;
DeathState getDeathState() const { return m_deathState; }
virtual void setDeathState(DeathState s); // overwrited in Creature/Player/Pet
@@ -1704,6 +1705,16 @@ class Unit : public WorldObject
void RemoveAura(AuraApplication * aurApp, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
void RemoveAura(Aura* aur, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
+ // Convenience methods removing auras by predicate
+ void RemoveAppliedAuras(std::function<bool(AuraApplication const*)> const& check);
+ void RemoveOwnedAuras(std::function<bool(Aura const*)> const& check);
+
+ // Optimized overloads taking advantage of map key
+ void RemoveAppliedAuras(uint32 spellId, std::function<bool(AuraApplication const*)> const& check);
+ void RemoveOwnedAuras(uint32 spellId, std::function<bool(Aura const*)> const& check);
+
+ void RemoveAurasByType(AuraType auraType, std::function<bool(AuraApplication const*)> const& check);
+
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, uint8 reqEffMask = 0, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
void RemoveAuraFromStack(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId, ObjectGuid casterGUID, Unit* dispeller, uint8 chargesRemoved = 1);
diff --git a/src/server/game/Entities/Vehicle/Vehicle.h b/src/server/game/Entities/Vehicle/Vehicle.h
index cd28c4082d4..f8992708a46 100644
--- a/src/server/game/Entities/Vehicle/Vehicle.h
+++ b/src/server/game/Entities/Vehicle/Vehicle.h
@@ -29,7 +29,7 @@ struct VehicleEntry;
class Unit;
class VehicleJoinEvent;
-class Vehicle : public TransportBase
+class TC_GAME_API Vehicle : public TransportBase
{
protected:
friend bool Unit::CreateVehicleKit(uint32 id, uint32 creatureEntry);
@@ -118,7 +118,7 @@ class Vehicle : public TransportBase
PendingJoinEventContainer _pendingJoinEvents; ///< Collection of delayed join events for prospective passengers
};
-class VehicleJoinEvent : public BasicEvent
+class TC_GAME_API VehicleJoinEvent : public BasicEvent
{
friend class Vehicle;
protected:
diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp
index b2871786034..bb8e89d4829 100644
--- a/src/server/game/Events/GameEventMgr.cpp
+++ b/src/server/game/Events/GameEventMgr.cpp
@@ -29,6 +29,12 @@
#include "UnitAI.h"
#include "GameObjectAI.h"
+GameEventMgr* GameEventMgr::instance()
+{
+ static GameEventMgr instance;
+ return &instance;
+}
+
bool GameEventMgr::CheckOneGameEvent(uint16 entry) const
{
switch (mGameEvent[entry].state)
@@ -221,7 +227,7 @@ void GameEventMgr::LoadFromDB()
uint8 event_id = fields[0].GetUInt8();
if (event_id == 0)
{
- TC_LOG_ERROR("sql.sql", "`game_event` game event entry 0 is reserved and can't be used.");
+ TC_LOG_ERROR("sql.sql", "`game_event`: game event entry 0 is reserved and can't be used.");
continue;
}
@@ -240,7 +246,7 @@ void GameEventMgr::LoadFromDB()
if (pGameEvent.length == 0 && pGameEvent.state == GAMEEVENT_NORMAL) // length>0 is validity check
{
- TC_LOG_ERROR("sql.sql", "`game_event` game event id (%i) isn't a world event and has length = 0, thus it can't be used.", event_id);
+ TC_LOG_ERROR("sql.sql", "`game_event`: game event id (%i) is not a world event and has length = 0, thus cannot be used.", event_id);
continue;
}
@@ -248,7 +254,7 @@ void GameEventMgr::LoadFromDB()
{
if (!sHolidaysStore.LookupEntry(pGameEvent.holiday_id))
{
- TC_LOG_ERROR("sql.sql", "`game_event` game event id (%i) have not existed holiday id %u.", event_id, pGameEvent.holiday_id);
+ TC_LOG_ERROR("sql.sql", "`game_event`: game event id (%i) contains nonexisting holiday id %u.", event_id, pGameEvent.holiday_id);
pGameEvent.holiday_id = HOLIDAY_NONE;
}
}
@@ -259,7 +265,7 @@ void GameEventMgr::LoadFromDB()
}
while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u game events in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u game events in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
@@ -283,7 +289,7 @@ void GameEventMgr::LoadFromDB()
if (event_id >= mGameEvent.size())
{
- TC_LOG_ERROR("sql.sql", "`game_event_save` game event entry (%i) is out of range compared to max event entry in `game_event`", event_id);
+ TC_LOG_ERROR("sql.sql", "`game_event_save`: game event entry (%i) is out of range compared to max event entry in `game_event`.", event_id);
continue;
}
@@ -294,7 +300,7 @@ void GameEventMgr::LoadFromDB()
}
else
{
- TC_LOG_ERROR("sql.sql", "game_event_save includes event save for non-worldevent id %u", event_id);
+ TC_LOG_ERROR("sql.sql", "game_event_save includes event save for non-worldevent id %u.", event_id);
continue;
}
@@ -302,7 +308,7 @@ void GameEventMgr::LoadFromDB()
}
while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u game event saves in game events in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u game event saves in game events in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
}
@@ -326,7 +332,7 @@ void GameEventMgr::LoadFromDB()
if (event_id >= mGameEvent.size())
{
- TC_LOG_ERROR("sql.sql", "`game_event_prerequisite` game event id (%i) is out of range compared to max event id in `game_event`", event_id);
+ TC_LOG_ERROR("sql.sql", "`game_event_prerequisite`: game event id (%i) is out of range compared to max event id in `game_event`.", event_id);
continue;
}
@@ -335,14 +341,14 @@ void GameEventMgr::LoadFromDB()
uint16 prerequisite_event = fields[1].GetUInt32();
if (prerequisite_event >= mGameEvent.size())
{
- TC_LOG_ERROR("sql.sql", "`game_event_prerequisite` game event prerequisite id (%i) is out of range compared to max event id in `game_event`", prerequisite_event);
+ TC_LOG_ERROR("sql.sql", "`game_event_prerequisite`: game event prerequisite id (%i) is out of range compared to max event id in `game_event`.", prerequisite_event);
continue;
}
mGameEvent[event_id].prerequisite_events.insert(prerequisite_event);
}
else
{
- TC_LOG_ERROR("sql.sql", "game_event_prerequisiste includes event entry for non-worldevent id %u", event_id);
+ TC_LOG_ERROR("sql.sql", "game_event_prerequisiste includes event entry for non-worldevent id %u.", event_id);
continue;
}
@@ -350,7 +356,7 @@ void GameEventMgr::LoadFromDB()
}
while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u game event prerequisites in game events in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u game event prerequisites in game events in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
}
@@ -363,7 +369,7 @@ void GameEventMgr::LoadFromDB()
QueryResult result = WorldDatabase.Query("SELECT guid, eventEntry FROM game_event_creature");
if (!result)
- TC_LOG_INFO("server.loading", ">> Loaded 0 creatures in game events. DB table `game_event_creature` is empty");
+ TC_LOG_INFO("server.loading", ">> Loaded 0 creatures in game events. DB table `game_event_creature` is empty.");
else
{
uint32 count = 0;
@@ -385,7 +391,7 @@ void GameEventMgr::LoadFromDB()
if (internal_event_id < 0 || internal_event_id >= int32(mGameEventCreatureGuids.size()))
{
- TC_LOG_ERROR("sql.sql", "`game_event_creature` game event id (%i) is out of range compared to max event id in `game_event`", event_id);
+ TC_LOG_ERROR("sql.sql", "`game_event_creature`: game event id (%i) is out of range compared to max event id in `game_event`.", event_id);
continue;
}
@@ -396,7 +402,7 @@ void GameEventMgr::LoadFromDB()
}
while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u creatures in game events in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u creatures in game events in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
}
@@ -431,7 +437,7 @@ void GameEventMgr::LoadFromDB()
if (internal_event_id < 0 || internal_event_id >= int32(mGameEventGameobjectGuids.size()))
{
- TC_LOG_ERROR("sql.sql", "`game_event_gameobject` game event id (%i) is out of range compared to max event id in `game_event`", event_id);
+ TC_LOG_ERROR("sql.sql", "`game_event_gameobject`: game event id (%i) is out of range compared to max event id in `game_event`.", event_id);
continue;
}
@@ -442,7 +448,7 @@ void GameEventMgr::LoadFromDB()
}
while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u gameobjects in game events in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u gameobjects in game events in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
}
@@ -469,7 +475,7 @@ void GameEventMgr::LoadFromDB()
if (event_id >= mGameEventModelEquip.size())
{
- TC_LOG_ERROR("sql.sql", "`game_event_model_equip` game event id (%u) is out of range compared to max event id in `game_event`", event_id);
+ TC_LOG_ERROR("sql.sql", "`game_event_model_equip`: game event id (%u) is out of range compared to max event id in `game_event`.", event_id);
continue;
}
@@ -485,7 +491,7 @@ void GameEventMgr::LoadFromDB()
int8 equipId = static_cast<int8>(newModelEquipSet.equipment_id);
if (!sObjectMgr->GetEquipmentInfo(entry, equipId))
{
- TC_LOG_ERROR("sql.sql", "Table `game_event_model_equip` have creature (Guid: %u, entry: %u) with equipment_id %u not found in table `creature_equip_template`, set to no equipment.",
+ TC_LOG_ERROR("sql.sql", "Table `game_event_model_equip` contains creature (Guid: %u, entry: %u) with equipment_id %u not found in table `creature_equip_template`. Setting entry to no equipment.",
guid, entry, newModelEquipSet.equipment_id);
continue;
}
@@ -497,7 +503,7 @@ void GameEventMgr::LoadFromDB()
}
while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u model/equipment changes in game events in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u model/equipment changes in game events in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
}
@@ -523,7 +529,7 @@ void GameEventMgr::LoadFromDB()
if (event_id >= mGameEventCreatureQuests.size())
{
- TC_LOG_ERROR("sql.sql", "`game_event_creature_quest` game event id (%u) is out of range compared to max event id in `game_event`", event_id);
+ TC_LOG_ERROR("sql.sql", "`game_event_creature_quest`: game event id (%u) is out of range compared to max event id in `game_event`.", event_id);
continue;
}
@@ -534,7 +540,7 @@ void GameEventMgr::LoadFromDB()
}
while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u quests additions in game events in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u quests additions in game events in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
}
@@ -560,7 +566,7 @@ void GameEventMgr::LoadFromDB()
if (event_id >= mGameEventGameObjectQuests.size())
{
- TC_LOG_ERROR("sql.sql", "`game_event_gameobject_quest` game event id (%u) is out of range compared to max event id in `game_event`", event_id);
+ TC_LOG_ERROR("sql.sql", "`game_event_gameobject_quest`: game event id (%u) is out of range compared to max event id in `game_event`.", event_id);
continue;
}
@@ -571,7 +577,7 @@ void GameEventMgr::LoadFromDB()
}
while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u quests additions in game events in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u quests additions in game events in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
}
@@ -598,7 +604,7 @@ void GameEventMgr::LoadFromDB()
if (event_id >= mGameEvent.size())
{
- TC_LOG_ERROR("sql.sql", "`game_event_quest_condition` game event id (%u) is out of range compared to max event id in `game_event`", event_id);
+ TC_LOG_ERROR("sql.sql", "`game_event_quest_condition`: game event id (%u) is out of range compared to max event id in `game_event`.", event_id);
continue;
}
@@ -610,7 +616,7 @@ void GameEventMgr::LoadFromDB()
}
while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u quest event conditions in game events in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u quest event conditions in game events in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
}
@@ -635,7 +641,7 @@ void GameEventMgr::LoadFromDB()
if (event_id >= mGameEvent.size())
{
- TC_LOG_ERROR("sql.sql", "`game_event_condition` game event id (%u) is out of range compared to max event id in `game_event`", event_id);
+ TC_LOG_ERROR("sql.sql", "`game_event_condition`: game event id (%u) is out of range compared to max event id in `game_event`.", event_id);
continue;
}
@@ -648,7 +654,7 @@ void GameEventMgr::LoadFromDB()
}
while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u conditions in game events in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u conditions in game events in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
}
@@ -673,7 +679,7 @@ void GameEventMgr::LoadFromDB()
if (event_id >= mGameEvent.size())
{
- TC_LOG_ERROR("sql.sql", "`game_event_condition_save` game event id (%u) is out of range compared to max event id in `game_event`", event_id);
+ TC_LOG_ERROR("sql.sql", "`game_event_condition_save`: game event id (%u) is out of range compared to max event id in `game_event`.", event_id);
continue;
}
@@ -684,7 +690,7 @@ void GameEventMgr::LoadFromDB()
}
else
{
- TC_LOG_ERROR("sql.sql", "game_event_condition_save contains not present condition evt id %u cond id %u", event_id, condition);
+ TC_LOG_ERROR("sql.sql", "game_event_condition_save contains not present condition event id %u condition id %u.", event_id, condition);
continue;
}
@@ -692,7 +698,7 @@ void GameEventMgr::LoadFromDB()
}
while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u condition saves in game events in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u condition saves in game events in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
}
@@ -718,7 +724,7 @@ void GameEventMgr::LoadFromDB()
if (event_id >= mGameEvent.size())
{
- TC_LOG_ERROR("sql.sql", "`game_event_npcflag` game event id (%u) is out of range compared to max event id in `game_event`", event_id);
+ TC_LOG_ERROR("sql.sql", "`game_event_npcflag`: game event id (%u) is out of range compared to max event id in `game_event`.", event_id);
continue;
}
@@ -728,7 +734,7 @@ void GameEventMgr::LoadFromDB()
}
while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u npcflags in game events in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u npcflags in game events in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
}
@@ -753,13 +759,13 @@ void GameEventMgr::LoadFromDB()
if (!sObjectMgr->GetQuestTemplate(questId))
{
- TC_LOG_ERROR("sql.sql", "`game_event_seasonal_questrelation` quest id (%u) does not exist in `quest_template`", questId);
+ TC_LOG_ERROR("sql.sql", "`game_event_seasonal_questrelation`: quest id (%u) does not exist in `quest_template`.", questId);
continue;
}
if (eventEntry >= mGameEvent.size())
{
- TC_LOG_ERROR("sql.sql", "`game_event_seasonal_questrelation` event id (%u) is out of range compared to max event in `game_event`", eventEntry);
+ TC_LOG_ERROR("sql.sql", "`game_event_seasonal_questrelation`: event id (%u) is out of range compared to max event in `game_event`.", eventEntry);
continue;
}
@@ -768,7 +774,7 @@ void GameEventMgr::LoadFromDB()
}
while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u quests additions in game events in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u quests additions in game events in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
}
@@ -792,7 +798,7 @@ void GameEventMgr::LoadFromDB()
if (event_id >= mGameEventVendors.size())
{
- TC_LOG_ERROR("sql.sql", "`game_event_npc_vendor` game event id (%u) is out of range compared to max event id in `game_event`", event_id);
+ TC_LOG_ERROR("sql.sql", "`game_event_npc_vendor`: game event id (%u) is out of range compared to max event id in `game_event`.", event_id);
continue;
}
@@ -830,7 +836,7 @@ void GameEventMgr::LoadFromDB()
}
while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u vendor additions in game events in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u vendor additions in game events in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
}
@@ -854,7 +860,7 @@ void GameEventMgr::LoadFromDB()
if (event_id >= mGameEvent.size())
{
- TC_LOG_ERROR("sql.sql", "`game_event_battleground_holiday` game event id (%u) is out of range compared to max event id in `game_event`", event_id);
+ TC_LOG_ERROR("sql.sql", "`game_event_battleground_holiday`: game event id (%u) is out of range compared to max event id in `game_event`.", event_id);
continue;
}
@@ -864,7 +870,7 @@ void GameEventMgr::LoadFromDB()
}
while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u battleground holidays in game events in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u battleground holidays in game events in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
}
@@ -892,13 +898,13 @@ void GameEventMgr::LoadFromDB()
if (internal_event_id < 0 || internal_event_id >= int32(mGameEventPoolIds.size()))
{
- TC_LOG_ERROR("sql.sql", "`game_event_pool` game event id (%i) is out of range compared to max event id in `game_event`", event_id);
+ TC_LOG_ERROR("sql.sql", "`game_event_pool`: game event id (%i) is out of range compared to max event id in `game_event`.", event_id);
continue;
}
if (!sPoolMgr->CheckPool(entry))
{
- TC_LOG_ERROR("sql.sql", "Pool Id (%u) has all creatures or gameobjects with explicit chance sum <>100 and no equal chance defined. The pool system cannot pick one to spawn.", entry);
+ TC_LOG_ERROR("sql.sql", "Pool Id (%u) has all creatures or gameobjects with explicit chance sum <> 100 and no equal chance defined. The pool system cannot pick one to spawn.", entry);
continue;
}
@@ -909,7 +915,7 @@ void GameEventMgr::LoadFromDB()
}
while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u pools for game events in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u pools for game events in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
}
}
@@ -971,7 +977,7 @@ void GameEventMgr::StartArenaSeason()
if (!result)
{
- TC_LOG_ERROR("gameevent", "ArenaSeason (%u) must be an existant Arena Season", season);
+ TC_LOG_ERROR("gameevent", "ArenaSeason (%u) must be an existing Arena Season.", season);
return;
}
@@ -980,7 +986,7 @@ void GameEventMgr::StartArenaSeason()
if (eventId >= mGameEvent.size())
{
- TC_LOG_ERROR("gameevent", "EventEntry %u for ArenaSeason (%u) does not exists", eventId, season);
+ TC_LOG_ERROR("gameevent", "EventEntry %u for ArenaSeason (%u) does not exist.", eventId, season);
return;
}
@@ -1171,7 +1177,7 @@ void GameEventMgr::GameEventSpawn(int16 event_id)
if (internal_event_id < 0 || internal_event_id >= int32(mGameEventCreatureGuids.size()))
{
- TC_LOG_ERROR("gameevent", "GameEventMgr::GameEventSpawn attempt access to out of range mGameEventCreatureGuids element %i (size: %zu)",
+ TC_LOG_ERROR("gameevent", "GameEventMgr::GameEventSpawn attempted access to out of range mGameEventCreatureGuids element %i (size: %zu).",
internal_event_id, mGameEventCreatureGuids.size());
return;
}
@@ -1198,7 +1204,7 @@ void GameEventMgr::GameEventSpawn(int16 event_id)
if (internal_event_id < 0 || internal_event_id >= int32(mGameEventGameobjectGuids.size()))
{
- TC_LOG_ERROR("gameevent", "GameEventMgr::GameEventSpawn attempt access to out of range mGameEventGameobjectGuids element %i (size: %zu)",
+ TC_LOG_ERROR("gameevent", "GameEventMgr::GameEventSpawn attempted access to out of range mGameEventGameobjectGuids element %i (size: %zu).",
internal_event_id, mGameEventGameobjectGuids.size());
return;
}
@@ -1231,7 +1237,7 @@ void GameEventMgr::GameEventSpawn(int16 event_id)
if (internal_event_id < 0 || internal_event_id >= int32(mGameEventPoolIds.size()))
{
- TC_LOG_ERROR("gameevent", "GameEventMgr::GameEventSpawn attempt access to out of range mGameEventPoolIds element %u (size: %zu)",
+ TC_LOG_ERROR("gameevent", "GameEventMgr::GameEventSpawn attempted access to out of range mGameEventPoolIds element %u (size: %zu).",
internal_event_id, mGameEventPoolIds.size());
return;
}
@@ -1246,7 +1252,7 @@ void GameEventMgr::GameEventUnspawn(int16 event_id)
if (internal_event_id < 0 || internal_event_id >= int32(mGameEventCreatureGuids.size()))
{
- TC_LOG_ERROR("gameevent", "GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventCreatureGuids element %i (size: %zu)",
+ TC_LOG_ERROR("gameevent", "GameEventMgr::GameEventUnspawn attempted access to out of range mGameEventCreatureGuids element %i (size: %zu).",
internal_event_id, mGameEventCreatureGuids.size());
return;
}
@@ -1276,7 +1282,7 @@ void GameEventMgr::GameEventUnspawn(int16 event_id)
if (internal_event_id < 0 || internal_event_id >= int32(mGameEventGameobjectGuids.size()))
{
- TC_LOG_ERROR("gameevent", "GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventGameobjectGuids element %i (size: %zu)",
+ TC_LOG_ERROR("gameevent", "GameEventMgr::GameEventUnspawn attempted access to out of range mGameEventGameobjectGuids element %i (size: %zu).",
internal_event_id, mGameEventGameobjectGuids.size());
return;
}
@@ -1305,7 +1311,7 @@ void GameEventMgr::GameEventUnspawn(int16 event_id)
}
if (internal_event_id < 0 || internal_event_id >= int32(mGameEventPoolIds.size()))
{
- TC_LOG_ERROR("gameevent", "GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventPoolIds element %u (size: %zu)", internal_event_id, mGameEventPoolIds.size());
+ TC_LOG_ERROR("gameevent", "GameEventMgr::GameEventUnspawn attempted access to out of range mGameEventPoolIds element %u (size: %zu).", internal_event_id, mGameEventPoolIds.size());
return;
}
diff --git a/src/server/game/Events/GameEventMgr.h b/src/server/game/Events/GameEventMgr.h
index b8d281dfdd7..44ed2fb1332 100644
--- a/src/server/game/Events/GameEventMgr.h
+++ b/src/server/game/Events/GameEventMgr.h
@@ -93,18 +93,14 @@ class Player;
class Creature;
class Quest;
-class GameEventMgr
+class TC_GAME_API GameEventMgr
{
private:
GameEventMgr();
~GameEventMgr() { }
public:
- static GameEventMgr* instance()
- {
- static GameEventMgr instance;
- return &instance;
- }
+ static GameEventMgr* instance();
typedef std::set<uint16> ActiveEvents;
typedef std::vector<GameEventData> GameEventDataMap;
@@ -186,8 +182,8 @@ class GameEventMgr
#define sGameEventMgr GameEventMgr::instance()
-bool IsHolidayActive(HolidayIds id);
-bool IsEventActive(uint16 event_id);
+TC_GAME_API bool IsHolidayActive(HolidayIds id);
+TC_GAME_API bool IsEventActive(uint16 event_id);
#endif
diff --git a/src/server/game/Globals/ObjectAccessor.cpp b/src/server/game/Globals/ObjectAccessor.cpp
index 762c9b9c28e..247c4943113 100644
--- a/src/server/game/Globals/ObjectAccessor.cpp
+++ b/src/server/game/Globals/ObjectAccessor.cpp
@@ -34,6 +34,53 @@
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/locks.hpp>
+template<class T>
+void HashMapHolder<T>::Insert(T* o)
+{
+ boost::unique_lock<boost::shared_mutex> lock(*GetLock());
+
+ GetContainer()[o->GetGUID()] = o;
+}
+
+template<class T>
+void HashMapHolder<T>::Remove(T* o)
+{
+ boost::unique_lock<boost::shared_mutex> lock(*GetLock());
+
+ GetContainer().erase(o->GetGUID());
+}
+
+template<class T>
+T* HashMapHolder<T>::Find(ObjectGuid guid)
+{
+ boost::shared_lock<boost::shared_mutex> lock(*GetLock());
+
+ typename MapType::iterator itr = GetContainer().find(guid);
+ return (itr != GetContainer().end()) ? itr->second : NULL;
+}
+
+template<class T>
+auto HashMapHolder<T>::GetContainer() -> MapType&
+{
+ static MapType _objectMap;
+ return _objectMap;
+}
+
+template<class T>
+boost::shared_mutex* HashMapHolder<T>::GetLock()
+{
+ static boost::shared_mutex _lock;
+ return &_lock;
+}
+
+HashMapHolder<Player>::MapType const& ObjectAccessor::GetPlayers()
+{
+ return HashMapHolder<Player>::GetContainer();
+}
+
+template class TC_GAME_API HashMapHolder<Player>;
+template class TC_GAME_API HashMapHolder<Transport>;
+
WorldObject* ObjectAccessor::GetWorldObject(WorldObject const& p, ObjectGuid const& guid)
{
switch (guid.GetHigh())
@@ -206,11 +253,6 @@ Player* ObjectAccessor::FindConnectedPlayerByName(std::string const& name)
return NULL;
}
-HashMapHolder<Player>::MapType const& ObjectAccessor::GetPlayers()
-{
- return HashMapHolder<Player>::GetContainer();
-}
-
void ObjectAccessor::SaveAllPlayers()
{
boost::shared_lock<boost::shared_mutex> lock(*HashMapHolder<Player>::GetLock());
@@ -219,14 +261,3 @@ void ObjectAccessor::SaveAllPlayers()
for (HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr)
itr->second->SaveToDB();
}
-
-/// Define the static members of HashMapHolder
-
-template <class T> typename HashMapHolder<T>::MapType HashMapHolder<T>::_objectMap;
-template <class T> boost::shared_mutex HashMapHolder<T>::_lock;
-
-/// Global definitions for the hashmap storage
-
-template class HashMapHolder<Player>;
-
-template class HashMapHolder<Transport>;
diff --git a/src/server/game/Globals/ObjectAccessor.h b/src/server/game/Globals/ObjectAccessor.h
index d8466dbb1bc..be7066c84a9 100644
--- a/src/server/game/Globals/ObjectAccessor.h
+++ b/src/server/game/Globals/ObjectAccessor.h
@@ -42,76 +42,56 @@ class WorldRunnable;
class Transport;
template <class T>
-class HashMapHolder
+class TC_GAME_API HashMapHolder
{
- public:
- static_assert(std::is_same<Player, T>::value
- || std::is_same<Transport, T>::value,
- "Only Player and Transport can be registered in global HashMapHolder");
+ //Non instanceable only static
+ HashMapHolder() { }
- typedef std::unordered_map<ObjectGuid, T*> MapType;
+public:
+ static_assert(std::is_same<Player, T>::value
+ || std::is_same<Transport, T>::value,
+ "Only Player and Transport can be registered in global HashMapHolder");
- static void Insert(T* o)
- {
- boost::unique_lock<boost::shared_mutex> lock(_lock);
+ typedef std::unordered_map<ObjectGuid, T*> MapType;
- _objectMap[o->GetGUID()] = o;
- }
+ static void Insert(T* o);
- static void Remove(T* o)
- {
- boost::unique_lock<boost::shared_mutex> lock(_lock);
+ static void Remove(T* o);
- _objectMap.erase(o->GetGUID());
- }
+ static T* Find(ObjectGuid guid);
- static T* Find(ObjectGuid guid)
- {
- boost::shared_lock<boost::shared_mutex> lock(_lock);
+ static MapType& GetContainer();
- typename MapType::iterator itr = _objectMap.find(guid);
- return (itr != _objectMap.end()) ? itr->second : NULL;
- }
-
- static MapType& GetContainer() { return _objectMap; }
-
- static boost::shared_mutex* GetLock() { return &_lock; }
-
- private:
- //Non instanceable only static
- HashMapHolder() { }
-
- static boost::shared_mutex _lock;
- static MapType _objectMap;
+ static boost::shared_mutex* GetLock();
};
namespace ObjectAccessor
{
// these functions return objects only if in map of specified object
- WorldObject* GetWorldObject(WorldObject const&, ObjectGuid const&);
- Object* GetObjectByTypeMask(WorldObject const&, ObjectGuid const&, uint32 typemask);
- Corpse* GetCorpse(WorldObject const& u, ObjectGuid const& guid);
- GameObject* GetGameObject(WorldObject const& u, ObjectGuid const& guid);
- Transport* GetTransport(WorldObject const& u, ObjectGuid const& guid);
- DynamicObject* GetDynamicObject(WorldObject const& u, ObjectGuid const& guid);
- Unit* GetUnit(WorldObject const&, ObjectGuid const& guid);
- Creature* GetCreature(WorldObject const& u, ObjectGuid const& guid);
- Pet* GetPet(WorldObject const&, ObjectGuid const& guid);
- Player* GetPlayer(Map const*, ObjectGuid const& guid);
- Player* GetPlayer(WorldObject const&, ObjectGuid const& guid);
- Creature* GetCreatureOrPetOrVehicle(WorldObject const&, ObjectGuid const&);
+ TC_GAME_API WorldObject* GetWorldObject(WorldObject const&, ObjectGuid const&);
+ TC_GAME_API Object* GetObjectByTypeMask(WorldObject const&, ObjectGuid const&, uint32 typemask);
+ TC_GAME_API Corpse* GetCorpse(WorldObject const& u, ObjectGuid const& guid);
+ TC_GAME_API GameObject* GetGameObject(WorldObject const& u, ObjectGuid const& guid);
+ TC_GAME_API Transport* GetTransport(WorldObject const& u, ObjectGuid const& guid);
+ TC_GAME_API DynamicObject* GetDynamicObject(WorldObject const& u, ObjectGuid const& guid);
+ TC_GAME_API Unit* GetUnit(WorldObject const&, ObjectGuid const& guid);
+ TC_GAME_API Creature* GetCreature(WorldObject const& u, ObjectGuid const& guid);
+ TC_GAME_API Pet* GetPet(WorldObject const&, ObjectGuid const& guid);
+ TC_GAME_API Player* GetPlayer(Map const*, ObjectGuid const& guid);
+ TC_GAME_API Player* GetPlayer(WorldObject const&, ObjectGuid const& guid);
+ TC_GAME_API Creature* GetCreatureOrPetOrVehicle(WorldObject const&, ObjectGuid const&);
// these functions return objects if found in whole world
// ACCESS LIKE THAT IS NOT THREAD SAFE
- Player* FindPlayer(ObjectGuid const&);
- Player* FindPlayerByName(std::string const& name);
+ TC_GAME_API Player* FindPlayer(ObjectGuid const&);
+ TC_GAME_API Player* FindPlayerByName(std::string const& name);
// this returns Player even if he is not in world, for example teleporting
- Player* FindConnectedPlayer(ObjectGuid const&);
- Player* FindConnectedPlayerByName(std::string const& name);
+ TC_GAME_API Player* FindConnectedPlayer(ObjectGuid const&);
+ TC_GAME_API Player* FindConnectedPlayerByName(std::string const& name);
// when using this, you must use the hashmapholder's lock
- HashMapHolder<Player>::MapType const& GetPlayers();
+ TC_GAME_API HashMapHolder<Player>::MapType const& GetPlayers();
template<class T>
void AddObject(T* object)
@@ -125,7 +105,8 @@ namespace ObjectAccessor
HashMapHolder<T>::Remove(object);
}
- void SaveAllPlayers();
+ TC_GAME_API void SaveAllPlayers();
};
#endif
+
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index f45634e9684..fc7d668ae0b 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -235,6 +235,12 @@ ObjectMgr::ObjectMgr():
}
}
+ObjectMgr* ObjectMgr::instance()
+{
+ static ObjectMgr instance;
+ return &instance;
+}
+
ObjectMgr::~ObjectMgr()
{
for (QuestMap::iterator i = _questTemplates.begin(); i != _questTemplates.end(); ++i)
@@ -6502,7 +6508,12 @@ uint32 ObjectMgr::GenerateMailID()
uint32 ObjectMgr::GeneratePetNumber()
{
- return ++_hiPetNumber;
+ if (_hiPetNumber >= 0xFFFFFFFE)
+ {
+ TC_LOG_ERROR("misc", "_hiPetNumber Id overflow!! Can't continue, shutting down server. ");
+ World::StopNow(ERROR_EXIT_CODE);
+ }
+ return _hiPetNumber++;
}
uint32 ObjectMgr::GenerateCreatureSpawnId()
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index ae1258713f5..73c03849699 100644
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -372,15 +372,15 @@ typedef std::multimap<uint32, ScriptInfo> ScriptMap;
typedef std::map<uint32, ScriptMap > ScriptMapMap;
typedef std::multimap<uint32, uint32> SpellScriptsContainer;
typedef std::pair<SpellScriptsContainer::iterator, SpellScriptsContainer::iterator> SpellScriptsBounds;
-extern ScriptMapMap sSpellScripts;
-extern ScriptMapMap sEventScripts;
-extern ScriptMapMap sWaypointScripts;
+TC_GAME_API extern ScriptMapMap sSpellScripts;
+TC_GAME_API extern ScriptMapMap sEventScripts;
+TC_GAME_API extern ScriptMapMap sWaypointScripts;
std::string GetScriptsTableNameByType(ScriptsType type);
ScriptMapMap* GetScriptsMapByType(ScriptsType type);
std::string GetScriptCommandName(ScriptCommands command);
-struct SpellClickInfo
+struct TC_GAME_API SpellClickInfo
{
uint32 spellId;
uint8 castFlags;
@@ -637,7 +637,7 @@ SkillRangeType GetSkillRangeType(SkillRaceClassInfoEntry const* rcEntry);
#define MAX_PET_NAME 12 // max allowed by client name length
#define MAX_CHARTER_NAME 24 // max allowed by client name length
-bool normalizePlayerName(std::string& name);
+TC_GAME_API bool normalizePlayerName(std::string& name);
struct LanguageDesc
{
@@ -646,7 +646,7 @@ struct LanguageDesc
uint32 skill_id;
};
-extern LanguageDesc lang_description[LANGUAGES_COUNT];
+TC_GAME_API extern LanguageDesc lang_description[LANGUAGES_COUNT];
LanguageDesc const* GetLanguageDescByID(uint32 lang);
enum EncounterCreditType
@@ -671,7 +671,7 @@ typedef std::unordered_map<uint32, DungeonEncounterList> DungeonEncounterContain
class PlayerDumpReader;
-class ObjectMgr
+class TC_GAME_API ObjectMgr
{
friend class PlayerDumpReader;
@@ -680,11 +680,13 @@ class ObjectMgr
~ObjectMgr();
public:
- static ObjectMgr* instance()
- {
- static ObjectMgr instance;
- return &instance;
- }
+ ObjectMgr(ObjectMgr const&) = delete;
+ ObjectMgr(ObjectMgr&&) = delete;
+
+ ObjectMgr& operator= (ObjectMgr const&) = delete;
+ ObjectMgr& operator= (ObjectMgr&&) = delete;
+
+ static ObjectMgr* instance();
typedef std::unordered_map<uint32, Item*> ItemMap;
diff --git a/src/server/game/Grids/GridReference.h b/src/server/game/Grids/GridReference.h
index b1f2e92a840..f5766382822 100644
--- a/src/server/game/Grids/GridReference.h
+++ b/src/server/game/Grids/GridReference.h
@@ -28,18 +28,18 @@ template<class OBJECT>
class GridReference : public Reference<GridRefManager<OBJECT>, OBJECT>
{
protected:
- void targetObjectBuildLink()
+ void targetObjectBuildLink() override
{
// called from link()
this->getTarget()->insertFirst(this);
this->getTarget()->incSize();
}
- void targetObjectDestroyLink()
+ void targetObjectDestroyLink() override
{
// called from unlink()
if (this->isValid()) this->getTarget()->decSize();
}
- void sourceObjectDestroyLink()
+ void sourceObjectDestroyLink() override
{
// called from invalidate()
this->getTarget()->decSize();
diff --git a/src/server/game/Grids/GridStates.h b/src/server/game/Grids/GridStates.h
index 9420bef4b9d..b567da43b69 100644
--- a/src/server/game/Grids/GridStates.h
+++ b/src/server/game/Grids/GridStates.h
@@ -24,32 +24,32 @@
class Map;
-class GridState
+class TC_GAME_API GridState
{
public:
virtual ~GridState() { };
virtual void Update(Map &, NGridType&, GridInfo &, uint32 t_diff) const = 0;
};
-class InvalidState : public GridState
+class TC_GAME_API InvalidState : public GridState
{
public:
void Update(Map &, NGridType &, GridInfo &, uint32 t_diff) const override;
};
-class ActiveState : public GridState
+class TC_GAME_API ActiveState : public GridState
{
public:
void Update(Map &, NGridType &, GridInfo &, uint32 t_diff) const override;
};
-class IdleState : public GridState
+class TC_GAME_API IdleState : public GridState
{
public:
void Update(Map &, NGridType &, GridInfo &, uint32 t_diff) const override;
};
-class RemovalState : public GridState
+class TC_GAME_API RemovalState : public GridState
{
public:
void Update(Map &, NGridType &, GridInfo &, uint32 t_diff) const override;
diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h
index 6edeadf6b94..84aa29f96b7 100644
--- a/src/server/game/Grids/Notifiers/GridNotifiers.h
+++ b/src/server/game/Grids/Notifiers/GridNotifiers.h
@@ -38,7 +38,7 @@ class Player;
namespace Trinity
{
- struct VisibleNotifier
+ struct TC_GAME_API VisibleNotifier
{
Player &i_player;
UpdateData i_data;
@@ -61,7 +61,7 @@ namespace Trinity
void Visit(DynamicObjectMapType &);
};
- struct PlayerRelocationNotifier : public VisibleNotifier
+ struct TC_GAME_API PlayerRelocationNotifier : public VisibleNotifier
{
PlayerRelocationNotifier(Player &player) : VisibleNotifier(player) { }
@@ -70,7 +70,7 @@ namespace Trinity
void Visit(PlayerMapType &);
};
- struct CreatureRelocationNotifier
+ struct TC_GAME_API CreatureRelocationNotifier
{
Creature &i_creature;
CreatureRelocationNotifier(Creature &c) : i_creature(c) { }
@@ -79,7 +79,7 @@ namespace Trinity
void Visit(PlayerMapType &);
};
- struct DelayedUnitRelocation
+ struct TC_GAME_API DelayedUnitRelocation
{
Map &i_map;
Cell &cell;
@@ -92,7 +92,7 @@ namespace Trinity
void Visit(PlayerMapType &);
};
- struct AIRelocationNotifier
+ struct TC_GAME_API AIRelocationNotifier
{
Unit &i_unit;
bool isCreature;
@@ -120,7 +120,7 @@ namespace Trinity
void Visit(CorpseMapType &m) { updateObjects<Corpse>(m); }
};
- struct MessageDistDeliverer
+ struct TC_GAME_API MessageDistDeliverer
{
WorldObject* i_source;
WorldPacket* i_message;
@@ -566,7 +566,7 @@ namespace Trinity
// WorldObject check classes
- class AnyDeadUnitObjectInRangeCheck
+ class TC_GAME_API AnyDeadUnitObjectInRangeCheck
{
public:
AnyDeadUnitObjectInRangeCheck(Unit* searchObj, float range) : i_searchObj(searchObj), i_range(range) { }
@@ -579,7 +579,7 @@ namespace Trinity
float i_range;
};
- class AnyDeadUnitSpellTargetInRangeCheck : public AnyDeadUnitObjectInRangeCheck
+ class TC_GAME_API AnyDeadUnitSpellTargetInRangeCheck : public AnyDeadUnitObjectInRangeCheck
{
public:
AnyDeadUnitSpellTargetInRangeCheck(Unit* searchObj, float range, SpellInfo const* spellInfo, SpellTargetCheckTypes check)
diff --git a/src/server/game/Grids/ObjectGridLoader.h b/src/server/game/Grids/ObjectGridLoader.h
index 9dc4c7e048b..f2893da609e 100644
--- a/src/server/game/Grids/ObjectGridLoader.h
+++ b/src/server/game/Grids/ObjectGridLoader.h
@@ -27,7 +27,7 @@
class ObjectWorldLoader;
-class ObjectGridLoader
+class TC_GAME_API ObjectGridLoader
{
friend class ObjectWorldLoader;
@@ -55,7 +55,7 @@ class ObjectGridLoader
};
//Stop the creatures before unloading the NGrid
-class ObjectGridStoper
+class TC_GAME_API ObjectGridStoper
{
public:
void Visit(CreatureMapType &m);
@@ -63,7 +63,7 @@ class ObjectGridStoper
};
//Move the foreign creatures back to respawn positions before unloading the NGrid
-class ObjectGridEvacuator
+class TC_GAME_API ObjectGridEvacuator
{
public:
void Visit(CreatureMapType &m);
diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h
index 42fd9b582e8..18b8119246f 100644
--- a/src/server/game/Groups/Group.h
+++ b/src/server/game/Groups/Group.h
@@ -158,7 +158,7 @@ struct InstanceGroupBind
/** request member stats checken **/
/// @todo uninvite people that not accepted invite
-class Group
+class TC_GAME_API Group
{
public:
struct MemberSlot
diff --git a/src/server/game/Groups/GroupMgr.cpp b/src/server/game/Groups/GroupMgr.cpp
index 0fd2e7c7095..a5aa432aadc 100644
--- a/src/server/game/Groups/GroupMgr.cpp
+++ b/src/server/game/Groups/GroupMgr.cpp
@@ -92,6 +92,12 @@ ObjectGuid::LowType GroupMgr::GenerateGroupId()
return NextGroupId++;
}
+GroupMgr* GroupMgr::instance()
+{
+ static GroupMgr instance;
+ return &instance;
+}
+
Group* GroupMgr::GetGroupByGUID(ObjectGuid::LowType groupId) const
{
GroupContainer::const_iterator itr = GroupStore.find(groupId);
diff --git a/src/server/game/Groups/GroupMgr.h b/src/server/game/Groups/GroupMgr.h
index 9afdddd0f18..14ff3519aa6 100644
--- a/src/server/game/Groups/GroupMgr.h
+++ b/src/server/game/Groups/GroupMgr.h
@@ -20,18 +20,14 @@
#include "Group.h"
-class GroupMgr
+class TC_GAME_API GroupMgr
{
private:
GroupMgr();
~GroupMgr();
public:
- static GroupMgr* instance()
- {
- static GroupMgr instance;
- return &instance;
- }
+ static GroupMgr* instance();
typedef std::map<ObjectGuid::LowType, Group*> GroupContainer;
typedef std::vector<Group*> GroupDbContainer;
diff --git a/src/server/game/Groups/GroupReference.h b/src/server/game/Groups/GroupReference.h
index 4718dda1832..6e7373de7d7 100644
--- a/src/server/game/Groups/GroupReference.h
+++ b/src/server/game/Groups/GroupReference.h
@@ -24,7 +24,7 @@
class Group;
class Player;
-class GroupReference : public Reference<Group, Player>
+class TC_GAME_API GroupReference : public Reference<Group, Player>
{
protected:
uint8 iSubGroup;
diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h
index 2bc57a70671..e25a3201957 100644
--- a/src/server/game/Guilds/Guild.h
+++ b/src/server/game/Guilds/Guild.h
@@ -223,7 +223,7 @@ enum GuildMemberFlags
};
// Emblem info
-class EmblemInfo
+class TC_GAME_API EmblemInfo
{
public:
EmblemInfo() : m_style(0), m_color(0), m_borderStyle(0), m_borderColor(0), m_backgroundColor(0) { }
@@ -279,7 +279,7 @@ typedef std::vector <GuildBankRightsAndSlots> GuildBankRightsAndSlotsVec;
typedef std::set <uint8> SlotIds;
-class Guild
+class TC_GAME_API Guild
{
private:
// Class representing guild member
diff --git a/src/server/game/Guilds/GuildMgr.cpp b/src/server/game/Guilds/GuildMgr.cpp
index 2d4fb849fb5..a4d245cbc9b 100644
--- a/src/server/game/Guilds/GuildMgr.cpp
+++ b/src/server/game/Guilds/GuildMgr.cpp
@@ -79,6 +79,12 @@ std::string GuildMgr::GetGuildNameById(ObjectGuid::LowType guildId) const
return "";
}
+GuildMgr* GuildMgr::instance()
+{
+ static GuildMgr instance;
+ return &instance;
+}
+
Guild* GuildMgr::GetGuildByLeader(ObjectGuid guid) const
{
for (GuildContainer::const_iterator itr = GuildStore.begin(); itr != GuildStore.end(); ++itr)
diff --git a/src/server/game/Guilds/GuildMgr.h b/src/server/game/Guilds/GuildMgr.h
index a97a59cafe0..ad2555c2e71 100644
--- a/src/server/game/Guilds/GuildMgr.h
+++ b/src/server/game/Guilds/GuildMgr.h
@@ -20,18 +20,14 @@
#include "Guild.h"
-class GuildMgr
+class TC_GAME_API GuildMgr
{
private:
GuildMgr();
~GuildMgr();
public:
- static GuildMgr* instance()
- {
- static GuildMgr instance;
- return &instance;
- }
+ static GuildMgr* instance();
Guild* GetGuildByLeader(ObjectGuid guid) const;
Guild* GetGuildById(ObjectGuid::LowType guildId) const;
diff --git a/src/server/game/Handlers/AddonHandler.cpp b/src/server/game/Handlers/AddonHandler.cpp
index ad44e0993e4..c72fc08982c 100644
--- a/src/server/game/Handlers/AddonHandler.cpp
+++ b/src/server/game/Handlers/AddonHandler.cpp
@@ -21,6 +21,12 @@
#include "Opcodes.h"
#include "Log.h"
+AddonHandler* AddonHandler::instance()
+{
+ static AddonHandler instance;
+ return &instance;
+}
+
bool AddonHandler::BuildAddonPacket(WorldPacket* source, WorldPacket* target)
{
ByteBuffer AddOnPacked;
diff --git a/src/server/game/Handlers/AddonHandler.h b/src/server/game/Handlers/AddonHandler.h
index 1e8081e0913..0113695895a 100644
--- a/src/server/game/Handlers/AddonHandler.h
+++ b/src/server/game/Handlers/AddonHandler.h
@@ -26,11 +26,7 @@
class AddonHandler
{
public:
- static AddonHandler* instance()
- {
- static AddonHandler instance;
- return &instance;
- }
+ static AddonHandler* instance();
bool BuildAddonPacket(WorldPacket* Source, WorldPacket* Target);
diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp
index 540eeba0752..1a654335714 100644
--- a/src/server/game/Handlers/CalendarHandler.cpp
+++ b/src/server/game/Handlers/CalendarHandler.cpp
@@ -700,7 +700,7 @@ void WorldSession::HandleSetSavedInstanceExtend(WorldPacket& recvData)
InstancePlayerBind* instanceBind = player->GetBoundInstance(mapId, Difficulty(difficulty), toggleExtend == 1); // include expired instances if we are toggling extend on
if (!instanceBind || !instanceBind->save || !instanceBind->perm)
return;
-
+
BindExtensionState newState;
if (!toggleExtend || instanceBind->extendState == EXTEND_STATE_EXPIRED)
newState = EXTEND_STATE_NORMAL;
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index e0d790312d2..2b4b77dc7a9 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -228,11 +228,11 @@ void WorldSession::HandleCharEnum(PreparedQueryResult result)
if (Player::BuildEnumData(result, &data))
{
// Do not allow banned characters to log in
- if (!(*result)[20].GetUInt32())
+ if (!(*result)[23].GetUInt32())
_legitCharacters.insert(guid);
if (!sWorld->HasCharacterInfo(guid)) // This can happen if characters are inserted into the database manually. Core hasn't loaded name data yet.
- sWorld->AddCharacterInfo(guid, GetAccountId(), (*result)[1].GetString(), (*result)[4].GetUInt8(), (*result)[2].GetUInt8(), (*result)[3].GetUInt8(), (*result)[7].GetUInt8());
+ sWorld->AddCharacterInfo(guid, GetAccountId(), (*result)[1].GetString(), (*result)[4].GetUInt8(), (*result)[2].GetUInt8(), (*result)[3].GetUInt8(), (*result)[10].GetUInt8());
++num;
}
}
@@ -627,13 +627,13 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_REALM_CHARACTERS_BY_REALM);
stmt->setUInt32(0, GetAccountId());
- stmt->setUInt32(1, realmID);
+ stmt->setUInt32(1, realm.Id.Realm);
trans->Append(stmt);
stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_REALM_CHARACTERS);
stmt->setUInt32(0, createInfo->CharCount);
stmt->setUInt32(1, GetAccountId());
- stmt->setUInt32(2, realmID);
+ stmt->setUInt32(2, realm.Id.Realm);
trans->Append(stmt);
LoginDatabase.CommitTransaction(trans);
diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp
index aaf6ca39d09..36df5b64f1b 100644
--- a/src/server/game/Handlers/MailHandler.cpp
+++ b/src/server/game/Handlers/MailHandler.cpp
@@ -35,7 +35,7 @@ bool WorldSession::CanOpenMailBox(ObjectGuid guid)
{
if (!HasPermission(rbac::RBAC_PERM_COMMAND_MAILBOX))
{
- TC_LOG_WARN("cheat", "%s attempt open mailbox in cheating way.", _player->GetName().c_str());
+ TC_LOG_WARN("cheat", "%s attempted to open mailbox by using a cheat.", _player->GetName().c_str());
return false;
}
}
@@ -108,7 +108,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
if (!receiverGuid)
{
- TC_LOG_INFO("network", "Player %u is sending mail to %s (GUID: not existed!) with subject %s "
+ TC_LOG_INFO("network", "Player %u is sending mail to %s (GUID: non-existing!) with subject %s "
"and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u",
player->GetGUID().GetCounter(), receiverName.c_str(), subject.c_str(), body.c_str(),
items_count, money, COD, stationery, package);
@@ -117,7 +117,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
}
TC_LOG_INFO("network", "Player %u is sending mail to %s (%s) with subject %s and body %s "
- "includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u",
+ "including %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u",
player->GetGUID().GetCounter(), receiverName.c_str(), receiverGuid.ToString().c_str(), subject.c_str(),
body.c_str(), items_count, money, COD, stationery, package);
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 5f5a66e7b20..91df877e936 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -569,7 +569,7 @@ void WorldSession::HandleAddFriendOpcodeCallBack(PreparedQueryResult result, std
team = Player::TeamForRace(fields[1].GetUInt8());
friendAccountId = fields[2].GetUInt32();
- if (HasPermission(rbac::RBAC_PERM_ALLOW_GM_FRIEND) || AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realmID)))
+ if (HasPermission(rbac::RBAC_PERM_ALLOW_GM_FRIEND) || AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realm.Id.Realm)))
{
if (friendGuid)
{
@@ -773,17 +773,11 @@ void WorldSession::HandleResurrectResponseOpcode(WorldPacket& recvData)
if (status == 0)
{
- GetPlayer()->clearResurrectRequestData(); // reject
+ GetPlayer()->ClearResurrectRequestData(); // reject
return;
}
- if (GetPlayer()->IsValidGhoulResurrectRequest(guid))
- {
- GetPlayer()->GhoulResurrect();
- return;
- }
-
- if (!GetPlayer()->isResurrectRequestedBy(guid))
+ if (!GetPlayer()->IsResurrectRequestedBy(guid))
return;
GetPlayer()->ResurrectUsingRequestData();
@@ -933,7 +927,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recvData)
default:
break;
}
-
+
if (reviveAtTrigger) // check if the player is touching the areatrigger leading to the map his corpse is on
if (!player->IsAlive() && player->HasCorpse())
if (player->GetCorpseLocation().GetMapId() == at->target_mapId)
@@ -1203,7 +1197,7 @@ void WorldSession::HandleInspectOpcode(WorldPacket& recvData)
WorldPacket data(SMSG_INSPECT_TALENT, guid_size+4+talent_points);
data << player->GetPackGUID();
- if (sWorld->getBoolConfig(CONFIG_TALENTS_INSPECTING) || _player->IsGameMaster())
+ if (GetPlayer()->CanBeGameMaster() || sWorld->getIntConfig(CONFIG_TALENTS_INSPECTING) + (GetPlayer()->GetTeamId() == player->GetTeamId()) > 1)
player->BuildPlayerTalentsInfoData(&data);
else
{
diff --git a/src/server/game/Instances/InstanceSaveMgr.cpp b/src/server/game/Instances/InstanceSaveMgr.cpp
index 3538262ed35..2fbf50cb020 100644
--- a/src/server/game/Instances/InstanceSaveMgr.cpp
+++ b/src/server/game/Instances/InstanceSaveMgr.cpp
@@ -38,6 +38,12 @@ InstanceSaveManager::~InstanceSaveManager()
{
}
+InstanceSaveManager* InstanceSaveManager::instance()
+{
+ static InstanceSaveManager instance;
+ return &instance;
+}
+
void InstanceSaveManager::Unload()
{
lock_instLists = true;
@@ -447,7 +453,7 @@ time_t InstanceSaveManager::GetSubsequentResetTime(uint32 mapid, Difficulty diff
TC_LOG_ERROR("misc", "InstanceSaveManager::GetSubsequentResetTime: not valid difficulty or no reset delay for map %u", mapid);
return 0;
}
-
+
time_t diff = sWorld->getIntConfig(CONFIG_INSTANCE_RESET_TIME_HOUR) * HOUR;
time_t period = uint32(((mapDiff->resetTime * sWorld->getRate(RATE_INSTANCE_RESET_TIME)) / DAY) * DAY);
if (period < DAY)
diff --git a/src/server/game/Instances/InstanceSaveMgr.h b/src/server/game/Instances/InstanceSaveMgr.h
index d2b3237b3cf..18e22602e07 100644
--- a/src/server/game/Instances/InstanceSaveMgr.h
+++ b/src/server/game/Instances/InstanceSaveMgr.h
@@ -41,7 +41,7 @@ class Group;
- player-instance binds for permanent heroic/raid saves
- group-instance binds (both solo and permanent) cache the player binds for the group leader
*/
-class InstanceSave
+class TC_GAME_API InstanceSave
{
friend class InstanceSaveManager;
public:
@@ -147,7 +147,7 @@ class InstanceSave
typedef std::unordered_map<uint32 /*PAIR32(map, difficulty)*/, time_t /*resetTime*/> ResetTimeByMapDifficultyMap;
-class InstanceSaveManager
+class TC_GAME_API InstanceSaveManager
{
friend class InstanceSave;
@@ -158,11 +158,7 @@ class InstanceSaveManager
public:
typedef std::unordered_map<uint32 /*InstanceId*/, InstanceSave*> InstanceSaveHashMap;
- static InstanceSaveManager* instance()
- {
- static InstanceSaveManager instance;
- return &instance;
- }
+ static InstanceSaveManager* instance();
void Unload();
diff --git a/src/server/game/Instances/InstanceScript.h b/src/server/game/Instances/InstanceScript.h
index ce83061e162..949cdf5abcb 100644
--- a/src/server/game/Instances/InstanceScript.h
+++ b/src/server/game/Instances/InstanceScript.h
@@ -79,7 +79,7 @@ struct BossBoundaryEntry
AreaBoundary const* Boundary;
};
-struct BossBoundaryData
+struct TC_GAME_API BossBoundaryData
{
typedef std::vector<BossBoundaryEntry> StorageType;
typedef StorageType::const_iterator const_iterator;
@@ -134,7 +134,7 @@ typedef std::map<uint32 /*entry*/, MinionInfo> MinionInfoMap;
typedef std::map<uint32 /*type*/, ObjectGuid /*guid*/> ObjectGuidMap;
typedef std::map<uint32 /*entry*/, uint32 /*type*/> ObjectInfoMap;
-class InstanceScript : public ZoneScript
+class TC_GAME_API InstanceScript : public ZoneScript
{
public:
explicit InstanceScript(Map* map) : instance(map), completedEncounters(0) { }
diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp
index 19dc210ea5b..5cede9a32d5 100644
--- a/src/server/game/Loot/LootMgr.cpp
+++ b/src/server/game/Loot/LootMgr.cpp
@@ -1871,3 +1871,20 @@ void LoadLootTemplates_Reference()
TC_LOG_INFO("server.loading", ">> Loaded refence loot templates in %u ms", GetMSTimeDiffToNow(oldMSTime));
}
+
+void LoadLootTables()
+{
+ LoadLootTemplates_Creature();
+ LoadLootTemplates_Fishing();
+ LoadLootTemplates_Gameobject();
+ LoadLootTemplates_Item();
+ LoadLootTemplates_Mail();
+ LoadLootTemplates_Milling();
+ LoadLootTemplates_Pickpocketing();
+ LoadLootTemplates_Skinning();
+ LoadLootTemplates_Disenchant();
+ LoadLootTemplates_Prospecting();
+ LoadLootTemplates_Spell();
+
+ LoadLootTemplates_Reference();
+}
diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h
index af6f3e56707..41feb7b26e2 100644
--- a/src/server/game/Loot/LootMgr.h
+++ b/src/server/game/Loot/LootMgr.h
@@ -122,7 +122,7 @@ enum LootSlotType
class Player;
class LootStore;
-struct LootStoreItem
+struct TC_GAME_API LootStoreItem
{
uint32 itemid; // id of the item
uint32 reference; // referenced TemplateleId
@@ -148,7 +148,7 @@ struct LootStoreItem
typedef std::set<ObjectGuid::LowType> AllowedLooterSet;
-struct LootItem
+struct TC_GAME_API LootItem
{
uint32 itemid;
uint32 randomSuffix;
@@ -203,7 +203,7 @@ typedef std::unordered_map<uint32, LootTemplate*> LootTemplateMap;
typedef std::set<uint32> LootIdSet;
-class LootStore
+class TC_GAME_API LootStore
{
public:
explicit LootStore(char const* name, char const* entryName, bool ratesAllowed)
@@ -239,7 +239,7 @@ class LootStore
bool m_ratesAllowed;
};
-class LootTemplate
+class TC_GAME_API LootTemplate
{
class LootGroup; // A set of loot definitions for items (refs are not allowed inside)
typedef std::vector<LootGroup*> LootGroups;
@@ -307,7 +307,7 @@ struct LootView;
ByteBuffer& operator<<(ByteBuffer& b, LootItem const& li);
ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv);
-struct Loot
+struct TC_GAME_API Loot
{
friend ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv);
@@ -409,48 +409,33 @@ struct LootView
: 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_Mail;
-extern LootStore LootTemplates_Milling;
-extern LootStore LootTemplates_Pickpocketing;
-extern LootStore LootTemplates_Reference;
-extern LootStore LootTemplates_Skinning;
-extern LootStore LootTemplates_Disenchant;
-extern LootStore LootTemplates_Prospecting;
-extern LootStore LootTemplates_Spell;
-
-void LoadLootTemplates_Creature();
-void LoadLootTemplates_Fishing();
-void LoadLootTemplates_Gameobject();
-void LoadLootTemplates_Item();
-void LoadLootTemplates_Mail();
-void LoadLootTemplates_Milling();
-void LoadLootTemplates_Pickpocketing();
-void LoadLootTemplates_Skinning();
-void LoadLootTemplates_Disenchant();
-void LoadLootTemplates_Prospecting();
-
-void LoadLootTemplates_Spell();
-void LoadLootTemplates_Reference();
-
-inline void LoadLootTables()
-{
- LoadLootTemplates_Creature();
- LoadLootTemplates_Fishing();
- LoadLootTemplates_Gameobject();
- LoadLootTemplates_Item();
- LoadLootTemplates_Mail();
- LoadLootTemplates_Milling();
- LoadLootTemplates_Pickpocketing();
- LoadLootTemplates_Skinning();
- LoadLootTemplates_Disenchant();
- LoadLootTemplates_Prospecting();
- LoadLootTemplates_Spell();
-
- LoadLootTemplates_Reference();
-}
+TC_GAME_API extern LootStore LootTemplates_Creature;
+TC_GAME_API extern LootStore LootTemplates_Fishing;
+TC_GAME_API extern LootStore LootTemplates_Gameobject;
+TC_GAME_API extern LootStore LootTemplates_Item;
+TC_GAME_API extern LootStore LootTemplates_Mail;
+TC_GAME_API extern LootStore LootTemplates_Milling;
+TC_GAME_API extern LootStore LootTemplates_Pickpocketing;
+TC_GAME_API extern LootStore LootTemplates_Reference;
+TC_GAME_API extern LootStore LootTemplates_Skinning;
+TC_GAME_API extern LootStore LootTemplates_Disenchant;
+TC_GAME_API extern LootStore LootTemplates_Prospecting;
+TC_GAME_API extern LootStore LootTemplates_Spell;
+
+TC_GAME_API void LoadLootTemplates_Creature();
+TC_GAME_API void LoadLootTemplates_Fishing();
+TC_GAME_API void LoadLootTemplates_Gameobject();
+TC_GAME_API void LoadLootTemplates_Item();
+TC_GAME_API void LoadLootTemplates_Mail();
+TC_GAME_API void LoadLootTemplates_Milling();
+TC_GAME_API void LoadLootTemplates_Pickpocketing();
+TC_GAME_API void LoadLootTemplates_Skinning();
+TC_GAME_API void LoadLootTemplates_Disenchant();
+TC_GAME_API void LoadLootTemplates_Prospecting();
+
+TC_GAME_API void LoadLootTemplates_Spell();
+TC_GAME_API void LoadLootTemplates_Reference();
+
+TC_GAME_API void LoadLootTables();
#endif
diff --git a/src/server/game/Mails/Mail.cpp b/src/server/game/Mails/Mail.cpp
index b0e8a1ebe02..bc31a3c8c06 100644
--- a/src/server/game/Mails/Mail.cpp
+++ b/src/server/game/Mails/Mail.cpp
@@ -49,8 +49,8 @@ MailSender::MailSender(Object* sender, MailStationery stationery) : m_stationery
break;
default:
m_messageType = MAIL_NORMAL;
- m_senderId = 0; // will show mail from not existed player
- TC_LOG_ERROR("misc", "MailSender::MailSender - Mail have unexpected sender typeid (%u)", sender->GetTypeId());
+ m_senderId = 0; // will show mail from non-existing player
+ TC_LOG_ERROR("misc", "MailSender::MailSender - Mail message contains unexpected sender typeid (%u).", sender->GetTypeId());
break;
}
}
diff --git a/src/server/game/Mails/Mail.h b/src/server/game/Mails/Mail.h
index 407edf2badb..ee1a0aae2c9 100644
--- a/src/server/game/Mails/Mail.h
+++ b/src/server/game/Mails/Mail.h
@@ -79,7 +79,7 @@ enum MailShowFlags
MAIL_SHOW_RETURN = 0x0010
};
-class MailSender
+class TC_GAME_API MailSender
{
public: // Constructors
MailSender(MailMessageType messageType, ObjectGuid::LowType sender_guidlow_or_entry, MailStationery stationery = MAIL_STATIONERY_DEFAULT)
@@ -100,7 +100,7 @@ class MailSender
MailStationery m_stationery;
};
-class MailReceiver
+class TC_GAME_API MailReceiver
{
public: // Constructors
explicit MailReceiver(ObjectGuid::LowType receiver_lowguid) : m_receiver(NULL), m_receiver_lowguid(receiver_lowguid) { }
@@ -114,7 +114,7 @@ class MailReceiver
ObjectGuid::LowType m_receiver_lowguid;
};
-class MailDraft
+class TC_GAME_API MailDraft
{
typedef std::map<ObjectGuid::LowType, Item*> MailItemMap;
@@ -162,7 +162,7 @@ struct MailItemInfo
};
typedef std::vector<MailItemInfo> MailItemInfoVec;
-struct Mail
+struct TC_GAME_API Mail
{
uint32 messageID;
uint8 messageType;
diff --git a/src/server/game/Maps/AreaBoundary.h b/src/server/game/Maps/AreaBoundary.h
index a134b783ca6..a8780ddb60f 100644
--- a/src/server/game/Maps/AreaBoundary.h
+++ b/src/server/game/Maps/AreaBoundary.h
@@ -20,7 +20,7 @@
#include "Position.h"
-class AreaBoundary
+class TC_GAME_API AreaBoundary
{
public:
enum BoundaryType
@@ -66,7 +66,7 @@ class AreaBoundary
bool m_isInvertedBoundary;
};
-class RectangleBoundary : public AreaBoundary
+class TC_GAME_API RectangleBoundary : public AreaBoundary
{
public:
// X axis is north/south, Y axis is east/west, larger values are northwest
@@ -79,7 +79,7 @@ class RectangleBoundary : public AreaBoundary
const float _minX, _maxX, _minY, _maxY;
};
-class CircleBoundary : public AreaBoundary
+class TC_GAME_API CircleBoundary : public AreaBoundary
{
public:
CircleBoundary(Position const& center, double radius, bool isInverted = false);
@@ -95,7 +95,7 @@ class CircleBoundary : public AreaBoundary
const double _radiusSq;
};
-class EllipseBoundary : public AreaBoundary
+class TC_GAME_API EllipseBoundary : public AreaBoundary
{
public:
EllipseBoundary(Position const& center, double radiusX, double radiusY, bool isInverted = false);
@@ -109,7 +109,7 @@ class EllipseBoundary : public AreaBoundary
const double _radiusYSq, _scaleXSq;
};
-class TriangleBoundary : public AreaBoundary
+class TC_GAME_API TriangleBoundary : public AreaBoundary
{
public:
TriangleBoundary(Position const& pointA, Position const& pointB, Position const& pointC, bool isInverted = false);
@@ -123,7 +123,7 @@ class TriangleBoundary : public AreaBoundary
const double _abx, _bcx, _cax, _aby, _bcy, _cay;
};
-class ParallelogramBoundary : public AreaBoundary
+class TC_GAME_API ParallelogramBoundary : public AreaBoundary
{
public:
// Note: AB must be orthogonal to AD
@@ -138,7 +138,7 @@ class ParallelogramBoundary : public AreaBoundary
const double _abx, _dax, _aby, _day;
};
-class ZRangeBoundary : public AreaBoundary
+class TC_GAME_API ZRangeBoundary : public AreaBoundary
{
public:
ZRangeBoundary(float minZ, float maxZ, bool isInverted = false);
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index ccc599b6de8..8640150d86b 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -129,9 +129,9 @@ void Map::LoadMMap(int gx, int gy)
bool mmapLoadResult = MMAP::MMapFactory::createOrGetMMapManager()->loadMap((sWorld->GetDataPath() + "mmaps").c_str(), GetId(), gx, gy);
if (mmapLoadResult)
- TC_LOG_DEBUG("maps", "MMAP loaded name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy);
+ TC_LOG_DEBUG("mmaps", "MMAP loaded name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy);
else
- TC_LOG_ERROR("maps", "Could not load MMAP name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy);
+ TC_LOG_ERROR("mmaps", "Could not load MMAP name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy);
}
void Map::LoadVMap(int gx, int gy)
@@ -209,6 +209,13 @@ void Map::LoadMapAndVMap(int gx, int gy)
}
}
+void Map::LoadAllCells()
+{
+ for (uint32 cellX = 0; cellX < TOTAL_NUMBER_OF_CELLS_PER_MAP; cellX++)
+ for (uint32 cellY = 0; cellY < TOTAL_NUMBER_OF_CELLS_PER_MAP; cellY++)
+ LoadGrid((cellX + 0.5f - CENTER_GRID_CELL_ID) * SIZE_OF_GRID_CELL, (cellY + 0.5f - CENTER_GRID_CELL_ID) * SIZE_OF_GRID_CELL);
+}
+
void Map::InitStateMachine()
{
si_GridStates[GRID_STATE_INVALID] = new InvalidState;
@@ -594,7 +601,7 @@ bool Map::AddToMap(T* obj)
//something, such as vehicle, needs to be update immediately
//also, trigger needs to cast spell, if not update, cannot see visual
- obj->UpdateObjectVisibility(true);
+ obj->UpdateObjectVisibilityOnCreate();
return true;
}
@@ -2986,15 +2993,15 @@ void Map::RemoveFromActive(DynamicObject* obj)
RemoveFromActiveHelper(obj);
}
-template bool Map::AddToMap(Corpse*);
-template bool Map::AddToMap(Creature*);
-template bool Map::AddToMap(GameObject*);
-template bool Map::AddToMap(DynamicObject*);
+template TC_GAME_API bool Map::AddToMap(Corpse*);
+template TC_GAME_API bool Map::AddToMap(Creature*);
+template TC_GAME_API bool Map::AddToMap(GameObject*);
+template TC_GAME_API bool Map::AddToMap(DynamicObject*);
-template void Map::RemoveFromMap(Corpse*, bool);
-template void Map::RemoveFromMap(Creature*, bool);
-template void Map::RemoveFromMap(GameObject*, bool);
-template void Map::RemoveFromMap(DynamicObject*, bool);
+template TC_GAME_API void Map::RemoveFromMap(Corpse*, bool);
+template TC_GAME_API void Map::RemoveFromMap(Creature*, bool);
+template TC_GAME_API void Map::RemoveFromMap(GameObject*, bool);
+template TC_GAME_API void Map::RemoveFromMap(DynamicObject*, bool);
/* ******* Dungeon Instance Maps ******* */
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index bc2bf72f271..5f134613e85 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -154,7 +154,7 @@ struct LiquidData
float depth_level;
};
-class GridMap
+class TC_GAME_API GridMap
{
uint32 _flags;
union{
@@ -253,7 +253,7 @@ typedef std::map<uint32/*leaderDBGUID*/, CreatureGroup*> CreatureGroupHol
typedef std::unordered_map<uint32 /*zoneId*/, ZoneDynamicInfo> ZoneDynamicInfoMap;
-class Map : public GridRefManager<NGridType>
+class TC_GAME_API Map : public GridRefManager<NGridType>
{
friend class MapReference;
public:
@@ -277,6 +277,7 @@ class Map : public GridRefManager<NGridType>
virtual bool AddPlayerToMap(Player*);
virtual void RemovePlayerFromMap(Player*, bool);
+
template<class T> bool AddToMap(T *);
template<class T> void RemoveFromMap(T *, bool);
@@ -292,7 +293,8 @@ class Map : public GridRefManager<NGridType>
void GameObjectRelocation(GameObject* go, float x, float y, float z, float orientation, bool respawnRelocationOnFail = true);
void DynamicObjectRelocation(DynamicObject* go, float x, float y, float z, float orientation);
- template<class T, class CONTAINER> void Visit(const Cell& cell, TypeContainerVisitor<T, CONTAINER> &visitor);
+ template<class T, class CONTAINER>
+ void Visit(const Cell& cell, TypeContainerVisitor<T, CONTAINER> &visitor);
bool IsRemovalGrid(float x, float y) const
{
@@ -308,6 +310,7 @@ class Map : public GridRefManager<NGridType>
bool GetUnloadLock(const GridCoord &p) const { return getNGrid(p.x_coord, p.y_coord)->getUnloadLock(); }
void SetUnloadLock(const GridCoord &p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadExplicitLock(on); }
void LoadGrid(float x, float y);
+ void LoadAllCells();
bool UnloadGrid(NGridType& ngrid, bool pForce);
virtual void UnloadAll();
@@ -753,7 +756,7 @@ enum InstanceResetMethod
INSTANCE_RESET_RESPAWN_DELAY
};
-class InstanceMap : public Map
+class TC_GAME_API InstanceMap : public Map
{
public:
InstanceMap(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode, Map* _parent);
@@ -785,7 +788,7 @@ class InstanceMap : public Map
uint32 i_script_id;
};
-class BattlegroundMap : public Map
+class TC_GAME_API BattlegroundMap : public Map
{
public:
BattlegroundMap(uint32 id, time_t, uint32 InstanceId, Map* _parent, uint8 spawnMode);
diff --git a/src/server/game/Maps/MapInstanced.cpp b/src/server/game/Maps/MapInstanced.cpp
index 47b9b376b1e..58decc05354 100644
--- a/src/server/game/Maps/MapInstanced.cpp
+++ b/src/server/game/Maps/MapInstanced.cpp
@@ -230,6 +230,9 @@ InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave* save,
bool load_data = save != NULL;
map->CreateInstanceData(load_data);
+ if (sWorld->getBoolConfig(CONFIG_INSTANCEMAP_LOAD_GRIDS))
+ map->LoadAllCells();
+
m_InstancedMaps[InstanceId] = map;
return map;
}
diff --git a/src/server/game/Maps/MapInstanced.h b/src/server/game/Maps/MapInstanced.h
index 7fa66bde06a..eea54e1f013 100644
--- a/src/server/game/Maps/MapInstanced.h
+++ b/src/server/game/Maps/MapInstanced.h
@@ -23,7 +23,7 @@
#include "InstanceSaveMgr.h"
#include "DBCEnums.h"
-class MapInstanced : public Map
+class TC_GAME_API MapInstanced : public Map
{
friend class MapManager;
public:
diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp
index e5f364e39f4..c1882b3dc75 100644
--- a/src/server/game/Maps/MapManager.cpp
+++ b/src/server/game/Maps/MapManager.cpp
@@ -62,6 +62,12 @@ void MapManager::InitializeVisibilityDistanceInfo()
(*iter).second->InitVisibilityDistance();
}
+MapManager* MapManager::instance()
+{
+ static MapManager instance;
+ return &instance;
+}
+
Map* MapManager::CreateBaseMap(uint32 id)
{
Map* map = FindBaseMap(id);
diff --git a/src/server/game/Maps/MapManager.h b/src/server/game/Maps/MapManager.h
index 7f9621593d4..e74453a1196 100644
--- a/src/server/game/Maps/MapManager.h
+++ b/src/server/game/Maps/MapManager.h
@@ -28,14 +28,10 @@
class Transport;
struct TransportCreatureProto;
-class MapManager
+class TC_GAME_API MapManager
{
public:
- static MapManager* instance()
- {
- static MapManager instance;
- return &instance;
- }
+ static MapManager* instance();
Map* CreateBaseMap(uint32 mapId);
Map* FindBaseNonInstanceMap(uint32 mapId) const;
diff --git a/src/server/game/Maps/MapUpdater.h b/src/server/game/Maps/MapUpdater.h
index 3d0f0b9e7e8..d95011d5a42 100644
--- a/src/server/game/Maps/MapUpdater.h
+++ b/src/server/game/Maps/MapUpdater.h
@@ -28,7 +28,7 @@
class MapUpdateRequest;
class Map;
-class MapUpdater
+class TC_GAME_API MapUpdater
{
public:
diff --git a/src/server/game/Maps/TransportMgr.cpp b/src/server/game/Maps/TransportMgr.cpp
index afbddc5e686..c94dd860dea 100644
--- a/src/server/game/Maps/TransportMgr.cpp
+++ b/src/server/game/Maps/TransportMgr.cpp
@@ -36,6 +36,12 @@ TransportMgr::TransportMgr() { }
TransportMgr::~TransportMgr() { }
+TransportMgr* TransportMgr::instance()
+{
+ static TransportMgr instance;
+ return &instance;
+}
+
void TransportMgr::Unload()
{
_transportTemplates.clear();
diff --git a/src/server/game/Maps/TransportMgr.h b/src/server/game/Maps/TransportMgr.h
index 0bfb5b7a410..229fea882a4 100644
--- a/src/server/game/Maps/TransportMgr.h
+++ b/src/server/game/Maps/TransportMgr.h
@@ -82,7 +82,7 @@ struct TransportTemplate
typedef std::map<uint32, TransportAnimationEntry const*> TransportPathContainer;
typedef std::map<uint32, TransportRotationEntry const*> TransportPathRotationContainer;
-struct TransportAnimation
+struct TC_GAME_API TransportAnimation
{
TransportAnimation() : TotalTime(0) { }
@@ -96,16 +96,12 @@ struct TransportAnimation
typedef std::map<uint32, TransportAnimation> TransportAnimationContainer;
-class TransportMgr
+class TC_GAME_API TransportMgr
{
- friend void LoadDBCStores(std::string const&);
+ friend TC_GAME_API void LoadDBCStores(std::string const&);
public:
- static TransportMgr* instance()
- {
- static TransportMgr instance;
- return &instance;
- }
+ static TransportMgr* instance();
void Unload();
diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h
index 62c2a3a1981..dcee5ff7071 100644
--- a/src/server/game/Miscellaneous/Language.h
+++ b/src/server/game/Miscellaneous/Language.h
@@ -208,7 +208,9 @@ enum TrinityStrings
LANG_INVALID_GAMEOBJECT_TYPE = 176,
LANG_GAMEOBJECT_DAMAGED = 177,
LANG_GRID_POSITION = 178,
- // Room for more level 1 179-199 not used
+ // 179-185 used in 6.x branch
+ LANG_TRANSPORT_POSITION = 186,
+ // Room for more level 1 187-199 not used
// level 2 chat
LANG_NO_SELECTION = 200,
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index 05948b987ad..2a57524cb3c 100644
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -193,7 +193,7 @@ void MotionMaster::MoveRandom(float spawndist)
{
if (_owner->GetTypeId() == TYPEID_UNIT)
{
- TC_LOG_DEBUG("misc", "Creature (GUID: %u) start moving random", _owner->GetGUID().GetCounter());
+ TC_LOG_DEBUG("misc", "Creature (GUID: %u) started random movement.", _owner->GetGUID().GetCounter());
Mutate(new RandomMovementGenerator<Creature>(spawndist), MOTION_SLOT_IDLE);
}
}
@@ -204,22 +204,22 @@ void MotionMaster::MoveTargetedHome()
if (_owner->GetTypeId() == TYPEID_UNIT && !_owner->ToCreature()->GetCharmerOrOwnerGUID())
{
- TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) targeted home", _owner->GetEntry(), _owner->GetGUID().GetCounter());
+ TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) targeted home.", _owner->GetEntry(), _owner->GetGUID().GetCounter());
Mutate(new HomeMovementGenerator<Creature>(), MOTION_SLOT_ACTIVE);
}
else if (_owner->GetTypeId() == TYPEID_UNIT && _owner->ToCreature()->GetCharmerOrOwnerGUID())
{
- TC_LOG_DEBUG("misc", "Pet or controlled creature (Entry: %u GUID: %u) targeting home", _owner->GetEntry(), _owner->GetGUID().GetCounter());
+ TC_LOG_DEBUG("misc", "Pet or controlled creature (Entry: %u GUID: %u) is targeting home.", _owner->GetEntry(), _owner->GetGUID().GetCounter());
Unit* target = _owner->ToCreature()->GetCharmerOrOwner();
if (target)
{
- TC_LOG_DEBUG("misc", "Following %s (GUID: %u)", target->GetTypeId() == TYPEID_PLAYER ? "player" : "creature", target->GetTypeId() == TYPEID_PLAYER ? target->GetGUID().GetCounter() : ((Creature*)target)->GetSpawnId());
+ TC_LOG_DEBUG("misc", "Following %s (GUID: %u).", target->GetTypeId() == TYPEID_PLAYER ? "player" : "creature", target->GetTypeId() == TYPEID_PLAYER ? target->GetGUID().GetCounter() : ((Creature*)target)->GetSpawnId());
Mutate(new FollowMovementGenerator<Creature>(target, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE), MOTION_SLOT_ACTIVE);
}
}
else
{
- TC_LOG_ERROR("misc", "Player (GUID: %u) attempt targeted home", _owner->GetGUID().GetCounter());
+ TC_LOG_ERROR("misc", "Player (GUID: %u) attempted to move towards target home.", _owner->GetGUID().GetCounter());
}
}
@@ -272,14 +272,14 @@ void MotionMaster::MoveFollow(Unit* target, float dist, float angle, MovementSlo
//_owner->AddUnitState(UNIT_STATE_FOLLOW);
if (_owner->GetTypeId() == TYPEID_PLAYER)
{
- TC_LOG_DEBUG("misc", "Player (GUID: %u) follow to %s (GUID: %u)", _owner->GetGUID().GetCounter(),
+ TC_LOG_DEBUG("misc", "Player (GUID: %u) follows %s (GUID: %u).", _owner->GetGUID().GetCounter(),
target->GetTypeId() == TYPEID_PLAYER ? "player" : "creature",
target->GetTypeId() == TYPEID_PLAYER ? target->GetGUID().GetCounter() : target->ToCreature()->GetSpawnId());
Mutate(new FollowMovementGenerator<Player>(target, dist, angle), slot);
}
else
{
- TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) follow to %s (GUID: %u)",
+ TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) follows %s (GUID: %u).",
_owner->GetEntry(), _owner->GetGUID().GetCounter(),
target->GetTypeId() == TYPEID_PLAYER ? "player" : "creature",
target->GetTypeId() == TYPEID_PLAYER ? target->GetGUID().GetCounter() : target->ToCreature()->GetSpawnId());
@@ -291,12 +291,12 @@ void MotionMaster::MovePoint(uint32 id, float x, float y, float z, bool generate
{
if (_owner->GetTypeId() == TYPEID_PLAYER)
{
- TC_LOG_DEBUG("misc", "Player (GUID: %u) targeted point (Id: %u X: %f Y: %f Z: %f)", _owner->GetGUID().GetCounter(), id, x, y, z);
+ TC_LOG_DEBUG("misc", "Player (GUID: %u) targeted point (Id: %u X: %f Y: %f Z: %f).", _owner->GetGUID().GetCounter(), id, x, y, z);
Mutate(new PointMovementGenerator<Player>(id, x, y, z, generatePath), MOTION_SLOT_ACTIVE);
}
else
{
- TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) targeted point (ID: %u X: %f Y: %f Z: %f)",
+ TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) targeted point (ID: %u X: %f Y: %f Z: %f).",
_owner->GetEntry(), _owner->GetGUID().GetCounter(), id, x, y, z);
Mutate(new PointMovementGenerator<Creature>(id, x, y, z, generatePath), MOTION_SLOT_ACTIVE);
}
@@ -307,7 +307,7 @@ void MotionMaster::MoveLand(uint32 id, Position const& pos)
float x, y, z;
pos.GetPosition(x, y, z);
- TC_LOG_DEBUG("misc", "Creature (Entry: %u) landing point (ID: %u X: %f Y: %f Z: %f)", _owner->GetEntry(), id, x, y, z);
+ TC_LOG_DEBUG("misc", "Creature (Entry: %u) landing point (ID: %u X: %f Y: %f Z: %f).", _owner->GetEntry(), id, x, y, z);
Movement::MoveSplineInit init(_owner);
init.MoveTo(x, y, z);
@@ -321,7 +321,7 @@ void MotionMaster::MoveTakeoff(uint32 id, Position const& pos)
float x, y, z;
pos.GetPosition(x, y, z);
- TC_LOG_DEBUG("misc", "Creature (Entry: %u) landing point (ID: %u X: %f Y: %f Z: %f)", _owner->GetEntry(), id, x, y, z);
+ TC_LOG_DEBUG("misc", "Creature (Entry: %u) landing point (ID: %u X: %f Y: %f Z: %f).", _owner->GetEntry(), id, x, y, z);
Movement::MoveSplineInit init(_owner);
init.MoveTo(x, y, z);
@@ -371,7 +371,7 @@ void MotionMaster::MoveJumpTo(float angle, float speedXY, float speedZ)
void MotionMaster::MoveJump(float x, float y, float z, float o, float speedXY, float speedZ, uint32 id, bool hasOrientation /* = false*/)
{
- TC_LOG_DEBUG("misc", "Unit (GUID: %u) jump to point (X: %f Y: %f Z: %f)", _owner->GetGUID().GetCounter(), x, y, z);
+ TC_LOG_DEBUG("misc", "Unit (GUID: %u) jumps to point (X: %f Y: %f Z: %f).", _owner->GetGUID().GetCounter(), x, y, z);
if (speedXY <= 0.1f)
return;
@@ -449,7 +449,7 @@ void MotionMaster::MoveFall(uint32 id /*=0*/)
float tz = _owner->GetMap()->GetHeight(_owner->GetPhaseMask(), _owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ(), true, MAX_FALL_DISTANCE);
if (tz <= INVALID_HEIGHT)
{
- TC_LOG_DEBUG("misc", "MotionMaster::MoveFall: unable retrive a proper height at map %u (x: %f, y: %f, z: %f).",
+ TC_LOG_DEBUG("misc", "MotionMaster::MoveFall: unable to retrieve a proper height at map %u (x: %f, y: %f, z: %f).",
_owner->GetMap()->GetId(), _owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ());
return;
}
@@ -478,12 +478,12 @@ void MotionMaster::MoveCharge(float x, float y, float z, float speed /*= SPEED_C
if (_owner->GetTypeId() == TYPEID_PLAYER)
{
- TC_LOG_DEBUG("misc", "Player (GUID: %u) charge point (X: %f Y: %f Z: %f)", _owner->GetGUID().GetCounter(), x, y, z);
+ TC_LOG_DEBUG("misc", "Player (GUID: %u) charged point (X: %f Y: %f Z: %f).", _owner->GetGUID().GetCounter(), x, y, z);
Mutate(new PointMovementGenerator<Player>(id, x, y, z, generatePath, speed), MOTION_SLOT_CONTROLLED);
}
else
{
- TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) charge point (X: %f Y: %f Z: %f)",
+ TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) charged point (X: %f Y: %f Z: %f).",
_owner->GetEntry(), _owner->GetGUID().GetCounter(), x, y, z);
Mutate(new PointMovementGenerator<Creature>(id, x, y, z, generatePath, speed), MOTION_SLOT_CONTROLLED);
}
@@ -506,7 +506,7 @@ void MotionMaster::MoveSeekAssistance(float x, float y, float z)
{
if (_owner->GetTypeId() == TYPEID_PLAYER)
{
- TC_LOG_ERROR("misc", "Player (GUID: %u) attempt to seek assistance", _owner->GetGUID().GetCounter());
+ TC_LOG_ERROR("misc", "Player (GUID: %u) attempted to seek assistance.", _owner->GetGUID().GetCounter());
}
else
{
@@ -522,11 +522,11 @@ void MotionMaster::MoveSeekAssistanceDistract(uint32 time)
{
if (_owner->GetTypeId() == TYPEID_PLAYER)
{
- TC_LOG_ERROR("misc", "Player (GUID: %u) attempt to call distract after assistance", _owner->GetGUID().GetCounter());
+ TC_LOG_ERROR("misc", "Player (GUID: %u) attempted to call distract assistance.", _owner->GetGUID().GetCounter());
}
else
{
- TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) is distracted after assistance call (Time: %u)",
+ TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) is distracted after assistance call (Time: %u).",
_owner->GetEntry(), _owner->GetGUID().GetCounter(), time);
Mutate(new AssistanceDistractMovementGenerator(time), MOTION_SLOT_ACTIVE);
}
@@ -539,14 +539,14 @@ void MotionMaster::MoveFleeing(Unit* enemy, uint32 time)
if (_owner->GetTypeId() == TYPEID_PLAYER)
{
- TC_LOG_DEBUG("misc", "Player (GUID: %u) flee from %s (GUID: %u)", _owner->GetGUID().GetCounter(),
+ TC_LOG_DEBUG("misc", "Player (GUID: %u) flees from %s (GUID: %u).", _owner->GetGUID().GetCounter(),
enemy->GetTypeId() == TYPEID_PLAYER ? "player" : "creature",
enemy->GetTypeId() == TYPEID_PLAYER ? enemy->GetGUID().GetCounter() : enemy->ToCreature()->GetSpawnId());
Mutate(new FleeingMovementGenerator<Player>(enemy->GetGUID()), MOTION_SLOT_CONTROLLED);
}
else
{
- TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) flee from %s (GUID: %u)%s",
+ TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) flees from %s (GUID: %u)%s.",
_owner->GetEntry(), _owner->GetGUID().GetCounter(),
enemy->GetTypeId() == TYPEID_PLAYER ? "player" : "creature",
enemy->GetTypeId() == TYPEID_PLAYER ? enemy->GetGUID().GetCounter() : enemy->ToCreature()->GetSpawnId(),
@@ -564,20 +564,20 @@ void MotionMaster::MoveTaxiFlight(uint32 path, uint32 pathnode)
{
if (path < sTaxiPathNodesByPath.size())
{
- TC_LOG_DEBUG("misc", "%s taxi to (Path %u node %u)", _owner->GetName().c_str(), path, pathnode);
+ TC_LOG_DEBUG("misc", "%s taxi to (Path %u node %u).", _owner->GetName().c_str(), path, pathnode);
FlightPathMovementGenerator* mgen = new FlightPathMovementGenerator(pathnode);
mgen->LoadPath(_owner->ToPlayer());
Mutate(mgen, MOTION_SLOT_CONTROLLED);
}
else
{
- TC_LOG_ERROR("misc", "%s attempt taxi to (not existed Path %u node %u)",
+ TC_LOG_ERROR("misc", "%s attempted taxi to (non-existing Path %u node %u).",
_owner->GetName().c_str(), path, pathnode);
}
}
else
{
- TC_LOG_ERROR("misc", "Creature (Entry: %u GUID: %u) attempt taxi to (Path %u node %u)",
+ TC_LOG_ERROR("misc", "Creature (Entry: %u GUID: %u) attempted taxi to (Path %u node %u).",
_owner->GetEntry(), _owner->GetGUID().GetCounter(), path, pathnode);
}
}
@@ -589,11 +589,11 @@ void MotionMaster::MoveDistract(uint32 timer)
if (_owner->GetTypeId() == TYPEID_PLAYER)
{
- TC_LOG_DEBUG("misc", "Player (GUID: %u) distracted (timer: %u)", _owner->GetGUID().GetCounter(), timer);
+ TC_LOG_DEBUG("misc", "Player (GUID: %u) distracted (timer: %u).", _owner->GetGUID().GetCounter(), timer);
}
else
{
- TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) (timer: %u)",
+ TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) distracted (timer: %u)",
_owner->GetEntry(), _owner->GetGUID().GetCounter(), timer);
}
@@ -645,7 +645,7 @@ void MotionMaster::MovePath(uint32 path_id, bool repeatable)
//Mutate(new WaypointMovementGenerator<Player>(path_id, repeatable)):
Mutate(new WaypointMovementGenerator<Creature>(path_id, repeatable), MOTION_SLOT_IDLE);
- TC_LOG_DEBUG("misc", "%s (GUID: %u) start moving over path(Id:%u, repeatable: %s)",
+ TC_LOG_DEBUG("misc", "%s (GUID: %u) starts moving over path(Id:%u, repeatable: %s).",
_owner->GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature",
_owner->GetGUID().GetCounter(), path_id, repeatable ? "YES" : "NO");
}
diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h
index 76ae12986d5..d1c6474fb36 100644
--- a/src/server/game/Movement/MotionMaster.h
+++ b/src/server/game/Movement/MotionMaster.h
@@ -79,7 +79,7 @@ enum RotateDirection
// assume it is 25 yard per 0.6 second
#define SPEED_CHARGE 42.0f
-class MotionMaster //: private std::stack<MovementGenerator *>
+class TC_GAME_API MotionMaster //: private std::stack<MovementGenerator *>
{
private:
//typedef std::stack<MovementGenerator *> Impl;
diff --git a/src/server/game/Movement/MovementGenerator.h b/src/server/game/Movement/MovementGenerator.h
index 56e5dc7058a..d9dd17fabc2 100755
--- a/src/server/game/Movement/MovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerator.h
@@ -27,7 +27,7 @@
class Unit;
-class MovementGenerator
+class TC_GAME_API MovementGenerator
{
public:
virtual ~MovementGenerator();
diff --git a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h
index 9aa778c5651..161f9e3e970 100755
--- a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h
@@ -32,7 +32,7 @@ class IdleMovementGenerator : public MovementGenerator
MovementGeneratorType GetMovementGeneratorType() const override { return IDLE_MOTION_TYPE; }
};
-extern IdleMovementGenerator si_idleMovement;
+TC_GAME_API extern IdleMovementGenerator si_idleMovement;
class RotateMovementGenerator : public MovementGenerator
{
diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h
index 7103eaace55..9250b666484 100755
--- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h
@@ -50,7 +50,7 @@ class TargetedMovementGeneratorMedium : public MovementGeneratorMedium< T, D >,
bool DoUpdate(T*, uint32);
Unit* GetTarget() const { return i_target.getTarget(); }
- void unitSpeedChanged() { i_recalculateTravel = true; }
+ void unitSpeedChanged() override { i_recalculateTravel = true; }
bool IsReachable() const { return (i_path) ? (i_path->GetPathType() & PATHFIND_NORMAL) : true; }
protected:
void _setTargetLocation(T* owner, bool updateDestination);
diff --git a/src/server/game/Movement/PathGenerator.h b/src/server/game/Movement/PathGenerator.h
index 71e0e88f0b2..3cad62abf25 100644
--- a/src/server/game/Movement/PathGenerator.h
+++ b/src/server/game/Movement/PathGenerator.h
@@ -49,7 +49,7 @@ enum PathType
PATHFIND_SHORT = 0x20, // path is longer or equal to its limited path length
};
-class PathGenerator
+class TC_GAME_API PathGenerator
{
public:
explicit PathGenerator(Unit const* owner);
diff --git a/src/server/game/Movement/Spline/MoveSpline.h b/src/server/game/Movement/Spline/MoveSpline.h
index 209f978d658..0e62862cecc 100644
--- a/src/server/game/Movement/Spline/MoveSpline.h
+++ b/src/server/game/Movement/Spline/MoveSpline.h
@@ -37,7 +37,7 @@ namespace Movement
// MoveSpline represents smooth catmullrom or linear curve and point that moves belong it
// curve can be cyclic - in this case movement will be cyclic
// point can have vertical acceleration motion componemt(used in fall, parabolic movement)
- class MoveSpline
+ class TC_GAME_API MoveSpline
{
public:
typedef Spline<int32> MySpline;
diff --git a/src/server/game/Movement/Spline/MoveSplineInit.h b/src/server/game/Movement/Spline/MoveSplineInit.h
index a94c84d92f3..3f38da97916 100644
--- a/src/server/game/Movement/Spline/MoveSplineInit.h
+++ b/src/server/game/Movement/Spline/MoveSplineInit.h
@@ -35,7 +35,7 @@ namespace Movement
};
// Transforms coordinates from global to transport offsets
- class TransportPathTransform
+ class TC_GAME_API TransportPathTransform
{
public:
TransportPathTransform(Unit* owner, bool transformForTransport)
@@ -49,7 +49,7 @@ namespace Movement
/* Initializes and launches spline movement
*/
- class MoveSplineInit
+ class TC_GAME_API MoveSplineInit
{
public:
diff --git a/src/server/game/Movement/Spline/MovementTypedefs.h b/src/server/game/Movement/Spline/MovementTypedefs.h
index 031ec729949..c87fea47a82 100644
--- a/src/server/game/Movement/Spline/MovementTypedefs.h
+++ b/src/server/game/Movement/Spline/MovementTypedefs.h
@@ -69,8 +69,8 @@ namespace Movement
typedef counter<uint32, 0xFFFFFFFF> UInt32Counter;
- extern float gravity;
- extern UInt32Counter splineIdGen;
+ TC_GAME_API extern float gravity;
+ TC_GAME_API extern UInt32Counter splineIdGen;
}
#endif // TRINITYSERVER_TYPEDEFS_H
diff --git a/src/server/game/Movement/Waypoints/WaypointManager.cpp b/src/server/game/Movement/Waypoints/WaypointManager.cpp
index e0639e38e77..dc935263927 100644
--- a/src/server/game/Movement/Waypoints/WaypointManager.cpp
+++ b/src/server/game/Movement/Waypoints/WaypointManager.cpp
@@ -94,6 +94,12 @@ void WaypointMgr::Load()
TC_LOG_INFO("server.loading", ">> Loaded %u waypoints in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
+WaypointMgr* WaypointMgr::instance()
+{
+ static WaypointMgr instance;
+ return &instance;
+}
+
void WaypointMgr::ReloadPath(uint32 id)
{
WaypointPathContainer::iterator itr = _waypointStore.find(id);
diff --git a/src/server/game/Movement/Waypoints/WaypointManager.h b/src/server/game/Movement/Waypoints/WaypointManager.h
index d519eee4793..63dc4184308 100644
--- a/src/server/game/Movement/Waypoints/WaypointManager.h
+++ b/src/server/game/Movement/Waypoints/WaypointManager.h
@@ -44,14 +44,10 @@ struct WaypointData
typedef std::vector<WaypointData*> WaypointPath;
typedef std::unordered_map<uint32, WaypointPath> WaypointPathContainer;
-class WaypointMgr
+class TC_GAME_API WaypointMgr
{
public:
- static WaypointMgr* instance()
- {
- static WaypointMgr instance;
- return &instance;
- }
+ static WaypointMgr* instance();
// Attempts to reload a single path from database
void ReloadPath(uint32 id);
diff --git a/src/server/game/OutdoorPvP/OutdoorPvP.h b/src/server/game/OutdoorPvP/OutdoorPvP.h
index 79f34ff10ea..255f3cd0f99 100644
--- a/src/server/game/OutdoorPvP/OutdoorPvP.h
+++ b/src/server/game/OutdoorPvP/OutdoorPvP.h
@@ -84,7 +84,7 @@ class Unit;
struct GossipMenuItems;
class OutdoorPvP;
-class OPvPCapturePoint
+class TC_GAME_API OPvPCapturePoint
{
public:
@@ -185,7 +185,7 @@ class OPvPCapturePoint
};
// base class for specific outdoor pvp handlers
-class OutdoorPvP : public ZoneScript
+class TC_GAME_API OutdoorPvP : public ZoneScript
{
friend class OutdoorPvPMgr;
diff --git a/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp b/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp
index 8296cdfb7ea..7f0695e16b3 100644
--- a/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp
+++ b/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp
@@ -37,6 +37,12 @@ void OutdoorPvPMgr::Die()
delete itr->second;
}
+OutdoorPvPMgr* OutdoorPvPMgr::instance()
+{
+ static OutdoorPvPMgr instance;
+ return &instance;
+}
+
void OutdoorPvPMgr::InitOutdoorPvP()
{
uint32 oldMSTime = getMSTime();
diff --git a/src/server/game/OutdoorPvP/OutdoorPvPMgr.h b/src/server/game/OutdoorPvP/OutdoorPvPMgr.h
index 8a113987882..e53a78ac271 100644
--- a/src/server/game/OutdoorPvP/OutdoorPvPMgr.h
+++ b/src/server/game/OutdoorPvP/OutdoorPvPMgr.h
@@ -35,18 +35,14 @@ struct OutdoorPvPData
};
// class to handle player enter / leave / areatrigger / GO use events
-class OutdoorPvPMgr
+class TC_GAME_API OutdoorPvPMgr
{
private:
OutdoorPvPMgr();
~OutdoorPvPMgr() { };
public:
- static OutdoorPvPMgr* instance()
- {
- static OutdoorPvPMgr instance;
- return &instance;
- }
+ static OutdoorPvPMgr* instance();
// create outdoor pvp events
void InitOutdoorPvP();
diff --git a/src/server/game/Pools/PoolMgr.cpp b/src/server/game/Pools/PoolMgr.cpp
index 12fb8a06b62..812d8ea3940 100644
--- a/src/server/game/Pools/PoolMgr.cpp
+++ b/src/server/game/Pools/PoolMgr.cpp
@@ -60,6 +60,11 @@ bool ActivePoolData::IsActiveObject<Quest>(uint32 quest_id) const
return mActiveQuests.find(quest_id) != mActiveQuests.end();
}
+template TC_GAME_API bool ActivePoolData::IsActiveObject<Creature>(uint32) const;
+template TC_GAME_API bool ActivePoolData::IsActiveObject<GameObject>(uint32) const;
+template TC_GAME_API bool ActivePoolData::IsActiveObject<Pool>(uint32) const;
+template TC_GAME_API bool ActivePoolData::IsActiveObject<Quest>(uint32) const;
+
template<>
void ActivePoolData::ActivateObject<Creature>(uint32 db_guid, uint32 pool_id)
{
@@ -570,6 +575,12 @@ void PoolMgr::Initialize()
mCreatureSearchMap.clear();
}
+PoolMgr* PoolMgr::instance()
+{
+ static PoolMgr instance;
+ return &instance;
+}
+
void PoolMgr::LoadFromDB()
{
// Pool templates
diff --git a/src/server/game/Pools/PoolMgr.h b/src/server/game/Pools/PoolMgr.h
index 51e0bcb4cac..f1af3a3530e 100644
--- a/src/server/game/Pools/PoolMgr.h
+++ b/src/server/game/Pools/PoolMgr.h
@@ -43,7 +43,7 @@ class Pool // for Pool of Pool
typedef std::set<ObjectGuid::LowType> ActivePoolObjects;
typedef std::map<uint32, uint32> ActivePoolPools;
-class ActivePoolData
+class TC_GAME_API ActivePoolData
{
public:
template<typename T>
@@ -66,7 +66,7 @@ class ActivePoolData
};
template <class T>
-class PoolGroup
+class TC_GAME_API PoolGroup
{
typedef std::vector<PoolObject> PoolObjectList;
public:
@@ -101,18 +101,14 @@ typedef std::multimap<uint32, uint32> PooledQuestRelation;
typedef std::pair<PooledQuestRelation::const_iterator, PooledQuestRelation::const_iterator> PooledQuestRelationBounds;
typedef std::pair<PooledQuestRelation::iterator, PooledQuestRelation::iterator> PooledQuestRelationBoundsNC;
-class PoolMgr
+class TC_GAME_API PoolMgr
{
private:
PoolMgr();
~PoolMgr() { };
public:
- static PoolMgr* instance()
- {
- static PoolMgr instance;
- return &instance;
- }
+ static PoolMgr* instance();
void LoadFromDB();
void LoadQuestPools();
diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h
index a502fef6140..75b52bb4537 100644
--- a/src/server/game/Quests/QuestDef.h
+++ b/src/server/game/Quests/QuestDef.h
@@ -190,7 +190,7 @@ struct QuestLocale
// This Quest class provides a convenient way to access a few pretotaled (cached) quest details,
// all base quest information, and any utility functions such as generating the amount of
// xp to give
-class Quest
+class TC_GAME_API Quest
{
friend class ObjectMgr;
public:
diff --git a/src/server/game/Reputation/ReputationMgr.h b/src/server/game/Reputation/ReputationMgr.h
index 6f319a39b0c..5a51c9eb383 100644
--- a/src/server/game/Reputation/ReputationMgr.h
+++ b/src/server/game/Reputation/ReputationMgr.h
@@ -61,7 +61,7 @@ typedef std::map<uint32, ReputationRank> ForcedReactions;
class Player;
-class ReputationMgr
+class TC_GAME_API ReputationMgr
{
public: // constructors and global modifiers
explicit ReputationMgr(Player* owner) : _player(owner),
diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp
deleted file mode 100644
index 2922e4ef58d..00000000000
--- a/src/server/game/Scripting/ScriptLoader.cpp
+++ /dev/null
@@ -1,1421 +0,0 @@
-/*
- * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "ScriptLoader.h"
-#include "World.h"
-
-// spells
-void AddSC_deathknight_spell_scripts();
-void AddSC_druid_spell_scripts();
-void AddSC_generic_spell_scripts();
-void AddSC_hunter_spell_scripts();
-void AddSC_mage_spell_scripts();
-void AddSC_paladin_spell_scripts();
-void AddSC_priest_spell_scripts();
-void AddSC_rogue_spell_scripts();
-void AddSC_shaman_spell_scripts();
-void AddSC_warlock_spell_scripts();
-void AddSC_warrior_spell_scripts();
-void AddSC_quest_spell_scripts();
-void AddSC_item_spell_scripts();
-void AddSC_holiday_spell_scripts();
-
-void AddSC_SmartScripts();
-
-//Commands
-void AddSC_account_commandscript();
-void AddSC_achievement_commandscript();
-void AddSC_ahbot_commandscript();
-void AddSC_arena_commandscript();
-void AddSC_ban_commandscript();
-void AddSC_bf_commandscript();
-void AddSC_cast_commandscript();
-void AddSC_character_commandscript();
-void AddSC_cheat_commandscript();
-void AddSC_debug_commandscript();
-void AddSC_deserter_commandscript();
-void AddSC_disable_commandscript();
-void AddSC_event_commandscript();
-void AddSC_gm_commandscript();
-void AddSC_go_commandscript();
-void AddSC_gobject_commandscript();
-void AddSC_group_commandscript();
-void AddSC_guild_commandscript();
-void AddSC_honor_commandscript();
-void AddSC_instance_commandscript();
-void AddSC_learn_commandscript();
-void AddSC_lfg_commandscript();
-void AddSC_list_commandscript();
-void AddSC_lookup_commandscript();
-void AddSC_message_commandscript();
-void AddSC_misc_commandscript();
-void AddSC_mmaps_commandscript();
-void AddSC_modify_commandscript();
-void AddSC_npc_commandscript();
-void AddSC_pet_commandscript();
-void AddSC_quest_commandscript();
-void AddSC_rbac_commandscript();
-void AddSC_reload_commandscript();
-void AddSC_reset_commandscript();
-void AddSC_send_commandscript();
-void AddSC_server_commandscript();
-void AddSC_tele_commandscript();
-void AddSC_ticket_commandscript();
-void AddSC_titles_commandscript();
-void AddSC_wp_commandscript();
-
-#ifdef SCRIPTS
-//world
-void AddSC_areatrigger_scripts();
-void AddSC_emerald_dragons();
-void AddSC_generic_creature();
-void AddSC_go_scripts();
-void AddSC_guards();
-void AddSC_item_scripts();
-void AddSC_npc_professions();
-void AddSC_npc_innkeeper();
-void AddSC_npcs_special();
-void AddSC_achievement_scripts();
-void AddSC_action_ip_logger();
-void AddSC_duel_reset();
-
-//eastern kingdoms
-void AddSC_alterac_valley(); //Alterac Valley
-void AddSC_boss_balinda();
-void AddSC_boss_drekthar();
-void AddSC_boss_galvangar();
-void AddSC_boss_vanndar();
-void AddSC_blackrock_depths(); //Blackrock Depths
-void AddSC_boss_ambassador_flamelash();
-void AddSC_boss_draganthaurissan();
-void AddSC_boss_general_angerforge();
-void AddSC_boss_high_interrogator_gerstahn();
-void AddSC_boss_magmus();
-void AddSC_boss_moira_bronzebeard();
-void AddSC_boss_tomb_of_seven();
-void AddSC_instance_blackrock_depths();
-void AddSC_boss_drakkisath(); //Blackrock Spire
-void AddSC_boss_halycon();
-void AddSC_boss_highlordomokk();
-void AddSC_boss_mothersmolderweb();
-void AddSC_boss_overlordwyrmthalak();
-void AddSC_boss_shadowvosh();
-void AddSC_boss_thebeast();
-void AddSC_boss_warmastervoone();
-void AddSC_boss_quatermasterzigris();
-void AddSC_boss_pyroguard_emberseer();
-void AddSC_boss_gyth();
-void AddSC_boss_rend_blackhand();
-void AddSC_boss_gizrul_the_slavener();
-void AddSC_boss_urok_doomhowl();
-void AddSC_boss_lord_valthalak();
-void AddSC_instance_blackrock_spire();
-void AddSC_boss_razorgore(); //Blackwing lair
-void AddSC_boss_vaelastrasz();
-void AddSC_boss_broodlord();
-void AddSC_boss_firemaw();
-void AddSC_boss_ebonroc();
-void AddSC_boss_flamegor();
-void AddSC_boss_chromaggus();
-void AddSC_boss_nefarian();
-void AddSC_instance_blackwing_lair();
-void AddSC_deadmines(); //Deadmines
-void AddSC_instance_deadmines();
-void AddSC_boss_mr_smite();
-void AddSC_gnomeregan(); //Gnomeregan
-void AddSC_instance_gnomeregan();
-void AddSC_boss_attumen(); //Karazhan
-void AddSC_boss_curator();
-void AddSC_boss_maiden_of_virtue();
-void AddSC_boss_shade_of_aran();
-void AddSC_boss_malchezaar();
-void AddSC_boss_terestian_illhoof();
-void AddSC_boss_moroes();
-void AddSC_bosses_opera();
-void AddSC_boss_netherspite();
-void AddSC_instance_karazhan();
-void AddSC_karazhan();
-void AddSC_boss_nightbane();
-void AddSC_boss_felblood_kaelthas(); // Magister's Terrace
-void AddSC_boss_selin_fireheart();
-void AddSC_boss_vexallus();
-void AddSC_boss_priestess_delrissa();
-void AddSC_instance_magisters_terrace();
-void AddSC_magisters_terrace();
-void AddSC_boss_lucifron(); //Molten core
-void AddSC_boss_magmadar();
-void AddSC_boss_gehennas();
-void AddSC_boss_garr();
-void AddSC_boss_baron_geddon();
-void AddSC_boss_shazzrah();
-void AddSC_boss_golemagg();
-void AddSC_boss_sulfuron();
-void AddSC_boss_majordomo();
-void AddSC_boss_ragnaros();
-void AddSC_instance_molten_core();
-void AddSC_instance_ragefire_chasm(); //Ragefire Chasm
-void AddSC_the_scarlet_enclave(); //Scarlet Enclave
-void AddSC_the_scarlet_enclave_c1();
-void AddSC_the_scarlet_enclave_c2();
-void AddSC_the_scarlet_enclave_c5();
-void AddSC_boss_arcanist_doan(); //Scarlet Monastery
-void AddSC_boss_azshir_the_sleepless();
-void AddSC_boss_bloodmage_thalnos();
-void AddSC_boss_headless_horseman();
-void AddSC_boss_herod();
-void AddSC_boss_high_inquisitor_fairbanks();
-void AddSC_boss_houndmaster_loksey();
-void AddSC_boss_interrogator_vishas();
-void AddSC_boss_scorn();
-void AddSC_instance_scarlet_monastery();
-void AddSC_boss_mograine_and_whitemane();
-void AddSC_boss_darkmaster_gandling(); //Scholomance
-void AddSC_boss_death_knight_darkreaver();
-void AddSC_boss_theolenkrastinov();
-void AddSC_boss_illuciabarov();
-void AddSC_boss_instructormalicia();
-void AddSC_boss_jandicebarov();
-void AddSC_boss_kormok();
-void AddSC_boss_lordalexeibarov();
-void AddSC_boss_lorekeeperpolkelt();
-void AddSC_boss_rasfrost();
-void AddSC_boss_theravenian();
-void AddSC_boss_vectus();
-void AddSC_boss_kirtonos_the_herald();
-void AddSC_instance_scholomance();
-void AddSC_shadowfang_keep(); //Shadowfang keep
-void AddSC_instance_shadowfang_keep();
-void AddSC_boss_magistrate_barthilas(); //Stratholme
-void AddSC_boss_maleki_the_pallid();
-void AddSC_boss_nerubenkan();
-void AddSC_boss_cannon_master_willey();
-void AddSC_boss_baroness_anastari();
-void AddSC_boss_ramstein_the_gorger();
-void AddSC_boss_timmy_the_cruel();
-void AddSC_boss_postmaster_malown();
-void AddSC_boss_baron_rivendare();
-void AddSC_boss_dathrohan_balnazzar();
-void AddSC_boss_order_of_silver_hand();
-void AddSC_instance_stratholme();
-void AddSC_stratholme();
-void AddSC_sunken_temple(); // Sunken Temple
-void AddSC_instance_sunken_temple();
-void AddSC_instance_sunwell_plateau(); //Sunwell Plateau
-void AddSC_boss_kalecgos();
-void AddSC_boss_brutallus();
-void AddSC_boss_felmyst();
-void AddSC_boss_eredar_twins();
-void AddSC_boss_muru();
-void AddSC_boss_kiljaeden();
-void AddSC_sunwell_plateau();
-void AddSC_boss_archaedas(); //Uldaman
-void AddSC_boss_ironaya();
-void AddSC_uldaman();
-void AddSC_instance_uldaman();
-void AddSC_instance_the_stockade(); //The Stockade
-void AddSC_boss_akilzon(); //Zul'Aman
-void AddSC_boss_halazzi();
-void AddSC_boss_hex_lord_malacrass();
-void AddSC_boss_janalai();
-void AddSC_boss_nalorakk();
-void AddSC_boss_zuljin();
-void AddSC_instance_zulaman();
-void AddSC_zulaman();
-void AddSC_boss_jeklik(); //Zul'Gurub
-void AddSC_boss_venoxis();
-void AddSC_boss_marli();
-void AddSC_boss_mandokir();
-void AddSC_boss_gahzranka();
-void AddSC_boss_thekal();
-void AddSC_boss_arlokk();
-void AddSC_boss_jindo();
-void AddSC_boss_hakkar();
-void AddSC_boss_grilek();
-void AddSC_boss_hazzarah();
-void AddSC_boss_renataki();
-void AddSC_boss_wushoolay();
-void AddSC_instance_zulgurub();
-
-//void AddSC_alterac_mountains();
-void AddSC_arathi_highlands();
-void AddSC_blasted_lands();
-void AddSC_burning_steppes();
-void AddSC_duskwood();
-void AddSC_eastern_plaguelands();
-void AddSC_ghostlands();
-void AddSC_hinterlands();
-void AddSC_isle_of_queldanas();
-void AddSC_loch_modan();
-void AddSC_redridge_mountains();
-void AddSC_silverpine_forest();
-void AddSC_stormwind_city();
-void AddSC_stranglethorn_vale();
-void AddSC_swamp_of_sorrows();
-void AddSC_tirisfal_glades();
-void AddSC_undercity();
-void AddSC_western_plaguelands();
-void AddSC_wetlands();
-
-//kalimdor
-void AddSC_blackfathom_deeps(); //Blackfathom Depths
-void AddSC_boss_gelihast();
-void AddSC_boss_kelris();
-void AddSC_boss_aku_mai();
-void AddSC_instance_blackfathom_deeps();
-void AddSC_hyjal(); //CoT Battle for Mt. Hyjal
-void AddSC_boss_archimonde();
-void AddSC_instance_mount_hyjal();
-void AddSC_hyjal_trash();
-void AddSC_boss_rage_winterchill();
-void AddSC_boss_anetheron();
-void AddSC_boss_kazrogal();
-void AddSC_boss_azgalor();
-void AddSC_boss_captain_skarloc(); //CoT Old Hillsbrad
-void AddSC_boss_epoch_hunter();
-void AddSC_boss_lieutenant_drake();
-void AddSC_instance_old_hillsbrad();
-void AddSC_old_hillsbrad();
-void AddSC_boss_aeonus(); //CoT The Black Morass
-void AddSC_boss_chrono_lord_deja();
-void AddSC_boss_temporus();
-void AddSC_the_black_morass();
-void AddSC_instance_the_black_morass();
-void AddSC_boss_epoch(); //CoT Culling Of Stratholme
-void AddSC_boss_infinite_corruptor();
-void AddSC_boss_salramm();
-void AddSC_boss_mal_ganis();
-void AddSC_boss_meathook();
-void AddSC_culling_of_stratholme();
-void AddSC_instance_culling_of_stratholme();
-void AddSC_instance_dire_maul(); //Dire Maul
-void AddSC_boss_celebras_the_cursed(); //Maraudon
-void AddSC_boss_landslide();
-void AddSC_boss_noxxion();
-void AddSC_boss_ptheradras();
-void AddSC_instance_maraudon();
-void AddSC_boss_onyxia(); //Onyxia's Lair
-void AddSC_instance_onyxias_lair();
-void AddSC_boss_tuten_kash(); //Razorfen Downs
-void AddSC_boss_mordresh_fire_eye();
-void AddSC_boss_glutton();
-void AddSC_boss_amnennar_the_coldbringer();
-void AddSC_razorfen_downs();
-void AddSC_instance_razorfen_downs();
-void AddSC_razorfen_kraul(); //Razorfen Kraul
-void AddSC_instance_razorfen_kraul();
-void AddSC_boss_kurinnaxx(); //Ruins of ahn'qiraj
-void AddSC_boss_rajaxx();
-void AddSC_boss_moam();
-void AddSC_boss_buru();
-void AddSC_boss_ayamiss();
-void AddSC_boss_ossirian();
-void AddSC_instance_ruins_of_ahnqiraj();
-void AddSC_boss_cthun(); //Temple of ahn'qiraj
-void AddSC_boss_viscidus();
-void AddSC_boss_fankriss();
-void AddSC_boss_huhuran();
-void AddSC_bug_trio();
-void AddSC_boss_sartura();
-void AddSC_boss_skeram();
-void AddSC_boss_twinemperors();
-void AddSC_boss_ouro();
-void AddSC_npc_anubisath_sentinel();
-void AddSC_instance_temple_of_ahnqiraj();
-void AddSC_wailing_caverns(); //Wailing caverns
-void AddSC_instance_wailing_caverns();
-void AddSC_boss_zum_rah(); //Zul'Farrak
-void AddSC_zulfarrak();
-void AddSC_instance_zulfarrak();
-
-void AddSC_ashenvale();
-void AddSC_azshara();
-void AddSC_azuremyst_isle();
-void AddSC_bloodmyst_isle();
-void AddSC_boss_azuregos();
-void AddSC_darkshore();
-void AddSC_desolace();
-void AddSC_durotar();
-void AddSC_dustwallow_marsh();
-void AddSC_felwood();
-void AddSC_feralas();
-void AddSC_moonglade();
-void AddSC_orgrimmar();
-void AddSC_silithus();
-void AddSC_stonetalon_mountains();
-void AddSC_tanaris();
-void AddSC_the_barrens();
-void AddSC_thousand_needles();
-void AddSC_thunder_bluff();
-void AddSC_ungoro_crater();
-void AddSC_winterspring();
-
-// Northrend
-
-void AddSC_boss_slad_ran();
-void AddSC_boss_moorabi();
-void AddSC_boss_drakkari_colossus();
-void AddSC_boss_gal_darah();
-void AddSC_boss_eck();
-void AddSC_instance_gundrak();
-
-// Azjol-Nerub - Azjol-Nerub
-void AddSC_boss_krik_thir();
-void AddSC_boss_hadronox();
-void AddSC_boss_anub_arak();
-void AddSC_instance_azjol_nerub();
-
-// Azjol-Nerub - Ahn'kahet
-void AddSC_boss_elder_nadox();
-void AddSC_boss_taldaram();
-void AddSC_boss_amanitar();
-void AddSC_boss_jedoga_shadowseeker();
-void AddSC_boss_volazj();
-void AddSC_instance_ahnkahet();
-
-// Drak'Tharon Keep
-void AddSC_boss_trollgore();
-void AddSC_boss_novos();
-void AddSC_boss_king_dred();
-void AddSC_boss_tharon_ja();
-void AddSC_instance_drak_tharon_keep();
-
-void AddSC_boss_argent_challenge(); //Trial of the Champion
-void AddSC_boss_black_knight();
-void AddSC_boss_grand_champions();
-void AddSC_instance_trial_of_the_champion();
-void AddSC_trial_of_the_champion();
-void AddSC_boss_anubarak_trial(); //Trial of the Crusader
-void AddSC_boss_faction_champions();
-void AddSC_boss_jaraxxus();
-void AddSC_boss_northrend_beasts();
-void AddSC_boss_twin_valkyr();
-void AddSC_trial_of_the_crusader();
-void AddSC_instance_trial_of_the_crusader();
-void AddSC_boss_anubrekhan(); //Naxxramas
-void AddSC_boss_maexxna();
-void AddSC_boss_patchwerk();
-void AddSC_boss_grobbulus();
-void AddSC_boss_razuvious();
-void AddSC_boss_kelthuzad();
-void AddSC_boss_loatheb();
-void AddSC_boss_noth();
-void AddSC_boss_gluth();
-void AddSC_boss_sapphiron();
-void AddSC_boss_four_horsemen();
-void AddSC_boss_faerlina();
-void AddSC_boss_heigan();
-void AddSC_boss_gothik();
-void AddSC_boss_thaddius();
-void AddSC_instance_naxxramas();
-void AddSC_boss_nexus_commanders(); // The Nexus Nexus
-void AddSC_boss_magus_telestra();
-void AddSC_boss_anomalus();
-void AddSC_boss_ormorok();
-void AddSC_boss_keristrasza();
-void AddSC_instance_nexus();
-void AddSC_boss_drakos(); //The Nexus The Oculus
-void AddSC_boss_urom();
-void AddSC_boss_varos();
-void AddSC_boss_eregos();
-void AddSC_instance_oculus();
-void AddSC_oculus();
-void AddSC_boss_malygos(); // The Nexus: Eye of Eternity
-void AddSC_instance_eye_of_eternity();
-void AddSC_boss_sartharion(); //Obsidian Sanctum
-void AddSC_obsidian_sanctum();
-void AddSC_instance_obsidian_sanctum();
-void AddSC_boss_bjarngrim(); //Ulduar Halls of Lightning
-void AddSC_boss_loken();
-void AddSC_boss_ionar();
-void AddSC_boss_volkhan();
-void AddSC_instance_halls_of_lightning();
-void AddSC_boss_maiden_of_grief(); //Ulduar Halls of Stone
-void AddSC_boss_krystallus();
-void AddSC_boss_sjonnir();
-void AddSC_instance_halls_of_stone();
-void AddSC_halls_of_stone();
-void AddSC_boss_auriaya(); //Ulduar Ulduar
-void AddSC_boss_flame_leviathan();
-void AddSC_boss_ignis();
-void AddSC_boss_razorscale();
-void AddSC_boss_xt002();
-void AddSC_boss_kologarn();
-void AddSC_boss_assembly_of_iron();
-void AddSC_boss_general_vezax();
-void AddSC_boss_mimiron();
-void AddSC_boss_hodir();
-void AddSC_boss_freya();
-void AddSC_boss_yogg_saron();
-void AddSC_boss_algalon_the_observer();
-void AddSC_instance_ulduar();
-
-// Utgarde Keep - Utgarde Keep
-void AddSC_boss_keleseth();
-void AddSC_boss_skarvald_dalronn();
-void AddSC_boss_ingvar_the_plunderer();
-void AddSC_instance_utgarde_keep();
-void AddSC_utgarde_keep();
-
-// Utgarde Keep - Utgarde Pinnacle
-void AddSC_boss_svala();
-void AddSC_boss_palehoof();
-void AddSC_boss_skadi();
-void AddSC_boss_ymiron();
-void AddSC_instance_utgarde_pinnacle();
-
-// Vault of Archavon
-void AddSC_boss_archavon();
-void AddSC_boss_emalon();
-void AddSC_boss_koralon();
-void AddSC_boss_toravon();
-void AddSC_instance_vault_of_archavon();
-
-void AddSC_boss_cyanigosa(); //Violet Hold
-void AddSC_boss_erekem();
-void AddSC_boss_ichoron();
-void AddSC_boss_lavanthor();
-void AddSC_boss_moragg();
-void AddSC_boss_xevozz();
-void AddSC_boss_zuramat();
-void AddSC_instance_violet_hold();
-void AddSC_violet_hold();
-void AddSC_instance_forge_of_souls(); //Forge of Souls
-void AddSC_forge_of_souls();
-void AddSC_boss_bronjahm();
-void AddSC_boss_devourer_of_souls();
-void AddSC_instance_pit_of_saron(); //Pit of Saron
-void AddSC_pit_of_saron();
-void AddSC_boss_garfrost();
-void AddSC_boss_ick();
-void AddSC_boss_tyrannus();
-void AddSC_instance_halls_of_reflection(); // Halls of Reflection
-void AddSC_halls_of_reflection();
-void AddSC_boss_falric();
-void AddSC_boss_marwyn();
-void AddSC_boss_lord_marrowgar(); // Icecrown Citadel
-void AddSC_boss_lady_deathwhisper();
-void AddSC_boss_icecrown_gunship_battle();
-void AddSC_boss_deathbringer_saurfang();
-void AddSC_boss_festergut();
-void AddSC_boss_rotface();
-void AddSC_boss_professor_putricide();
-void AddSC_boss_blood_prince_council();
-void AddSC_boss_blood_queen_lana_thel();
-void AddSC_boss_valithria_dreamwalker();
-void AddSC_boss_sindragosa();
-void AddSC_boss_the_lich_king();
-void AddSC_icecrown_citadel_teleport();
-void AddSC_instance_icecrown_citadel();
-void AddSC_icecrown_citadel();
-void AddSC_instance_ruby_sanctum(); // Ruby Sanctum
-void AddSC_ruby_sanctum();
-void AddSC_boss_baltharus_the_warborn();
-void AddSC_boss_saviana_ragefire();
-void AddSC_boss_general_zarithrian();
-void AddSC_boss_halion();
-
-void AddSC_dalaran();
-void AddSC_borean_tundra();
-void AddSC_dragonblight();
-void AddSC_grizzly_hills();
-void AddSC_howling_fjord();
-void AddSC_icecrown();
-void AddSC_sholazar_basin();
-void AddSC_storm_peaks();
-void AddSC_wintergrasp();
-void AddSC_zuldrak();
-void AddSC_crystalsong_forest();
-void AddSC_isle_of_conquest();
-
-// Outland
-
-// Auchindoun - Auchenai Crypts
-void AddSC_boss_shirrak_the_dead_watcher();
-void AddSC_boss_exarch_maladaar();
-void AddSC_instance_auchenai_crypts();
-
-// Auchindoun - Mana Tombs
-void AddSC_boss_pandemonius();
-void AddSC_boss_nexusprince_shaffar();
-void AddSC_instance_mana_tombs();
-
-// Auchindoun - Sekketh Halls
-void AddSC_boss_darkweaver_syth();
-void AddSC_boss_talon_king_ikiss();
-void AddSC_boss_anzu();
-void AddSC_instance_sethekk_halls();
-
-// Auchindoun - Shadow Labyrinth
-void AddSC_boss_ambassador_hellmaw();
-void AddSC_boss_blackheart_the_inciter();
-void AddSC_boss_grandmaster_vorpil();
-void AddSC_boss_murmur();
-void AddSC_instance_shadow_labyrinth();
-
-// Black Temple
-void AddSC_black_temple();
-void AddSC_boss_illidan();
-void AddSC_boss_shade_of_akama();
-void AddSC_boss_supremus();
-void AddSC_boss_gurtogg_bloodboil();
-void AddSC_boss_mother_shahraz();
-void AddSC_boss_reliquary_of_souls();
-void AddSC_boss_teron_gorefiend();
-void AddSC_boss_najentus();
-void AddSC_boss_illidari_council();
-void AddSC_instance_black_temple();
-
-// Coilfang Reservoir - Serpent Shrine Cavern
-void AddSC_boss_fathomlord_karathress();
-void AddSC_boss_hydross_the_unstable();
-void AddSC_boss_lady_vashj();
-void AddSC_boss_leotheras_the_blind();
-void AddSC_boss_morogrim_tidewalker();
-void AddSC_instance_serpentshrine_cavern();
-void AddSC_boss_the_lurker_below();
-
-// Coilfang Reservoir - The Steam Vault
-void AddSC_boss_hydromancer_thespia();
-void AddSC_boss_mekgineer_steamrigger();
-void AddSC_boss_warlord_kalithresh();
-void AddSC_instance_steam_vault();
-
-// Coilfang Reservoir - The Slave Pens
-void AddSC_instance_the_slave_pens();
-void AddSC_boss_mennu_the_betrayer();
-void AddSC_boss_rokmar_the_crackler();
-void AddSC_boss_quagmirran();
-
-// Coilfang Reservoir - The Underbog
-void AddSC_instance_the_underbog();
-void AddSC_boss_hungarfen();
-void AddSC_boss_the_black_stalker();
-
-// Gruul's Lair
-void AddSC_boss_gruul();
-void AddSC_boss_high_king_maulgar();
-void AddSC_instance_gruuls_lair();
-void AddSC_boss_broggok(); //HC Blood Furnace
-void AddSC_boss_kelidan_the_breaker();
-void AddSC_boss_the_maker();
-void AddSC_instance_blood_furnace();
-void AddSC_boss_magtheridon(); //HC Magtheridon's Lair
-void AddSC_instance_magtheridons_lair();
-void AddSC_boss_grand_warlock_nethekurse(); //HC Shattered Halls
-void AddSC_boss_warbringer_omrogg();
-void AddSC_boss_warchief_kargath_bladefist();
-void AddSC_shattered_halls();
-void AddSC_instance_shattered_halls();
-void AddSC_boss_watchkeeper_gargolmar(); //HC Ramparts
-void AddSC_boss_omor_the_unscarred();
-void AddSC_boss_vazruden_the_herald();
-void AddSC_instance_ramparts();
-void AddSC_arcatraz(); //TK Arcatraz
-void AddSC_boss_zereketh_the_unbound();
-void AddSC_boss_dalliah_the_doomsayer();
-void AddSC_boss_wrath_scryer_soccothrates();
-void AddSC_boss_harbinger_skyriss();
-void AddSC_instance_arcatraz();
-void AddSC_boss_high_botanist_freywinn(); //TK Botanica
-void AddSC_boss_laj();
-void AddSC_boss_warp_splinter();
-void AddSC_boss_thorngrin_the_tender();
-void AddSC_boss_commander_sarannis();
-void AddSC_instance_the_botanica();
-void AddSC_boss_alar(); //TK The Eye
-void AddSC_boss_kaelthas();
-void AddSC_boss_void_reaver();
-void AddSC_boss_high_astromancer_solarian();
-void AddSC_instance_the_eye();
-void AddSC_the_eye();
-void AddSC_boss_gatewatcher_iron_hand(); //TK The Mechanar
-void AddSC_boss_gatewatcher_gyrokill();
-void AddSC_boss_nethermancer_sepethrea();
-void AddSC_boss_pathaleon_the_calculator();
-void AddSC_boss_mechano_lord_capacitus();
-void AddSC_instance_mechanar();
-
-void AddSC_blades_edge_mountains();
-void AddSC_boss_doomlordkazzak();
-void AddSC_boss_doomwalker();
-void AddSC_hellfire_peninsula();
-void AddSC_nagrand();
-void AddSC_netherstorm();
-void AddSC_shadowmoon_valley();
-void AddSC_shattrath_city();
-void AddSC_terokkar_forest();
-void AddSC_zangarmarsh();
-
-// Events
-void AddSC_event_childrens_week();
-
-// Pets
-void AddSC_deathknight_pet_scripts();
-void AddSC_generic_pet_scripts();
-void AddSC_hunter_pet_scripts();
-void AddSC_mage_pet_scripts();
-void AddSC_priest_pet_scripts();
-void AddSC_shaman_pet_scripts();
-
-// battlegrounds
-
-// outdoor pvp
-void AddSC_outdoorpvp_ep();
-void AddSC_outdoorpvp_hp();
-void AddSC_outdoorpvp_na();
-void AddSC_outdoorpvp_si();
-void AddSC_outdoorpvp_tf();
-void AddSC_outdoorpvp_zm();
-
-// player
-void AddSC_chat_log();
-void AddSC_action_ip_logger();
-
-#endif
-
-void AddScripts()
-{
- AddSpellScripts();
- AddSC_SmartScripts();
- AddCommandScripts();
-#ifdef SCRIPTS
- AddWorldScripts();
- AddEasternKingdomsScripts();
- AddKalimdorScripts();
- AddOutlandScripts();
- AddNorthrendScripts();
- AddEventScripts();
- AddPetScripts();
- AddBattlegroundScripts();
- AddOutdoorPvPScripts();
- AddCustomScripts();
-#endif
-}
-
-void AddSpellScripts()
-{
- AddSC_deathknight_spell_scripts();
- AddSC_druid_spell_scripts();
- AddSC_generic_spell_scripts();
- AddSC_hunter_spell_scripts();
- AddSC_mage_spell_scripts();
- AddSC_paladin_spell_scripts();
- AddSC_priest_spell_scripts();
- AddSC_rogue_spell_scripts();
- AddSC_shaman_spell_scripts();
- AddSC_warlock_spell_scripts();
- AddSC_warrior_spell_scripts();
- AddSC_quest_spell_scripts();
- AddSC_item_spell_scripts();
- AddSC_holiday_spell_scripts();
-}
-
-void AddCommandScripts()
-{
- AddSC_account_commandscript();
- AddSC_achievement_commandscript();
- AddSC_ahbot_commandscript();
- AddSC_arena_commandscript();
- AddSC_ban_commandscript();
- AddSC_bf_commandscript();
- AddSC_cast_commandscript();
- AddSC_character_commandscript();
- AddSC_cheat_commandscript();
- AddSC_debug_commandscript();
- AddSC_deserter_commandscript();
- AddSC_disable_commandscript();
- AddSC_event_commandscript();
- AddSC_gm_commandscript();
- AddSC_go_commandscript();
- AddSC_gobject_commandscript();
- AddSC_group_commandscript();
- AddSC_guild_commandscript();
- AddSC_honor_commandscript();
- AddSC_instance_commandscript();
- AddSC_learn_commandscript();
- AddSC_lookup_commandscript();
- AddSC_lfg_commandscript();
- AddSC_list_commandscript();
- AddSC_message_commandscript();
- AddSC_misc_commandscript();
- AddSC_mmaps_commandscript();
- AddSC_modify_commandscript();
- AddSC_npc_commandscript();
- AddSC_quest_commandscript();
- AddSC_pet_commandscript();
- AddSC_rbac_commandscript();
- AddSC_reload_commandscript();
- AddSC_reset_commandscript();
- AddSC_send_commandscript();
- AddSC_server_commandscript();
- AddSC_tele_commandscript();
- AddSC_ticket_commandscript();
- AddSC_titles_commandscript();
- AddSC_wp_commandscript();
-}
-
-void AddWorldScripts()
-{
-#ifdef SCRIPTS
- AddSC_areatrigger_scripts();
- AddSC_emerald_dragons();
- AddSC_generic_creature();
- AddSC_go_scripts();
- AddSC_guards();
- AddSC_item_scripts();
- AddSC_npc_professions();
- AddSC_npc_innkeeper();
- AddSC_npcs_special();
- AddSC_achievement_scripts();
- AddSC_chat_log(); // location: scripts\World\chat_log.cpp
- // To avoid duplicate code, we check once /*ONLY*/ if logging is permitted or not.
- if (sWorld->getBoolConfig(CONFIG_IP_BASED_ACTION_LOGGING))
- AddSC_action_ip_logger(); // location: scripts\World\action_ip_logger.cpp
- AddSC_duel_reset();
-#endif
-}
-
-void AddEasternKingdomsScripts()
-{
-#ifdef SCRIPTS
- AddSC_alterac_valley(); //Alterac Valley
- AddSC_boss_balinda();
- AddSC_boss_drekthar();
- AddSC_boss_galvangar();
- AddSC_boss_vanndar();
- AddSC_blackrock_depths(); //Blackrock Depths
- AddSC_boss_ambassador_flamelash();
- AddSC_boss_draganthaurissan();
- AddSC_boss_general_angerforge();
- AddSC_boss_high_interrogator_gerstahn();
- AddSC_boss_magmus();
- AddSC_boss_moira_bronzebeard();
- AddSC_boss_tomb_of_seven();
- AddSC_instance_blackrock_depths();
- AddSC_boss_drakkisath(); //Blackrock Spire
- AddSC_boss_halycon();
- AddSC_boss_highlordomokk();
- AddSC_boss_mothersmolderweb();
- AddSC_boss_overlordwyrmthalak();
- AddSC_boss_shadowvosh();
- AddSC_boss_thebeast();
- AddSC_boss_warmastervoone();
- AddSC_boss_quatermasterzigris();
- AddSC_boss_pyroguard_emberseer();
- AddSC_boss_gyth();
- AddSC_boss_rend_blackhand();
- AddSC_boss_gizrul_the_slavener();
- AddSC_boss_urok_doomhowl();
- AddSC_boss_lord_valthalak();
- AddSC_instance_blackrock_spire();
- AddSC_boss_razorgore(); //Blackwing lair
- AddSC_boss_vaelastrasz();
- AddSC_boss_broodlord();
- AddSC_boss_firemaw();
- AddSC_boss_ebonroc();
- AddSC_boss_flamegor();
- AddSC_boss_chromaggus();
- AddSC_boss_nefarian();
- AddSC_instance_blackwing_lair();
- AddSC_deadmines(); //Deadmines
- AddSC_boss_mr_smite();
- AddSC_instance_deadmines();
- AddSC_gnomeregan(); //Gnomeregan
- AddSC_instance_gnomeregan();
- AddSC_boss_attumen(); //Karazhan
- AddSC_boss_curator();
- AddSC_boss_maiden_of_virtue();
- AddSC_boss_shade_of_aran();
- AddSC_boss_malchezaar();
- AddSC_boss_terestian_illhoof();
- AddSC_boss_moroes();
- AddSC_bosses_opera();
- AddSC_boss_netherspite();
- AddSC_instance_karazhan();
- AddSC_karazhan();
- AddSC_boss_nightbane();
- AddSC_boss_felblood_kaelthas(); // Magister's Terrace
- AddSC_boss_selin_fireheart();
- AddSC_boss_vexallus();
- AddSC_boss_priestess_delrissa();
- AddSC_instance_magisters_terrace();
- AddSC_magisters_terrace();
- AddSC_boss_lucifron(); //Molten core
- AddSC_boss_magmadar();
- AddSC_boss_gehennas();
- AddSC_boss_garr();
- AddSC_boss_baron_geddon();
- AddSC_boss_shazzrah();
- AddSC_boss_golemagg();
- AddSC_boss_sulfuron();
- AddSC_boss_majordomo();
- AddSC_boss_ragnaros();
- AddSC_instance_molten_core();
- AddSC_instance_ragefire_chasm(); //Ragefire Chasm
- AddSC_the_scarlet_enclave(); //Scarlet Enclave
- AddSC_the_scarlet_enclave_c1();
- AddSC_the_scarlet_enclave_c2();
- AddSC_the_scarlet_enclave_c5();
- AddSC_boss_arcanist_doan(); //Scarlet Monastery
- AddSC_boss_azshir_the_sleepless();
- AddSC_boss_bloodmage_thalnos();
- AddSC_boss_headless_horseman();
- AddSC_boss_herod();
- AddSC_boss_high_inquisitor_fairbanks();
- AddSC_boss_houndmaster_loksey();
- AddSC_boss_interrogator_vishas();
- AddSC_boss_scorn();
- AddSC_instance_scarlet_monastery();
- AddSC_boss_mograine_and_whitemane();
- AddSC_boss_darkmaster_gandling(); //Scholomance
- AddSC_boss_death_knight_darkreaver();
- AddSC_boss_theolenkrastinov();
- AddSC_boss_illuciabarov();
- AddSC_boss_instructormalicia();
- AddSC_boss_jandicebarov();
- AddSC_boss_kormok();
- AddSC_boss_lordalexeibarov();
- AddSC_boss_lorekeeperpolkelt();
- AddSC_boss_rasfrost();
- AddSC_boss_theravenian();
- AddSC_boss_vectus();
- AddSC_boss_kirtonos_the_herald();
- AddSC_instance_scholomance();
- AddSC_shadowfang_keep(); //Shadowfang keep
- AddSC_instance_shadowfang_keep();
- AddSC_boss_magistrate_barthilas(); //Stratholme
- AddSC_boss_maleki_the_pallid();
- AddSC_boss_nerubenkan();
- AddSC_boss_cannon_master_willey();
- AddSC_boss_baroness_anastari();
- AddSC_boss_ramstein_the_gorger();
- AddSC_boss_timmy_the_cruel();
- AddSC_boss_postmaster_malown();
- AddSC_boss_baron_rivendare();
- AddSC_boss_dathrohan_balnazzar();
- AddSC_boss_order_of_silver_hand();
- AddSC_instance_stratholme();
- AddSC_stratholme();
- AddSC_sunken_temple(); // Sunken Temple
- AddSC_instance_sunken_temple();
- AddSC_instance_sunwell_plateau(); //Sunwell Plateau
- AddSC_boss_kalecgos();
- AddSC_boss_brutallus();
- AddSC_boss_felmyst();
- AddSC_boss_eredar_twins();
- AddSC_boss_muru();
- AddSC_boss_kiljaeden();
- AddSC_sunwell_plateau();
- AddSC_instance_the_stockade(); //The Stockade
- AddSC_boss_archaedas(); //Uldaman
- AddSC_boss_ironaya();
- AddSC_uldaman();
- AddSC_instance_uldaman();
- AddSC_boss_akilzon(); //Zul'Aman
- AddSC_boss_halazzi();
- AddSC_boss_hex_lord_malacrass();
- AddSC_boss_janalai();
- AddSC_boss_nalorakk();
- AddSC_boss_zuljin();
- AddSC_instance_zulaman();
- AddSC_zulaman();
- AddSC_boss_jeklik(); //Zul'Gurub
- AddSC_boss_venoxis();
- AddSC_boss_marli();
- AddSC_boss_mandokir();
- AddSC_boss_gahzranka();
- AddSC_boss_thekal();
- AddSC_boss_arlokk();
- AddSC_boss_jindo();
- AddSC_boss_hakkar();
- AddSC_boss_grilek();
- AddSC_boss_hazzarah();
- AddSC_boss_renataki();
- AddSC_boss_wushoolay();
- AddSC_instance_zulgurub();
-
- //AddSC_alterac_mountains();
- AddSC_arathi_highlands();
- AddSC_blasted_lands();
- AddSC_burning_steppes();
- AddSC_duskwood();
- AddSC_eastern_plaguelands();
- AddSC_ghostlands();
- AddSC_hinterlands();
- AddSC_isle_of_queldanas();
- AddSC_loch_modan();
- AddSC_redridge_mountains();
- AddSC_silverpine_forest();
- AddSC_stormwind_city();
- AddSC_stranglethorn_vale();
- AddSC_swamp_of_sorrows();
- AddSC_tirisfal_glades();
- AddSC_undercity();
- AddSC_western_plaguelands();
- AddSC_wetlands();
-#endif
-}
-
-void AddKalimdorScripts()
-{
-#ifdef SCRIPTS
- AddSC_blackfathom_deeps(); //Blackfathom Depths
- AddSC_boss_gelihast();
- AddSC_boss_kelris();
- AddSC_boss_aku_mai();
- AddSC_instance_blackfathom_deeps();
- AddSC_hyjal(); //CoT Battle for Mt. Hyjal
- AddSC_boss_archimonde();
- AddSC_instance_mount_hyjal();
- AddSC_hyjal_trash();
- AddSC_boss_rage_winterchill();
- AddSC_boss_anetheron();
- AddSC_boss_kazrogal();
- AddSC_boss_azgalor();
- AddSC_boss_captain_skarloc(); //CoT Old Hillsbrad
- AddSC_boss_epoch_hunter();
- AddSC_boss_lieutenant_drake();
- AddSC_instance_old_hillsbrad();
- AddSC_old_hillsbrad();
- AddSC_boss_aeonus(); //CoT The Black Morass
- AddSC_boss_chrono_lord_deja();
- AddSC_boss_temporus();
- AddSC_the_black_morass();
- AddSC_instance_the_black_morass();
- AddSC_boss_epoch(); //CoT Culling Of Stratholme
- AddSC_boss_infinite_corruptor();
- AddSC_boss_salramm();
- AddSC_boss_mal_ganis();
- AddSC_boss_meathook();
- AddSC_culling_of_stratholme();
- AddSC_instance_culling_of_stratholme();
- AddSC_instance_dire_maul(); //Dire Maul
- AddSC_boss_celebras_the_cursed(); //Maraudon
- AddSC_boss_landslide();
- AddSC_boss_noxxion();
- AddSC_boss_ptheradras();
- AddSC_instance_maraudon();
- AddSC_boss_onyxia(); //Onyxia's Lair
- AddSC_instance_onyxias_lair();
- AddSC_boss_tuten_kash(); //Razorfen Downs
- AddSC_boss_mordresh_fire_eye();
- AddSC_boss_glutton();
- AddSC_boss_amnennar_the_coldbringer();
- AddSC_razorfen_downs();
- AddSC_instance_razorfen_downs();
- AddSC_razorfen_kraul(); //Razorfen Kraul
- AddSC_instance_razorfen_kraul();
- AddSC_boss_kurinnaxx(); //Ruins of ahn'qiraj
- AddSC_boss_rajaxx();
- AddSC_boss_moam();
- AddSC_boss_buru();
- AddSC_boss_ayamiss();
- AddSC_boss_ossirian();
- AddSC_instance_ruins_of_ahnqiraj();
- AddSC_boss_cthun(); //Temple of ahn'qiraj
- AddSC_boss_viscidus();
- AddSC_boss_fankriss();
- AddSC_boss_huhuran();
- AddSC_bug_trio();
- AddSC_boss_sartura();
- AddSC_boss_skeram();
- AddSC_boss_twinemperors();
- AddSC_boss_ouro();
- AddSC_npc_anubisath_sentinel();
- AddSC_instance_temple_of_ahnqiraj();
- AddSC_wailing_caverns(); //Wailing caverns
- AddSC_instance_wailing_caverns();
- AddSC_boss_zum_rah(); //Zul'Farrak
- AddSC_zulfarrak();
- AddSC_instance_zulfarrak();
-
- AddSC_ashenvale();
- AddSC_azshara();
- AddSC_azuremyst_isle();
- AddSC_bloodmyst_isle();
- AddSC_boss_azuregos();
- AddSC_darkshore();
- AddSC_desolace();
- AddSC_durotar();
- AddSC_dustwallow_marsh();
- AddSC_felwood();
- AddSC_feralas();
- AddSC_moonglade();
- AddSC_orgrimmar();
- AddSC_silithus();
- AddSC_stonetalon_mountains();
- AddSC_tanaris();
- AddSC_the_barrens();
- AddSC_thousand_needles();
- AddSC_thunder_bluff();
- AddSC_ungoro_crater();
- AddSC_winterspring();
-#endif
-}
-
-void AddOutlandScripts()
-{
-#ifdef SCRIPTS
- // Auchindoun - Auchenai Crypts
- AddSC_boss_shirrak_the_dead_watcher();
- AddSC_boss_exarch_maladaar();
- AddSC_instance_auchenai_crypts();
-
- // Auchindoun - Mana Tombs
- AddSC_boss_pandemonius();
- AddSC_boss_nexusprince_shaffar();
- AddSC_instance_mana_tombs();
-
- // Auchindoun - Sekketh Halls
- AddSC_boss_darkweaver_syth();
- AddSC_boss_talon_king_ikiss();
- AddSC_boss_anzu();
- AddSC_instance_sethekk_halls();
-
- // Auchindoun - Shadow Labyrinth
- AddSC_boss_ambassador_hellmaw();
- AddSC_boss_blackheart_the_inciter();
- AddSC_boss_grandmaster_vorpil();
- AddSC_boss_murmur();
- AddSC_instance_shadow_labyrinth();
-
- // Black Temple
- AddSC_black_temple();
- AddSC_boss_illidan();
- AddSC_boss_shade_of_akama();
- AddSC_boss_supremus();
- AddSC_boss_gurtogg_bloodboil();
- AddSC_boss_mother_shahraz();
- AddSC_boss_reliquary_of_souls();
- AddSC_boss_teron_gorefiend();
- AddSC_boss_najentus();
- AddSC_boss_illidari_council();
- AddSC_instance_black_temple();
-
- // Coilfang Reservoir - Serpent Shrine Cavern
- AddSC_boss_fathomlord_karathress();
- AddSC_boss_hydross_the_unstable();
- AddSC_boss_lady_vashj();
- AddSC_boss_leotheras_the_blind();
- AddSC_boss_morogrim_tidewalker();
- AddSC_instance_serpentshrine_cavern();
- AddSC_boss_the_lurker_below();
-
- // Coilfang Reservoir - The Steam Vault
- AddSC_instance_steam_vault();
- AddSC_boss_hydromancer_thespia();
- AddSC_boss_mekgineer_steamrigger();
- AddSC_boss_warlord_kalithresh();
-
- // Coilfang Reservoir - The Slave Pens
- AddSC_instance_the_slave_pens();
- AddSC_boss_mennu_the_betrayer();
- AddSC_boss_rokmar_the_crackler();
- AddSC_boss_quagmirran();
-
- // Coilfang Reservoir - The Underbog
- AddSC_instance_the_underbog();
- AddSC_boss_hungarfen();
- AddSC_boss_the_black_stalker();
-
- // Gruul's Lair
- AddSC_boss_gruul();
- AddSC_boss_high_king_maulgar();
- AddSC_instance_gruuls_lair();
- AddSC_boss_broggok(); //HC Blood Furnace
- AddSC_boss_kelidan_the_breaker();
- AddSC_boss_the_maker();
- AddSC_instance_blood_furnace();
- AddSC_boss_magtheridon(); //HC Magtheridon's Lair
- AddSC_instance_magtheridons_lair();
- AddSC_boss_grand_warlock_nethekurse(); //HC Shattered Halls
- AddSC_boss_warbringer_omrogg();
- AddSC_boss_warchief_kargath_bladefist();
- AddSC_shattered_halls();
- AddSC_instance_shattered_halls();
- AddSC_boss_watchkeeper_gargolmar(); //HC Ramparts
- AddSC_boss_omor_the_unscarred();
- AddSC_boss_vazruden_the_herald();
- AddSC_instance_ramparts();
- AddSC_arcatraz(); //TK Arcatraz
- AddSC_boss_zereketh_the_unbound();
- AddSC_boss_dalliah_the_doomsayer();
- AddSC_boss_wrath_scryer_soccothrates();
- AddSC_boss_harbinger_skyriss();
- AddSC_instance_arcatraz();
- AddSC_boss_high_botanist_freywinn(); //TK Botanica
- AddSC_boss_laj();
- AddSC_boss_warp_splinter();
- AddSC_boss_thorngrin_the_tender();
- AddSC_boss_commander_sarannis();
- AddSC_instance_the_botanica();
- AddSC_boss_alar(); //TK The Eye
- AddSC_boss_kaelthas();
- AddSC_boss_void_reaver();
- AddSC_boss_high_astromancer_solarian();
- AddSC_instance_the_eye();
- AddSC_the_eye();
- AddSC_boss_gatewatcher_iron_hand(); //TK The Mechanar
- AddSC_boss_gatewatcher_gyrokill();
- AddSC_boss_nethermancer_sepethrea();
- AddSC_boss_pathaleon_the_calculator();
- AddSC_boss_mechano_lord_capacitus();
- AddSC_instance_mechanar();
-
- AddSC_blades_edge_mountains();
- AddSC_boss_doomlordkazzak();
- AddSC_boss_doomwalker();
- AddSC_hellfire_peninsula();
- AddSC_nagrand();
- AddSC_netherstorm();
- AddSC_shadowmoon_valley();
- AddSC_shattrath_city();
- AddSC_terokkar_forest();
- AddSC_zangarmarsh();
-#endif
-}
-
-void AddNorthrendScripts()
-{
-#ifdef SCRIPTS
- AddSC_boss_slad_ran(); //Gundrak
- AddSC_boss_moorabi();
- AddSC_boss_drakkari_colossus();
- AddSC_boss_gal_darah();
- AddSC_boss_eck();
- AddSC_instance_gundrak();
-
- // Azjol-Nerub - Ahn'kahet
- AddSC_boss_elder_nadox();
- AddSC_boss_taldaram();
- AddSC_boss_amanitar();
- AddSC_boss_jedoga_shadowseeker();
- AddSC_boss_volazj();
- AddSC_instance_ahnkahet();
-
- // Azjol-Nerub - Azjol-Nerub
- AddSC_boss_krik_thir();
- AddSC_boss_hadronox();
- AddSC_boss_anub_arak();
- AddSC_instance_azjol_nerub();
-
- // Drak'Tharon Keep
- AddSC_boss_trollgore();
- AddSC_boss_novos();
- AddSC_boss_king_dred();
- AddSC_boss_tharon_ja();
- AddSC_instance_drak_tharon_keep();
-
- AddSC_boss_argent_challenge(); //Trial of the Champion
- AddSC_boss_black_knight();
- AddSC_boss_grand_champions();
- AddSC_instance_trial_of_the_champion();
- AddSC_trial_of_the_champion();
- AddSC_boss_anubarak_trial(); //Trial of the Crusader
- AddSC_boss_faction_champions();
- AddSC_boss_jaraxxus();
- AddSC_trial_of_the_crusader();
- AddSC_boss_twin_valkyr();
- AddSC_boss_northrend_beasts();
- AddSC_instance_trial_of_the_crusader();
- AddSC_boss_anubrekhan(); //Naxxramas
- AddSC_boss_maexxna();
- AddSC_boss_patchwerk();
- AddSC_boss_grobbulus();
- AddSC_boss_razuvious();
- AddSC_boss_kelthuzad();
- AddSC_boss_loatheb();
- AddSC_boss_noth();
- AddSC_boss_gluth();
- AddSC_boss_sapphiron();
- AddSC_boss_four_horsemen();
- AddSC_boss_faerlina();
- AddSC_boss_heigan();
- AddSC_boss_gothik();
- AddSC_boss_thaddius();
- AddSC_instance_naxxramas();
- AddSC_boss_nexus_commanders(); // The Nexus Nexus
- AddSC_boss_magus_telestra();
- AddSC_boss_anomalus();
- AddSC_boss_ormorok();
- AddSC_boss_keristrasza();
- AddSC_instance_nexus();
- AddSC_boss_drakos(); //The Nexus The Oculus
- AddSC_boss_urom();
- AddSC_boss_varos();
- AddSC_boss_eregos();
- AddSC_instance_oculus();
- AddSC_oculus();
- AddSC_boss_malygos(); // The Nexus: Eye of Eternity
- AddSC_instance_eye_of_eternity();
- AddSC_boss_sartharion(); //Obsidian Sanctum
- AddSC_obsidian_sanctum();
- AddSC_instance_obsidian_sanctum();
- AddSC_boss_bjarngrim(); //Ulduar Halls of Lightning
- AddSC_boss_loken();
- AddSC_boss_ionar();
- AddSC_boss_volkhan();
- AddSC_instance_halls_of_lightning();
- AddSC_boss_maiden_of_grief(); //Ulduar Halls of Stone
- AddSC_boss_krystallus();
- AddSC_boss_sjonnir();
- AddSC_instance_halls_of_stone();
- AddSC_halls_of_stone();
- AddSC_boss_auriaya(); //Ulduar Ulduar
- AddSC_boss_flame_leviathan();
- AddSC_boss_ignis();
- AddSC_boss_razorscale();
- AddSC_boss_xt002();
- AddSC_boss_general_vezax();
- AddSC_boss_assembly_of_iron();
- AddSC_boss_kologarn();
- AddSC_boss_mimiron();
- AddSC_boss_hodir();
- AddSC_boss_freya();
- AddSC_boss_yogg_saron();
- AddSC_boss_algalon_the_observer();
- AddSC_instance_ulduar();
-
- // Utgarde Keep - Utgarde Keep
- AddSC_boss_keleseth();
- AddSC_boss_skarvald_dalronn();
- AddSC_boss_ingvar_the_plunderer();
- AddSC_instance_utgarde_keep();
- AddSC_utgarde_keep();
-
- // Utgarde Keep - Utgarde Pinnacle
- AddSC_boss_svala();
- AddSC_boss_palehoof();
- AddSC_boss_skadi();
- AddSC_boss_ymiron();
- AddSC_instance_utgarde_pinnacle();
-
- // Vault of Archavon
- AddSC_boss_archavon();
- AddSC_boss_emalon();
- AddSC_boss_koralon();
- AddSC_boss_toravon();
- AddSC_instance_vault_of_archavon();
-
- AddSC_boss_cyanigosa(); //Violet Hold
- AddSC_boss_erekem();
- AddSC_boss_ichoron();
- AddSC_boss_lavanthor();
- AddSC_boss_moragg();
- AddSC_boss_xevozz();
- AddSC_boss_zuramat();
- AddSC_instance_violet_hold();
- AddSC_violet_hold();
- AddSC_instance_forge_of_souls(); //Forge of Souls
- AddSC_forge_of_souls();
- AddSC_boss_bronjahm();
- AddSC_boss_devourer_of_souls();
- AddSC_instance_pit_of_saron(); //Pit of Saron
- AddSC_pit_of_saron();
- AddSC_boss_garfrost();
- AddSC_boss_ick();
- AddSC_boss_tyrannus();
- AddSC_instance_halls_of_reflection(); // Halls of Reflection
- AddSC_halls_of_reflection();
- AddSC_boss_falric();
- AddSC_boss_marwyn();
- AddSC_boss_lord_marrowgar(); // Icecrown Citadel
- AddSC_boss_lady_deathwhisper();
- AddSC_boss_icecrown_gunship_battle();
- AddSC_boss_deathbringer_saurfang();
- AddSC_boss_festergut();
- AddSC_boss_rotface();
- AddSC_boss_professor_putricide();
- AddSC_boss_blood_prince_council();
- AddSC_boss_blood_queen_lana_thel();
- AddSC_boss_valithria_dreamwalker();
- AddSC_boss_sindragosa();
- AddSC_boss_the_lich_king();
- AddSC_icecrown_citadel_teleport();
- AddSC_instance_icecrown_citadel();
- AddSC_icecrown_citadel();
- AddSC_instance_ruby_sanctum(); // Ruby Sanctum
- AddSC_ruby_sanctum();
- AddSC_boss_baltharus_the_warborn();
- AddSC_boss_saviana_ragefire();
- AddSC_boss_general_zarithrian();
- AddSC_boss_halion();
-
- AddSC_dalaran();
- AddSC_borean_tundra();
- AddSC_dragonblight();
- AddSC_grizzly_hills();
- AddSC_howling_fjord();
- AddSC_icecrown();
- AddSC_sholazar_basin();
- AddSC_storm_peaks();
- AddSC_wintergrasp();
- AddSC_zuldrak();
- AddSC_crystalsong_forest();
- AddSC_isle_of_conquest();
-#endif
-}
-
-void AddEventScripts()
-{
-#ifdef SCRIPTS
- AddSC_event_childrens_week();
-#endif
-}
-
-void AddPetScripts()
-{
-#ifdef SCRIPTS
- AddSC_deathknight_pet_scripts();
- AddSC_generic_pet_scripts();
- AddSC_hunter_pet_scripts();
- AddSC_mage_pet_scripts();
- AddSC_priest_pet_scripts();
- AddSC_shaman_pet_scripts();
-#endif
-}
-
-void AddOutdoorPvPScripts()
-{
-#ifdef SCRIPTS
- AddSC_outdoorpvp_ep();
- AddSC_outdoorpvp_hp();
- AddSC_outdoorpvp_na();
- AddSC_outdoorpvp_si();
- AddSC_outdoorpvp_tf();
- AddSC_outdoorpvp_zm();
-#endif
-}
-
-void AddBattlegroundScripts()
-{
-#ifdef SCRIPTS
-#endif
-}
-
-#ifdef SCRIPTS
-/* This is where custom scripts' loading functions should be declared. */
-
-#endif
-
-void AddCustomScripts()
-{
-#ifdef SCRIPTS
- /* This is where custom scripts should be added. */
-
-#endif
-}
diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp
index 4b26ba96c9b..4218746893f 100644
--- a/src/server/game/Scripting/ScriptMgr.cpp
+++ b/src/server/game/Scripting/ScriptMgr.cpp
@@ -22,10 +22,10 @@
#include "DBCStores.h"
#include "ObjectMgr.h"
#include "OutdoorPvPMgr.h"
-#include "ScriptLoader.h"
#include "ScriptSystem.h"
#include "Transport.h"
#include "Vehicle.h"
+#include "SmartAI.h"
#include "SpellInfo.h"
#include "SpellScript.h"
#include "GossipDef.h"
@@ -240,12 +240,19 @@ struct TSpellSummary
uint8 Effects; // set of enum SelectEffect
} *SpellSummary;
-ScriptMgr::ScriptMgr() : _scriptCount(0), _scheduledScripts(0)
+ScriptMgr::ScriptMgr()
+ : _scriptCount(0), _scheduledScripts(0), _script_loader_callback(nullptr)
{
}
ScriptMgr::~ScriptMgr() { }
+ScriptMgr* ScriptMgr::instance()
+{
+ static ScriptMgr instance;
+ return &instance;
+}
+
void ScriptMgr::Initialize()
{
uint32 oldMSTime = getMSTime();
@@ -255,7 +262,13 @@ void ScriptMgr::Initialize()
TC_LOG_INFO("server.loading", "Loading C++ scripts");
FillSpellSummary();
- AddScripts();
+
+ AddSC_SmartScripts();
+
+ ASSERT(_script_loader_callback,
+ "Script loader callback wasn't registered!");
+
+ _script_loader_callback();
#ifdef SCRIPTS
for (std::string const& scriptName : UnusedScriptNames)
@@ -501,17 +514,6 @@ void ScriptMgr::OnPacketSend(WorldSession* session, WorldPacket const& packet)
FOREACH_SCRIPT(ServerScript)->OnPacketSend(session, copy);
}
-void ScriptMgr::OnUnknownPacketReceive(WorldSession* session, WorldPacket const& packet)
-{
- ASSERT(session);
-
- if (SCR_REG_LST(ServerScript).empty())
- return;
-
- WorldPacket copy(packet);
- FOREACH_SCRIPT(ServerScript)->OnUnknownPacketReceive(session, copy);
-}
-
void ScriptMgr::OnOpenStateChange(bool open)
{
FOREACH_SCRIPT(WorldScript)->OnOpenStateChange(open);
@@ -1686,32 +1688,32 @@ template<class TScript> std::vector<TScript*> ScriptRegistry<TScript>::Scripts;
template<class TScript> uint32 ScriptRegistry<TScript>::_scriptIdCounter = 0;
// Specialize for each script type class like so:
-template class ScriptRegistry<SpellScriptLoader>;
-template class ScriptRegistry<ServerScript>;
-template class ScriptRegistry<WorldScript>;
-template class ScriptRegistry<FormulaScript>;
-template class ScriptRegistry<WorldMapScript>;
-template class ScriptRegistry<InstanceMapScript>;
-template class ScriptRegistry<BattlegroundMapScript>;
-template class ScriptRegistry<ItemScript>;
-template class ScriptRegistry<CreatureScript>;
-template class ScriptRegistry<GameObjectScript>;
-template class ScriptRegistry<AreaTriggerScript>;
-template class ScriptRegistry<BattlegroundScript>;
-template class ScriptRegistry<OutdoorPvPScript>;
-template class ScriptRegistry<CommandScript>;
-template class ScriptRegistry<WeatherScript>;
-template class ScriptRegistry<AuctionHouseScript>;
-template class ScriptRegistry<ConditionScript>;
-template class ScriptRegistry<VehicleScript>;
-template class ScriptRegistry<DynamicObjectScript>;
-template class ScriptRegistry<TransportScript>;
-template class ScriptRegistry<AchievementCriteriaScript>;
-template class ScriptRegistry<PlayerScript>;
-template class ScriptRegistry<GuildScript>;
-template class ScriptRegistry<GroupScript>;
-template class ScriptRegistry<UnitScript>;
-template class ScriptRegistry<AccountScript>;
+template class TC_GAME_API ScriptRegistry<SpellScriptLoader>;
+template class TC_GAME_API ScriptRegistry<ServerScript>;
+template class TC_GAME_API ScriptRegistry<WorldScript>;
+template class TC_GAME_API ScriptRegistry<FormulaScript>;
+template class TC_GAME_API ScriptRegistry<WorldMapScript>;
+template class TC_GAME_API ScriptRegistry<InstanceMapScript>;
+template class TC_GAME_API ScriptRegistry<BattlegroundMapScript>;
+template class TC_GAME_API ScriptRegistry<ItemScript>;
+template class TC_GAME_API ScriptRegistry<CreatureScript>;
+template class TC_GAME_API ScriptRegistry<GameObjectScript>;
+template class TC_GAME_API ScriptRegistry<AreaTriggerScript>;
+template class TC_GAME_API ScriptRegistry<BattlegroundScript>;
+template class TC_GAME_API ScriptRegistry<OutdoorPvPScript>;
+template class TC_GAME_API ScriptRegistry<CommandScript>;
+template class TC_GAME_API ScriptRegistry<WeatherScript>;
+template class TC_GAME_API ScriptRegistry<AuctionHouseScript>;
+template class TC_GAME_API ScriptRegistry<ConditionScript>;
+template class TC_GAME_API ScriptRegistry<VehicleScript>;
+template class TC_GAME_API ScriptRegistry<DynamicObjectScript>;
+template class TC_GAME_API ScriptRegistry<TransportScript>;
+template class TC_GAME_API ScriptRegistry<AchievementCriteriaScript>;
+template class TC_GAME_API ScriptRegistry<PlayerScript>;
+template class TC_GAME_API ScriptRegistry<GuildScript>;
+template class TC_GAME_API ScriptRegistry<GroupScript>;
+template class TC_GAME_API ScriptRegistry<UnitScript>;
+template class TC_GAME_API ScriptRegistry<AccountScript>;
// Undefine utility macros.
#undef GET_SCRIPT_RET
diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h
index 8a00305b4da..337e7de4861 100644
--- a/src/server/game/Scripting/ScriptMgr.h
+++ b/src/server/game/Scripting/ScriptMgr.h
@@ -147,7 +147,7 @@ struct OutdoorPvPData;
event on all registered scripts of that type.
*/
-class ScriptObject
+class TC_GAME_API ScriptObject
{
friend class ScriptMgr;
@@ -186,7 +186,7 @@ template<class TObject> class UpdatableScript
virtual void OnUpdate(TObject* /*obj*/, uint32 /*diff*/) { }
};
-class SpellScriptLoader : public ScriptObject
+class TC_GAME_API SpellScriptLoader : public ScriptObject
{
protected:
@@ -201,7 +201,7 @@ class SpellScriptLoader : public ScriptObject
virtual AuraScript* GetAuraScript() const { return NULL; }
};
-class ServerScript : public ScriptObject
+class TC_GAME_API ServerScript : public ScriptObject
{
protected:
@@ -229,13 +229,9 @@ class ServerScript : public ScriptObject
// Called when a (valid) packet is received by a client. The packet object is a copy of the original packet, so
// reading and modifying it is safe. Make sure to check WorldSession pointer before usage, it might be null in case of auth packets
virtual void OnPacketReceive(WorldSession* /*session*/, WorldPacket& /*packet*/) { }
-
- // Called when an invalid (unknown opcode) packet is received by a client. The packet is a reference to the orignal
- // packet; not a copy. This allows you to actually handle unknown packets (for whatever purpose).
- virtual void OnUnknownPacketReceive(WorldSession* /*session*/, WorldPacket& /*packet*/) { }
};
-class WorldScript : public ScriptObject
+class TC_GAME_API WorldScript : public ScriptObject
{
protected:
@@ -268,7 +264,7 @@ class WorldScript : public ScriptObject
virtual void OnShutdown() { }
};
-class FormulaScript : public ScriptObject
+class TC_GAME_API FormulaScript : public ScriptObject
{
protected:
@@ -335,14 +331,14 @@ template<class TMap> class MapScript : public UpdatableScript<TMap>
virtual void OnPlayerLeave(TMap* /*map*/, Player* /*player*/) { }
};
-class WorldMapScript : public ScriptObject, public MapScript<Map>
+class TC_GAME_API WorldMapScript : public ScriptObject, public MapScript<Map>
{
protected:
WorldMapScript(const char* name, uint32 mapId);
};
-class InstanceMapScript : public ScriptObject, public MapScript<InstanceMap>
+class TC_GAME_API InstanceMapScript : public ScriptObject, public MapScript<InstanceMap>
{
protected:
@@ -354,14 +350,14 @@ class InstanceMapScript : public ScriptObject, public MapScript<InstanceMap>
virtual InstanceScript* GetInstanceScript(InstanceMap* /*map*/) const { return NULL; }
};
-class BattlegroundMapScript : public ScriptObject, public MapScript<BattlegroundMap>
+class TC_GAME_API BattlegroundMapScript : public ScriptObject, public MapScript<BattlegroundMap>
{
protected:
BattlegroundMapScript(const char* name, uint32 mapId);
};
-class ItemScript : public ScriptObject
+class TC_GAME_API ItemScript : public ScriptObject
{
protected:
@@ -385,7 +381,7 @@ class ItemScript : public ScriptObject
virtual bool OnRemove(Player* /*player*/, Item* /*item*/) { return false; }
};
-class UnitScript : public ScriptObject
+class TC_GAME_API UnitScript : public ScriptObject
{
protected:
@@ -408,7 +404,7 @@ class UnitScript : public ScriptObject
virtual void ModifySpellDamageTaken(Unit* /*target*/, Unit* /*attacker*/, int32& /*damage*/) { }
};
-class CreatureScript : public UnitScript, public UpdatableScript<Creature>
+class TC_GAME_API CreatureScript : public UnitScript, public UpdatableScript<Creature>
{
protected:
@@ -444,7 +440,7 @@ class CreatureScript : public UnitScript, public UpdatableScript<Creature>
virtual CreatureAI* GetAI(Creature* /*creature*/) const { return NULL; }
};
-class GameObjectScript : public ScriptObject, public UpdatableScript<GameObject>
+class TC_GAME_API GameObjectScript : public ScriptObject, public UpdatableScript<GameObject>
{
protected:
@@ -489,7 +485,7 @@ class GameObjectScript : public ScriptObject, public UpdatableScript<GameObject>
virtual GameObjectAI* GetAI(GameObject* /*go*/) const { return NULL; }
};
-class AreaTriggerScript : public ScriptObject
+class TC_GAME_API AreaTriggerScript : public ScriptObject
{
protected:
@@ -501,7 +497,7 @@ class AreaTriggerScript : public ScriptObject
virtual bool OnTrigger(Player* /*player*/, AreaTriggerEntry const* /*trigger*/) { return false; }
};
-class BattlegroundScript : public ScriptObject
+class TC_GAME_API BattlegroundScript : public ScriptObject
{
protected:
@@ -513,7 +509,7 @@ class BattlegroundScript : public ScriptObject
virtual Battleground* GetBattleground() const = 0;
};
-class OutdoorPvPScript : public ScriptObject
+class TC_GAME_API OutdoorPvPScript : public ScriptObject
{
protected:
@@ -525,7 +521,7 @@ class OutdoorPvPScript : public ScriptObject
virtual OutdoorPvP* GetOutdoorPvP() const = 0;
};
-class CommandScript : public ScriptObject
+class TC_GAME_API CommandScript : public ScriptObject
{
protected:
@@ -537,7 +533,7 @@ class CommandScript : public ScriptObject
virtual std::vector<ChatCommand> GetCommands() const = 0;
};
-class WeatherScript : public ScriptObject, public UpdatableScript<Weather>
+class TC_GAME_API WeatherScript : public ScriptObject, public UpdatableScript<Weather>
{
protected:
@@ -549,7 +545,7 @@ class WeatherScript : public ScriptObject, public UpdatableScript<Weather>
virtual void OnChange(Weather* /*weather*/, WeatherState /*state*/, float /*grade*/) { }
};
-class AuctionHouseScript : public ScriptObject
+class TC_GAME_API AuctionHouseScript : public ScriptObject
{
protected:
@@ -570,7 +566,7 @@ class AuctionHouseScript : public ScriptObject
virtual void OnAuctionExpire(AuctionHouseObject* /*ah*/, AuctionEntry* /*entry*/) { }
};
-class ConditionScript : public ScriptObject
+class TC_GAME_API ConditionScript : public ScriptObject
{
protected:
@@ -582,7 +578,7 @@ class ConditionScript : public ScriptObject
virtual bool OnConditionCheck(Condition const* /*condition*/, ConditionSourceInfo& /*sourceInfo*/) { return true; }
};
-class VehicleScript : public ScriptObject
+class TC_GAME_API VehicleScript : public ScriptObject
{
protected:
@@ -609,14 +605,14 @@ class VehicleScript : public ScriptObject
virtual void OnRemovePassenger(Vehicle* /*veh*/, Unit* /*passenger*/) { }
};
-class DynamicObjectScript : public ScriptObject, public UpdatableScript<DynamicObject>
+class TC_GAME_API DynamicObjectScript : public ScriptObject, public UpdatableScript<DynamicObject>
{
protected:
DynamicObjectScript(const char* name);
};
-class TransportScript : public ScriptObject, public UpdatableScript<Transport>
+class TC_GAME_API TransportScript : public ScriptObject, public UpdatableScript<Transport>
{
protected:
@@ -637,7 +633,7 @@ class TransportScript : public ScriptObject, public UpdatableScript<Transport>
virtual void OnRelocate(Transport* /*transport*/, uint32 /*waypointId*/, uint32 /*mapId*/, float /*x*/, float /*y*/, float /*z*/) { }
};
-class AchievementCriteriaScript : public ScriptObject
+class TC_GAME_API AchievementCriteriaScript : public ScriptObject
{
protected:
@@ -649,7 +645,7 @@ class AchievementCriteriaScript : public ScriptObject
virtual bool OnCheck(Player* source, Unit* target) = 0;
};
-class PlayerScript : public UnitScript
+class TC_GAME_API PlayerScript : public UnitScript
{
protected:
@@ -746,7 +742,7 @@ class PlayerScript : public UnitScript
virtual void OnQuestStatusChange(Player* /*player*/, uint32 /*questId*/, QuestStatus /*status*/) { }
};
-class AccountScript : public ScriptObject
+class TC_GAME_API AccountScript : public ScriptObject
{
protected:
@@ -773,7 +769,7 @@ class AccountScript : public ScriptObject
virtual void OnFailedPasswordChange(uint32 /*accountId*/) {}
};
-class GuildScript : public ScriptObject
+class TC_GAME_API GuildScript : public ScriptObject
{
protected:
@@ -814,7 +810,7 @@ class GuildScript : public ScriptObject
virtual void OnBankEvent(Guild* /*guild*/, uint8 /*eventType*/, uint8 /*tabId*/, ObjectGuid::LowType /*playerGuid*/, uint32 /*itemOrMoney*/, uint16 /*itemStackCount*/, uint8 /*destTabId*/) { }
};
-class GroupScript : public ScriptObject
+class TC_GAME_API GroupScript : public ScriptObject
{
protected:
@@ -844,11 +840,11 @@ class GroupScript : public ScriptObject
// namespace
// {
typedef std::list<std::string> UnusedScriptNamesContainer;
- extern UnusedScriptNamesContainer UnusedScriptNames;
+ TC_GAME_API extern UnusedScriptNamesContainer UnusedScriptNames;
// }
// Manages registration, loading, and execution of scripts.
-class ScriptMgr
+class TC_GAME_API ScriptMgr
{
friend class ScriptObject;
@@ -857,11 +853,7 @@ class ScriptMgr
virtual ~ScriptMgr();
public: /* Initialization */
- static ScriptMgr* instance()
- {
- static ScriptMgr instance;
- return &instance;
- }
+ static ScriptMgr* instance();
void Initialize();
void LoadDatabase();
@@ -872,6 +864,15 @@ class ScriptMgr
void IncrementScriptCount() { ++_scriptCount; }
uint32 GetScriptCount() const { return _scriptCount; }
+ typedef void(*ScriptLoaderCallbackType)();
+
+ /// Sets the script loader callback which is invoked to load scripts
+ /// (Workaround for circular dependency game <-> scripts)
+ void SetScriptLoader(ScriptLoaderCallbackType script_loader_callback)
+ {
+ _script_loader_callback = script_loader_callback;
+ }
+
public: /* Unloading */
void Unload();
@@ -890,7 +891,6 @@ class ScriptMgr
void OnSocketClose(std::shared_ptr<WorldSocket> socket);
void OnPacketReceive(WorldSession* session, WorldPacket const& packet);
void OnPacketSend(WorldSession* session, WorldPacket const& packet);
- void OnUnknownPacketReceive(WorldSession* session, WorldPacket const& packet);
public: /* WorldScript */
@@ -1107,6 +1107,8 @@ class ScriptMgr
//atomic op counter for active scripts amount
std::atomic<uint32> _scheduledScripts;
+
+ ScriptLoaderCallbackType _script_loader_callback;
};
#endif
diff --git a/src/server/game/Scripting/ScriptSystem.cpp b/src/server/game/Scripting/ScriptSystem.cpp
index e828830ec0f..52c5c1640af 100644
--- a/src/server/game/Scripting/ScriptSystem.cpp
+++ b/src/server/game/Scripting/ScriptSystem.cpp
@@ -21,7 +21,13 @@
#include "DatabaseEnv.h"
#include "ScriptMgr.h"
-ScriptPointVector const SystemMgr::_empty;
+TC_GAME_API ScriptPointVector const SystemMgr::_empty;
+
+SystemMgr* SystemMgr::instance()
+{
+ static SystemMgr instance;
+ return &instance;
+}
void SystemMgr::LoadScriptWaypoints()
{
diff --git a/src/server/game/Scripting/ScriptSystem.h b/src/server/game/Scripting/ScriptSystem.h
index 74c51e5b136..7cf8ffc85b0 100644
--- a/src/server/game/Scripting/ScriptSystem.h
+++ b/src/server/game/Scripting/ScriptSystem.h
@@ -45,18 +45,14 @@ struct ScriptPointMove
typedef std::vector<ScriptPointMove> ScriptPointVector;
-class SystemMgr
+class TC_GAME_API SystemMgr
{
private:
SystemMgr() { }
~SystemMgr() { }
public:
- static SystemMgr* instance()
- {
- static SystemMgr instance;
- return &instance;
- }
+ static SystemMgr* instance();
typedef std::unordered_map<uint32, ScriptPointVector> PointMoveMap;
diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h
index 0d30134aa9f..48ed03004ea 100644
--- a/src/server/game/Server/Protocol/Opcodes.h
+++ b/src/server/game/Server/Protocol/Opcodes.h
@@ -1373,7 +1373,7 @@ struct OpcodeHandler
void (WorldSession::*handler)(WorldPacket& recvPacket);
};
-extern OpcodeHandler opcodeTable[NUM_MSG_TYPES];
+TC_GAME_API extern OpcodeHandler opcodeTable[NUM_MSG_TYPES];
#pragma pack(pop)
diff --git a/src/server/game/Server/Protocol/PacketLog.cpp b/src/server/game/Server/Protocol/PacketLog.cpp
index 57b76304a77..11a02828998 100644
--- a/src/server/game/Server/Protocol/PacketLog.cpp
+++ b/src/server/game/Server/Protocol/PacketLog.cpp
@@ -69,6 +69,12 @@ PacketLog::~PacketLog()
_file = NULL;
}
+PacketLog* PacketLog::instance()
+{
+ static PacketLog instance;
+ return &instance;
+}
+
void PacketLog::Initialize()
{
std::string logsDir = sConfigMgr->GetStringDefault("LogsDir", "");
diff --git a/src/server/game/Server/Protocol/PacketLog.h b/src/server/game/Server/Protocol/PacketLog.h
index 45a3f0a4655..5e7661a884b 100644
--- a/src/server/game/Server/Protocol/PacketLog.h
+++ b/src/server/game/Server/Protocol/PacketLog.h
@@ -31,7 +31,7 @@ enum Direction
class WorldPacket;
-class PacketLog
+class TC_GAME_API PacketLog
{
private:
PacketLog();
@@ -40,11 +40,7 @@ class PacketLog
std::once_flag _initializeFlag;
public:
- static PacketLog* instance()
- {
- static PacketLog instance;
- return &instance;
- }
+ static PacketLog* instance();
void Initialize();
bool CanLogPacket() const { return (_file != NULL); }
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index c380c1a5627..ddcc10b53dd 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -187,7 +187,7 @@ ObjectGuid::LowType WorldSession::GetGUIDLow() const
}
/// Send a packet to the client
-void WorldSession::SendPacket(WorldPacket* packet)
+void WorldSession::SendPacket(WorldPacket const* packet)
{
if (!m_Socket)
return;
@@ -272,119 +272,99 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
WorldPacket* packet = NULL;
//! Delete packet after processing by default
bool deletePacket = true;
- //! To prevent infinite loop
- WorldPacket* firstDelayedPacket = NULL;
- //! If _recvQueue.peek() == firstDelayedPacket it means that in this Update call, we've processed all
- //! *properly timed* packets, and we're now at the part of the queue where we find
- //! delayed packets that were re-enqueued due to improper timing. To prevent an infinite
- //! loop caused by re-enqueueing the same packets over and over again, we stop updating this session
- //! and continue updating others. The re-enqueued packets will be handled in the next Update call for this session.
+ std::vector<WorldPacket*> requeuePackets;
uint32 processedPackets = 0;
time_t currentTime = time(NULL);
- while (m_Socket && !_recvQueue.empty() && _recvQueue.peek(true) != firstDelayedPacket && _recvQueue.next(packet, updater))
+ while (m_Socket && _recvQueue.next(packet, updater))
{
- if (packet->GetOpcode() >= NUM_MSG_TYPES)
+ OpcodeHandler const& opHandle = opcodeTable[packet->GetOpcode()];
+ try
{
- TC_LOG_ERROR("network.opcode", "Received non-existed opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode()).c_str()
- , GetPlayerInfo().c_str());
- sScriptMgr->OnUnknownPacketReceive(this, *packet);
- }
- else
- {
- OpcodeHandler& opHandle = opcodeTable[packet->GetOpcode()];
- try
+ switch (opHandle.status)
{
- switch (opHandle.status)
- {
- case STATUS_LOGGEDIN:
- if (!_player)
- {
- // skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets
- //! If player didn't log out a while ago, it means packets are being sent while the server does not recognize
- //! the client to be in world yet. We will re-add the packets to the bottom of the queue and process them later.
- if (!m_playerRecentlyLogout)
- {
- //! Prevent infinite loop
- if (!firstDelayedPacket)
- firstDelayedPacket = packet;
- //! Because checking a bool is faster than reallocating memory
- deletePacket = false;
- QueuePacket(packet);
- //! Log
- TC_LOG_DEBUG("network", "Re-enqueueing packet with opcode %s with with status STATUS_LOGGEDIN. "
- "Player is currently not in world yet.", GetOpcodeNameForLogging(packet->GetOpcode()).c_str());
- }
- }
- else if (_player->IsInWorld() && AntiDOS.EvaluateOpcode(*packet, currentTime))
- {
- sScriptMgr->OnPacketReceive(this, *packet);
- (this->*opHandle.handler)(*packet);
- LogUnprocessedTail(packet);
- }
- // lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer
- break;
- case STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT:
- if (!_player && !m_playerRecentlyLogout && !m_playerLogout) // There's a short delay between _player = null and m_playerRecentlyLogout = true during logout
- LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT",
- "the player has not logged in yet and not recently logout");
- else if (AntiDOS.EvaluateOpcode(*packet, currentTime))
- {
- // not expected _player or must checked in packet handler
- sScriptMgr->OnPacketReceive(this, *packet);
- (this->*opHandle.handler)(*packet);
- LogUnprocessedTail(packet);
- }
- break;
- case STATUS_TRANSFER:
- if (!_player)
- LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player has not logged in yet");
- else if (_player->IsInWorld())
- LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player is still in world");
- else if (AntiDOS.EvaluateOpcode(*packet, currentTime))
- {
- sScriptMgr->OnPacketReceive(this, *packet);
- (this->*opHandle.handler)(*packet);
- LogUnprocessedTail(packet);
- }
- break;
- case STATUS_AUTHED:
- // prevent cheating with skip queue wait
- if (m_inQueue)
+ case STATUS_LOGGEDIN:
+ if (!_player)
+ {
+ // skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets
+ //! If player didn't log out a while ago, it means packets are being sent while the server does not recognize
+ //! the client to be in world yet. We will re-add the packets to the bottom of the queue and process them later.
+ if (!m_playerRecentlyLogout)
{
- LogUnexpectedOpcode(packet, "STATUS_AUTHED", "the player not pass queue yet");
- break;
+ requeuePackets.push_back(packet);
+ deletePacket = false;
+ TC_LOG_DEBUG("network", "Re-enqueueing packet with opcode %s with with status STATUS_LOGGEDIN. "
+ "Player is currently not in world yet.", GetOpcodeNameForLogging(packet->GetOpcode()).c_str());
}
-
- // some auth opcodes can be recieved before STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes
- // however when we recieve CMSG_CHAR_ENUM we are surely no longer during the logout process.
- if (packet->GetOpcode() == CMSG_CHAR_ENUM)
- m_playerRecentlyLogout = false;
-
- if (AntiDOS.EvaluateOpcode(*packet, currentTime))
- {
- sScriptMgr->OnPacketReceive(this, *packet);
- (this->*opHandle.handler)(*packet);
- LogUnprocessedTail(packet);
- }
- break;
- case STATUS_NEVER:
- TC_LOG_ERROR("network.opcode", "Received not allowed opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode()).c_str()
- , GetPlayerInfo().c_str());
- break;
- case STATUS_UNHANDLED:
- TC_LOG_DEBUG("network.opcode", "Received not handled opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode()).c_str()
- , GetPlayerInfo().c_str());
+ }
+ else if (_player->IsInWorld() && AntiDOS.EvaluateOpcode(*packet, currentTime))
+ {
+ sScriptMgr->OnPacketReceive(this, *packet);
+ (this->*opHandle.handler)(*packet);
+ LogUnprocessedTail(packet);
+ }
+ // lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer
+ break;
+ case STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT:
+ if (!_player && !m_playerRecentlyLogout && !m_playerLogout) // There's a short delay between _player = null and m_playerRecentlyLogout = true during logout
+ LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT",
+ "the player has not logged in yet and not recently logout");
+ else if (AntiDOS.EvaluateOpcode(*packet, currentTime))
+ {
+ // not expected _player or must checked in packet hanlder
+ sScriptMgr->OnPacketReceive(this, *packet);
+ (this->*opHandle.handler)(*packet);
+ LogUnprocessedTail(packet);
+ }
+ break;
+ case STATUS_TRANSFER:
+ if (!_player)
+ LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player has not logged in yet");
+ else if (_player->IsInWorld())
+ LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player is still in world");
+ else if (AntiDOS.EvaluateOpcode(*packet, currentTime))
+ {
+ sScriptMgr->OnPacketReceive(this, *packet);
+ (this->*opHandle.handler)(*packet);
+ LogUnprocessedTail(packet);
+ }
+ break;
+ case STATUS_AUTHED:
+ // prevent cheating with skip queue wait
+ if (m_inQueue)
+ {
+ LogUnexpectedOpcode(packet, "STATUS_AUTHED", "the player not pass queue yet");
break;
- }
- }
- catch (ByteBufferException const&)
- {
- TC_LOG_ERROR("misc", "WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i. Skipped packet.",
- packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId());
- packet->hexlike();
+ }
+
+ // some auth opcodes can be recieved before STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes
+ // however when we recieve CMSG_CHAR_ENUM we are surely no longer during the logout process.
+ if (packet->GetOpcode() == CMSG_CHAR_ENUM)
+ m_playerRecentlyLogout = false;
+
+ if (AntiDOS.EvaluateOpcode(*packet, currentTime))
+ {
+ sScriptMgr->OnPacketReceive(this, *packet);
+ (this->*opHandle.handler)(*packet);
+ LogUnprocessedTail(packet);
+ }
+ break;
+ case STATUS_NEVER:
+ TC_LOG_ERROR("network.opcode", "Received not allowed opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode()).c_str()
+ , GetPlayerInfo().c_str());
+ break;
+ case STATUS_UNHANDLED:
+ TC_LOG_DEBUG("network.opcode", "Received not handled opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode()).c_str()
+ , GetPlayerInfo().c_str());
+ break;
}
}
+ catch (ByteBufferException const&)
+ {
+ TC_LOG_ERROR("network", "WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i. Skipped packet.",
+ packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId());
+ packet->hexlike();
+ }
if (deletePacket)
delete packet;
@@ -400,6 +380,8 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
break;
}
+ _recvQueue.readd(requeuePackets.begin(), requeuePackets.end());
+
if (m_Socket && m_Socket->IsOpen() && _warden)
_warden->Update();
@@ -1220,7 +1202,7 @@ void WorldSession::LoadPermissions()
uint32 id = GetAccountId();
uint8 secLevel = GetSecurity();
- _RBACData = new rbac::RBACData(id, _accountName, realmID, secLevel);
+ _RBACData = new rbac::RBACData(id, _accountName, realm.Id.Realm, secLevel);
_RBACData->LoadFromDB();
}
@@ -1230,9 +1212,9 @@ PreparedQueryResultFuture WorldSession::LoadPermissionsAsync()
uint8 secLevel = GetSecurity();
TC_LOG_DEBUG("rbac", "WorldSession::LoadPermissions [AccountId: %u, Name: %s, realmId: %d, secLevel: %u]",
- id, _accountName.c_str(), realmID, secLevel);
+ id, _accountName.c_str(), realm.Id.Realm, secLevel);
- _RBACData = new rbac::RBACData(id, _accountName, realmID, secLevel);
+ _RBACData = new rbac::RBACData(id, _accountName, realm.Id.Realm, secLevel);
return _RBACData->LoadFromDBAsync();
}
@@ -1310,7 +1292,7 @@ bool WorldSession::HasPermission(uint32 permission)
bool hasPermission = _RBACData->HasPermission(permission);
TC_LOG_DEBUG("rbac", "WorldSession::HasPermission [AccountId: %u, Name: %s, realmId: %d]",
- _RBACData->GetId(), _RBACData->GetName().c_str(), realmID);
+ _RBACData->GetId(), _RBACData->GetName().c_str(), realm.Id.Realm);
return hasPermission;
}
@@ -1318,7 +1300,7 @@ bool WorldSession::HasPermission(uint32 permission)
void WorldSession::InvalidateRBACData()
{
TC_LOG_DEBUG("rbac", "WorldSession::Invalidaterbac::RBACData [AccountId: %u, Name: %s, realmId: %d]",
- _RBACData->GetId(), _RBACData->GetName().c_str(), realmID);
+ _RBACData->GetId(), _RBACData->GetName().c_str(), realm.Id.Realm);
delete _RBACData;
_RBACData = NULL;
}
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 2253b6bc684..584367bd375 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -246,7 +246,7 @@ struct PacketCounter
};
/// Player session in the World
-class WorldSession
+class TC_GAME_API WorldSession
{
public:
WorldSession(uint32 id, std::string&& name, std::shared_ptr<WorldSocket> sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale, uint32 recruiter, bool isARecruiter);
@@ -264,7 +264,7 @@ class WorldSession
void ReadMovementInfo(WorldPacket& data, MovementInfo* mi);
void WriteMovementInfo(WorldPacket* data, MovementInfo* mi);
- void SendPacket(WorldPacket* packet);
+ void SendPacket(WorldPacket const* packet);
void SendNotification(const char *format, ...) ATTR_PRINTF(2, 3);
void SendNotification(uint32 string_id, ...);
void SendPetNameInvalid(uint32 error, std::string const& name, DeclinedName *declinedName);
diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp
index a2d357cbc4d..e3c6179a34a 100644
--- a/src/server/game/Server/WorldSocket.cpp
+++ b/src/server/game/Server/WorldSocket.cpp
@@ -25,6 +25,17 @@
#include <memory>
+class EncryptablePacket : public WorldPacket
+{
+public:
+ EncryptablePacket(WorldPacket const& packet, bool encrypt) : WorldPacket(packet), _encrypt(encrypt) { }
+
+ bool NeedsEncryption() const { return _encrypt; }
+
+private:
+ bool _encrypt;
+};
+
using boost::asio::ip::tcp;
WorldSocket::WorldSocket(tcp::socket&& socket)
@@ -40,11 +51,8 @@ void WorldSocket::Start()
stmt->setString(0, ip_address);
stmt->setUInt32(1, inet_addr(ip_address.c_str()));
- {
- std::lock_guard<std::mutex> guard(_queryLock);
- _queryCallback = io_service().wrap(std::bind(&WorldSocket::CheckIpCallback, this, std::placeholders::_1));
- _queryFuture = LoginDatabase.AsyncQuery(stmt);
- }
+ _queryCallback = std::bind(&WorldSocket::CheckIpCallback, this, std::placeholders::_1);
+ _queryFuture = LoginDatabase.AsyncQuery(stmt);
}
void WorldSocket::CheckIpCallback(PreparedQueryResult result)
@@ -78,17 +86,50 @@ void WorldSocket::CheckIpCallback(PreparedQueryResult result)
bool WorldSocket::Update()
{
+ EncryptablePacket* queued;
+ MessageBuffer buffer;
+ while (_bufferQueue.Dequeue(queued))
+ {
+ ServerPktHeader header(queued->size() + 2, queued->GetOpcode());
+ if (queued->NeedsEncryption())
+ _authCrypt.EncryptSend(header.header, header.getHeaderLength());
+
+ if (buffer.GetRemainingSpace() < queued->size() + header.getHeaderLength())
+ {
+ QueuePacket(std::move(buffer));
+ buffer.Resize(4096);
+ }
+
+ if (buffer.GetRemainingSpace() >= queued->size() + header.getHeaderLength())
+ {
+ buffer.Write(header.header, header.getHeaderLength());
+ if (!queued->empty())
+ buffer.Write(queued->contents(), queued->size());
+ }
+ else // single packet larger than 4096 bytes
+ {
+ MessageBuffer packetBuffer(queued->size() + header.getHeaderLength());
+ packetBuffer.Write(header.header, header.getHeaderLength());
+ if (!queued->empty())
+ packetBuffer.Write(queued->contents(), queued->size());
+
+ QueuePacket(std::move(packetBuffer));
+ }
+
+ delete queued;
+ }
+
+ if (buffer.GetActiveSize() > 0)
+ QueuePacket(std::move(buffer));
+
if (!BaseSocket::Update())
return false;
+ if (_queryFuture.valid() && _queryFuture.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
{
- std::lock_guard<std::mutex> guard(_queryLock);
- if (_queryFuture.valid() && _queryFuture.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
- {
- auto callback = std::move(_queryCallback);
- _queryCallback = nullptr;
- callback(_queryFuture.get());
- }
+ auto callback = _queryCallback;
+ _queryCallback = nullptr;
+ callback(_queryFuture.get());
}
return true;
@@ -351,29 +392,7 @@ void WorldSocket::SendPacket(WorldPacket const& packet)
if (sPacketLog->CanLogPacket())
sPacketLog->LogPacket(packet, SERVER_TO_CLIENT, GetRemoteIpAddress(), GetRemotePort());
- ServerPktHeader header(packet.size() + 2, packet.GetOpcode());
-
- std::unique_lock<std::mutex> guard(_writeLock);
-
- _authCrypt.EncryptSend(header.header, header.getHeaderLength());
-
-#ifndef TC_SOCKET_USE_IOCP
- if (_writeQueue.empty() && _writeBuffer.GetRemainingSpace() >= header.getHeaderLength() + packet.size())
- {
- _writeBuffer.Write(header.header, header.getHeaderLength());
- if (!packet.empty())
- _writeBuffer.Write(packet.contents(), packet.size());
- }
- else
-#endif
- {
- MessageBuffer buffer(header.getHeaderLength() + packet.size());
- buffer.Write(header.header, header.getHeaderLength());
- if (!packet.empty())
- buffer.Write(packet.contents(), packet.size());
-
- QueuePacket(std::move(buffer), guard);
- }
+ _bufferQueue.Enqueue(new EncryptablePacket(packet, _authCrypt.IsInitialized()));
}
void WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
@@ -395,14 +414,11 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
// Get the account information from the auth database
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME);
- stmt->setInt32(0, int32(realmID));
+ stmt->setInt32(0, int32(realm.Id.Realm));
stmt->setString(1, authSession->Account);
- {
- std::lock_guard<std::mutex> guard(_queryLock);
- _queryCallback = io_service().wrap(std::bind(&WorldSocket::HandleAuthSessionCallback, this, authSession, std::placeholders::_1));
- _queryFuture = LoginDatabase.AsyncQuery(stmt);
- }
+ _queryCallback = std::bind(&WorldSocket::HandleAuthSessionCallback, this, authSession, std::placeholders::_1);
+ _queryFuture = LoginDatabase.AsyncQuery(stmt);
}
void WorldSocket::HandleAuthSessionCallback(std::shared_ptr<AuthSession> authSession, PreparedQueryResult result)
@@ -441,10 +457,11 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptr<AuthSession> authSes
return;
}
- if (authSession->RealmID != realmID)
+ if (authSession->RealmID != realm.Id.Realm)
{
SendAuthResponseError(REALM_LIST_REALM_NOT_FOUND);
- TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Sent Auth Response (bad realm).");
+ TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Client %s requested connecting with realm id %u but this realm has id %u set in config.",
+ GetRemoteIpAddress().to_string().c_str(), authSession->RealmID, realm.Id.Realm);
DelayedCloseSocket();
return;
}
@@ -559,7 +576,7 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptr<AuthSession> authSes
if (wardenActive)
_worldSession->InitWarden(&account.SessionKey, account.OS);
- _queryCallback = io_service().wrap(std::bind(&WorldSocket::LoadSessionPermissionsCallback, this, std::placeholders::_1));
+ _queryCallback = std::bind(&WorldSocket::LoadSessionPermissionsCallback, this, std::placeholders::_1);
_queryFuture = _worldSession->LoadPermissionsAsync();
AsyncRead();
}
diff --git a/src/server/game/Server/WorldSocket.h b/src/server/game/Server/WorldSocket.h
index 9e5b35992a6..3874b60b0bb 100644
--- a/src/server/game/Server/WorldSocket.h
+++ b/src/server/game/Server/WorldSocket.h
@@ -26,11 +26,12 @@
#include "Util.h"
#include "WorldPacket.h"
#include "WorldSession.h"
+#include "MPSCQueue.h"
#include <chrono>
#include <boost/asio/ip/tcp.hpp>
-#include <boost/asio/buffer.hpp>
using boost::asio::ip::tcp;
+class EncryptablePacket;
#pragma pack(push, 1)
@@ -47,7 +48,7 @@ struct ClientPktHeader
struct AuthSession;
-class WorldSocket : public Socket<WorldSocket>
+class TC_GAME_API WorldSocket : public Socket<WorldSocket>
{
typedef Socket<WorldSocket> BaseSocket;
@@ -104,8 +105,8 @@ private:
MessageBuffer _headerBuffer;
MessageBuffer _packetBuffer;
+ MPSCQueue<EncryptablePacket> _bufferQueue;
- std::mutex _queryLock;
PreparedQueryResultFuture _queryFuture;
std::function<void(PreparedQueryResult&&)> _queryCallback;
std::string _ipCountry;
diff --git a/src/server/game/Server/WorldSocketMgr.cpp b/src/server/game/Server/WorldSocketMgr.cpp
index 529396b3966..cbdb6a4a70b 100644
--- a/src/server/game/Server/WorldSocketMgr.cpp
+++ b/src/server/game/Server/WorldSocketMgr.cpp
@@ -24,9 +24,9 @@
#include <boost/system/error_code.hpp>
-static void OnSocketAccept(tcp::socket&& sock)
+static void OnSocketAccept(tcp::socket&& sock, uint32 threadIndex)
{
- sWorldSocketMgr.OnSocketOpen(std::forward<tcp::socket>(sock));
+ sWorldSocketMgr.OnSocketOpen(std::forward<tcp::socket>(sock), threadIndex);
}
class WorldSocketThread : public NetworkThread<WorldSocket>
@@ -47,6 +47,12 @@ WorldSocketMgr::WorldSocketMgr() : BaseSocketMgr(), _socketSendBufferSize(-1), m
{
}
+WorldSocketMgr& WorldSocketMgr::Instance()
+{
+ static WorldSocketMgr instance;
+ return instance;
+}
+
bool WorldSocketMgr::StartNetwork(boost::asio::io_service& service, std::string const& bindIp, uint16 port)
{
_tcpNoDelay = sConfigMgr->GetBoolDefault("Network.TcpNodelay", true);
@@ -67,7 +73,9 @@ bool WorldSocketMgr::StartNetwork(boost::asio::io_service& service, std::string
BaseSocketMgr::StartNetwork(service, bindIp, port);
- _acceptor->AsyncAcceptManaged(&OnSocketAccept);
+ _acceptor->SetSocketFactory(std::bind(&BaseSocketMgr::GetSocketForAccept, this));
+
+ _acceptor->AsyncAcceptWithCallback<&OnSocketAccept>();
sScriptMgr->OnNetworkStart();
return true;
@@ -80,7 +88,7 @@ void WorldSocketMgr::StopNetwork()
sScriptMgr->OnNetworkStop();
}
-void WorldSocketMgr::OnSocketOpen(tcp::socket&& sock)
+void WorldSocketMgr::OnSocketOpen(tcp::socket&& sock, uint32 threadIndex)
{
// set some options here
if (_socketSendBufferSize >= 0)
@@ -108,7 +116,7 @@ void WorldSocketMgr::OnSocketOpen(tcp::socket&& sock)
//sock->m_OutBufferSize = static_cast<size_t> (m_SockOutUBuff);
- BaseSocketMgr::OnSocketOpen(std::forward<tcp::socket>(sock));
+ BaseSocketMgr::OnSocketOpen(std::forward<tcp::socket>(sock), threadIndex);
}
NetworkThread<WorldSocket>* WorldSocketMgr::CreateThreads() const
diff --git a/src/server/game/Server/WorldSocketMgr.h b/src/server/game/Server/WorldSocketMgr.h
index 92a28d0c135..0dcc30e8f70 100644
--- a/src/server/game/Server/WorldSocketMgr.h
+++ b/src/server/game/Server/WorldSocketMgr.h
@@ -30,16 +30,12 @@
class WorldSocket;
/// Manages all sockets connected to peers and network threads
-class WorldSocketMgr : public SocketMgr<WorldSocket>
+class TC_GAME_API WorldSocketMgr : public SocketMgr<WorldSocket>
{
typedef SocketMgr<WorldSocket> BaseSocketMgr;
public:
- static WorldSocketMgr& Instance()
- {
- static WorldSocketMgr instance;
- return instance;
- }
+ static WorldSocketMgr& Instance();
/// Start network, listen at address:port .
bool StartNetwork(boost::asio::io_service& service, std::string const& bindIp, uint16 port) override;
@@ -47,7 +43,7 @@ public:
/// Stops all network threads, It will wait for all running threads .
void StopNetwork() override;
- void OnSocketOpen(tcp::socket&& sock) override;
+ void OnSocketOpen(tcp::socket&& sock, uint32 threadIndex) override;
protected:
WorldSocketMgr();
diff --git a/src/server/game/Skills/SkillDiscovery.cpp b/src/server/game/Skills/SkillDiscovery.cpp
index 36a7d147192..8860b391f48 100644
--- a/src/server/game/Skills/SkillDiscovery.cpp
+++ b/src/server/game/Skills/SkillDiscovery.cpp
@@ -88,7 +88,7 @@ void LoadSkillDiscoveryTable()
{
if (reportedReqSpells.find(absReqSkillOrSpell) == reportedReqSpells.end())
{
- TC_LOG_ERROR("sql.sql", "Spell (ID: %u) have not existed spell (ID: %i) in `reqSpell` field in `skill_discovery_template` table", spellId, reqSkillOrSpell);
+ TC_LOG_ERROR("sql.sql", "Spell (ID: %u) has a non-existing spell (ID: %i) in `reqSpell` field in the `skill_discovery_template` table.", spellId, reqSkillOrSpell);
reportedReqSpells.insert(absReqSkillOrSpell);
}
continue;
@@ -101,8 +101,8 @@ void LoadSkillDiscoveryTable()
{
if (reportedReqSpells.find(absReqSkillOrSpell) == reportedReqSpells.end())
{
- TC_LOG_ERROR("sql.sql", "Spell (ID: %u) not have MECHANIC_DISCOVERY (28) value in Mechanic field in spell.dbc"
- " and not 100%% chance random discovery ability but listed for spellId %u (and maybe more) in `skill_discovery_template` table",
+ TC_LOG_ERROR("sql.sql", "Spell (ID: %u) does not have any MECHANIC_DISCOVERY (28) value in the Mechanic field in spell.dbc"
+ " nor 100%% chance random discovery ability, but is listed for spellId %u (and maybe more) in the `skill_discovery_template` table.",
absReqSkillOrSpell, spellId);
reportedReqSpells.insert(absReqSkillOrSpell);
}
@@ -117,7 +117,7 @@ void LoadSkillDiscoveryTable()
if (bounds.first == bounds.second)
{
- TC_LOG_ERROR("sql.sql", "Spell (ID: %u) not listed in `SkillLineAbility.dbc` but listed with `reqSpell`=0 in `skill_discovery_template` table", spellId);
+ TC_LOG_ERROR("sql.sql", "Spell (ID: %u) is not listed in `SkillLineAbility.dbc`, but listed with `reqSpell`= 0 in the `skill_discovery_template` table.", spellId);
continue;
}
@@ -126,7 +126,7 @@ void LoadSkillDiscoveryTable()
}
else
{
- TC_LOG_ERROR("sql.sql", "Spell (ID: %u) have negative value in `reqSpell` field in `skill_discovery_template` table", spellId);
+ TC_LOG_ERROR("sql.sql", "Spell (ID: %u) has a negative value in `reqSpell` field in the `skill_discovery_template` table.", spellId);
continue;
}
@@ -135,7 +135,7 @@ void LoadSkillDiscoveryTable()
while (result->NextRow());
if (!ssNonDiscoverableEntries.str().empty())
- TC_LOG_ERROR("sql.sql", "Some items can't be successfully discovered: have in chance field value < 0.000001 in `skill_discovery_template` DB table . List:\n%s", ssNonDiscoverableEntries.str().c_str());
+ TC_LOG_ERROR("sql.sql", "Some items can't be successfully discovered, their chance field value is < 0.000001 in the `skill_discovery_template` DB table. List:\n%s", ssNonDiscoverableEntries.str().c_str());
// report about empty data for explicit discovery spells
for (uint32 spell_id = 1; spell_id < sSpellMgr->GetSpellInfoStoreSize(); ++spell_id)
@@ -149,10 +149,10 @@ void LoadSkillDiscoveryTable()
continue;
if (SkillDiscoveryStore.find(int32(spell_id)) == SkillDiscoveryStore.end())
- TC_LOG_ERROR("sql.sql", "Spell (ID: %u) is 100%% chance random discovery ability but not have data in `skill_discovery_template` table", spell_id);
+ TC_LOG_ERROR("sql.sql", "Spell (ID: %u) has got 100%% chance random discovery ability, but does not have data in the `skill_discovery_template` table.", spell_id);
}
- TC_LOG_INFO("server.loading", ">> Loaded %u skill discovery definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u skill discovery definitions in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
uint32 GetExplicitDiscoverySpell(uint32 spellId, Player* player)
diff --git a/src/server/game/Skills/SkillDiscovery.h b/src/server/game/Skills/SkillDiscovery.h
index b7fe1cdc8b2..c2020e5b075 100644
--- a/src/server/game/Skills/SkillDiscovery.h
+++ b/src/server/game/Skills/SkillDiscovery.h
@@ -23,8 +23,9 @@
class Player;
-void LoadSkillDiscoveryTable();
-uint32 GetSkillDiscoverySpell(uint32 skillId, uint32 spellId, Player* player);
-bool HasDiscoveredAllSpells(uint32 spellId, Player* player);
-uint32 GetExplicitDiscoverySpell(uint32 spellId, Player* player);
+TC_GAME_API void LoadSkillDiscoveryTable();
+TC_GAME_API uint32 GetSkillDiscoverySpell(uint32 skillId, uint32 spellId, Player* player);
+TC_GAME_API bool HasDiscoveredAllSpells(uint32 spellId, Player* player);
+TC_GAME_API uint32 GetExplicitDiscoverySpell(uint32 spellId, Player* player);
+
#endif
diff --git a/src/server/game/Skills/SkillExtraItems.cpp b/src/server/game/Skills/SkillExtraItems.cpp
index 5213944cc90..f76e4623137 100644
--- a/src/server/game/Skills/SkillExtraItems.cpp
+++ b/src/server/game/Skills/SkillExtraItems.cpp
@@ -74,28 +74,28 @@ void LoadSkillPerfectItemTable()
if (!sSpellMgr->GetSpellInfo(spellId))
{
- TC_LOG_ERROR("sql.sql", "Skill perfection data for spell %u has non-existent spell id in `skill_perfect_item_template`!", spellId);
+ TC_LOG_ERROR("sql.sql", "Skill perfection data for spell %u has a non-existing spell id in the `skill_perfect_item_template`!", spellId);
continue;
}
uint32 requiredSpecialization = fields[1].GetUInt32();
if (!sSpellMgr->GetSpellInfo(requiredSpecialization))
{
- TC_LOG_ERROR("sql.sql", "Skill perfection data for spell %u has non-existent required specialization spell id %u in `skill_perfect_item_template`!", spellId, requiredSpecialization);
+ TC_LOG_ERROR("sql.sql", "Skill perfection data for spell %u has a non-existing required specialization spell id %u in the `skill_perfect_item_template`!", spellId, requiredSpecialization);
continue;
}
float perfectCreateChance = fields[2].GetFloat();
if (perfectCreateChance <= 0.0f)
{
- TC_LOG_ERROR("sql.sql", "Skill perfection data for spell %u has impossibly low proc chance in `skill_perfect_item_template`!", spellId);
+ TC_LOG_ERROR("sql.sql", "Skill perfection data for spell %u has impossibly low proc chance in the `skill_perfect_item_template`!", spellId);
continue;
}
uint32 perfectItemType = fields[3].GetUInt32();
if (!sObjectMgr->GetItemTemplate(perfectItemType))
{
- TC_LOG_ERROR("sql.sql", "Skill perfection data for spell %u references non-existent perfect item id %u in `skill_perfect_item_template`!", spellId, perfectItemType);
+ TC_LOG_ERROR("sql.sql", "Skill perfection data for spell %u references a non-existing perfect item id %u in the `skill_perfect_item_template`!", spellId, perfectItemType);
continue;
}
@@ -109,7 +109,7 @@ void LoadSkillPerfectItemTable()
}
while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u spell perfection definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u spell perfection definitions in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
// struct to store information about extra item creation
@@ -161,28 +161,28 @@ void LoadSkillExtraItemTable()
if (!sSpellMgr->GetSpellInfo(spellId))
{
- TC_LOG_ERROR("sql.sql", "Skill specialization %u has non-existent spell id in `skill_extra_item_template`!", spellId);
+ TC_LOG_ERROR("sql.sql", "Skill specialization %u has a non-existing spell id in the `skill_extra_item_template`!", spellId);
continue;
}
uint32 requiredSpecialization = fields[1].GetUInt32();
if (!sSpellMgr->GetSpellInfo(requiredSpecialization))
{
- TC_LOG_ERROR("sql.sql", "Skill specialization %u have not existed required specialization spell id %u in `skill_extra_item_template`!", spellId, requiredSpecialization);
+ TC_LOG_ERROR("sql.sql", "Skill specialization %u has a non-existing required specialization spell id %u in the `skill_extra_item_template`!", spellId, requiredSpecialization);
continue;
}
float additionalCreateChance = fields[2].GetFloat();
if (additionalCreateChance <= 0.0f)
{
- TC_LOG_ERROR("sql.sql", "Skill specialization %u has too low additional create chance in `skill_extra_item_template`!", spellId);
+ TC_LOG_ERROR("sql.sql", "Skill specialization %u has too low additional create chance in the `skill_extra_item_template`!", spellId);
continue;
}
uint8 additionalMaxNum = fields[3].GetUInt8();
if (!additionalMaxNum)
{
- TC_LOG_ERROR("sql.sql", "Skill specialization %u has 0 max number of extra items in `skill_extra_item_template`!", spellId);
+ TC_LOG_ERROR("sql.sql", "Skill specialization %u has 0 max number of extra items in the `skill_extra_item_template`!", spellId);
continue;
}
diff --git a/src/server/game/Skills/SkillExtraItems.h b/src/server/game/Skills/SkillExtraItems.h
index 2889b221600..5a477b65f0b 100644
--- a/src/server/game/Skills/SkillExtraItems.h
+++ b/src/server/game/Skills/SkillExtraItems.h
@@ -23,12 +23,14 @@
// predef classes used in functions
class Player;
+
// returns true and sets the appropriate info if the player can create a perfect item with the given spellId
-bool CanCreatePerfectItem(Player* player, uint32 spellId, float &perfectCreateChance, uint32 &perfectItemType);
+TC_GAME_API bool CanCreatePerfectItem(Player* player, uint32 spellId, float &perfectCreateChance, uint32 &perfectItemType);
// load perfection proc info from DB
-void LoadSkillPerfectItemTable();
+TC_GAME_API void LoadSkillPerfectItemTable();
// returns true and sets the appropriate info if the player can create extra items with the given spellId
-bool CanCreateExtraItems(Player* player, uint32 spellId, float &additionalChance, uint8 &additionalMax);
+TC_GAME_API bool CanCreateExtraItems(Player* player, uint32 spellId, float &additionalChance, uint8 &additionalMax);
// function to load the extra item creation info from DB
-void LoadSkillExtraItemTable();
+TC_GAME_API void LoadSkillExtraItemTable();
+
#endif
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h
index b400520a08a..32a7b97fff2 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.h
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.h
@@ -27,7 +27,7 @@ class Aura;
typedef void(AuraEffect::*pAuraEffectHandler)(AuraApplication const* aurApp, uint8 mode, bool apply) const;
-class AuraEffect
+class TC_GAME_API AuraEffect
{
friend void Aura::_InitEffects(uint8 effMask, Unit* caster, int32 *baseAmount);
friend Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8 effMask, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID);
diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h
index 2180f524194..750110dc146 100644
--- a/src/server/game/Spells/Auras/SpellAuras.h
+++ b/src/server/game/Spells/Auras/SpellAuras.h
@@ -39,7 +39,7 @@ class ChargeDropEvent;
// update aura target map every 500 ms instead of every update - reduce amount of grid searcher calls
#define UPDATE_TARGET_MAP_INTERVAL 500
-class AuraApplication
+class TC_GAME_API AuraApplication
{
friend void Unit::_ApplyAura(AuraApplication * aurApp, uint8 effMask);
friend void Unit::_UnapplyAura(AuraApplicationMap::iterator &i, AuraRemoveMode removeMode);
@@ -82,7 +82,7 @@ class AuraApplication
void ClientUpdate(bool remove = false);
};
-class Aura
+class TC_GAME_API Aura
{
friend Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8 effMask, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
public:
@@ -273,7 +273,7 @@ class Aura
Unit::AuraApplicationList m_removedApplications;
};
-class UnitAura : public Aura
+class TC_GAME_API UnitAura : public Aura
{
friend Aura* Aura::Create(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
protected:
@@ -294,7 +294,7 @@ class UnitAura : public Aura
DiminishingGroup m_AuraDRGroup:8; // Diminishing
};
-class DynObjAura : public Aura
+class TC_GAME_API DynObjAura : public Aura
{
friend Aura* Aura::Create(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
protected:
@@ -305,12 +305,12 @@ class DynObjAura : public Aura
void FillTargetMap(std::map<Unit*, uint8> & targets, Unit* caster) override;
};
-class ChargeDropEvent : public BasicEvent
+class TC_GAME_API ChargeDropEvent : public BasicEvent
{
friend class Aura;
protected:
ChargeDropEvent(Aura* base, AuraRemoveMode mode) : _base(base), _mode(mode) { }
- bool Execute(uint64 /*e_time*/, uint32 /*p_time*/);
+ bool Execute(uint64 /*e_time*/, uint32 /*p_time*/) override;
private:
Aura* _base;
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 23e2f144ff2..b2fb2766fb0 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -602,7 +602,7 @@ m_caster((info->HasAttribute(SPELL_ATTR6_CAST_BY_CHARMER) && caster->GetCharmerO
//Auto Shot & Shoot (wand)
m_autoRepeat = m_spellInfo->IsAutoRepeatRangedSpell();
-
+
m_isDelayedInstantCast = false;
m_runesState = 0;
@@ -3811,7 +3811,7 @@ void Spell::SendSpellStart()
if ((IsTriggered() && !m_spellInfo->IsAutoRepeatRangedSpell()) || m_triggeredByAuraSpell)
castFlags |= CAST_FLAG_PENDING;
- if (m_spellInfo->HasAttribute(SPELL_ATTR0_REQ_AMMO))
+ if (m_spellInfo->HasAttribute(SPELL_ATTR0_REQ_AMMO) || m_spellInfo->HasAttribute(SPELL_ATTR0_CU_NEEDS_AMMO_DATA))
castFlags |= CAST_FLAG_AMMO;
if ((m_caster->GetTypeId() == TYPEID_PLAYER ||
(m_caster->GetTypeId() == TYPEID_UNIT && m_caster->IsPet()))
@@ -3864,7 +3864,7 @@ void Spell::SendSpellGo()
if ((IsTriggered() && !m_spellInfo->IsAutoRepeatRangedSpell()) || m_triggeredByAuraSpell)
castFlags |= CAST_FLAG_PENDING;
- if (m_spellInfo->HasAttribute(SPELL_ATTR0_REQ_AMMO))
+ if (m_spellInfo->HasAttribute(SPELL_ATTR0_REQ_AMMO) || m_spellInfo->HasAttribute(SPELL_ATTR0_CU_NEEDS_AMMO_DATA))
castFlags |= CAST_FLAG_AMMO; // arrows/bullets visual
if ((m_caster->GetTypeId() == TYPEID_PLAYER ||
@@ -5702,27 +5702,37 @@ bool Spell::CanAutoCast(Unit* target)
{
ObjectGuid targetguid = target->GetGUID();
- for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
+ // check if target already has the same or a more powerful aura
+ for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
- if (m_spellInfo->Effects[j].Effect == SPELL_EFFECT_APPLY_AURA)
+ if (!GetSpellInfo()->Effects[i].IsAura())
+ continue;
+
+ AuraType const& auraType = AuraType(GetSpellInfo()->Effects[i].ApplyAuraName);
+ Unit::AuraEffectList const& auras = target->GetAuraEffectsByType(auraType);
+ for (Unit::AuraEffectList::const_iterator auraIt = auras.begin(); auraIt != auras.end(); ++auraIt)
{
- if (m_spellInfo->StackAmount <= 1)
+ if (GetSpellInfo()->Id == (*auraIt)->GetSpellInfo()->Id)
+ return false;
+
+ switch (sSpellMgr->CheckSpellGroupStackRules(GetSpellInfo(), (*auraIt)->GetSpellInfo()))
{
- if (target->HasAuraEffect(m_spellInfo->Id, j))
+ case SPELL_GROUP_STACK_RULE_EXCLUSIVE:
return false;
- }
- else
- {
- if (AuraEffect* aureff = target->GetAuraEffect(m_spellInfo->Id, j))
- if (aureff->GetBase()->GetStackAmount() >= m_spellInfo->StackAmount)
+ case SPELL_GROUP_STACK_RULE_EXCLUSIVE_FROM_SAME_CASTER:
+ if (GetCaster() == (*auraIt)->GetCaster())
+ return false;
+ break;
+ case SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT: // this one has further checks, but i don't think they're necessary for autocast logic
+ case SPELL_GROUP_STACK_RULE_EXCLUSIVE_HIGHEST:
+ if (abs(GetSpellInfo()->Effects[i].BasePoints) <= abs((*auraIt)->GetAmount()))
return false;
+ break;
+ case SPELL_GROUP_STACK_RULE_DEFAULT:
+ default:
+ break;
}
}
- else if (m_spellInfo->Effects[j].IsAreaAuraEffect())
- {
- if (target->HasAuraEffect(m_spellInfo->Id, j))
- return false;
- }
}
SpellCastResult result = CheckPetCast(target);
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index 696d2801645..e634aa62a1c 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -80,7 +80,7 @@ enum SpellRangeFlag
SPELL_RANGE_RANGED = 2 //hunter range and ranged weapon
};
-struct SpellDestination
+struct TC_GAME_API SpellDestination
{
SpellDestination();
SpellDestination(float x, float y, float z, float orientation = 0.0f, uint32 mapId = MAPID_INVALID);
@@ -95,7 +95,7 @@ struct SpellDestination
Position _transportOffset;
};
-class SpellCastTargets
+class TC_GAME_API SpellCastTargets
{
public:
SpellCastTargets();
@@ -218,7 +218,7 @@ enum SpellEffectHandleMode
typedef std::list<std::pair<uint32, ObjectGuid>> DispelList;
-class Spell
+class TC_GAME_API Spell
{
friend void Unit::SetCurrentCastSpell(Spell* pSpell);
friend class SpellScript;
@@ -708,7 +708,7 @@ class Spell
namespace Trinity
{
- struct WorldObjectSpellTargetCheck
+ struct TC_GAME_API WorldObjectSpellTargetCheck
{
Unit* _caster;
Unit* _referer;
@@ -723,7 +723,7 @@ namespace Trinity
bool operator()(WorldObject* target);
};
- struct WorldObjectSpellNearbyTargetCheck : public WorldObjectSpellTargetCheck
+ struct TC_GAME_API WorldObjectSpellNearbyTargetCheck : public WorldObjectSpellTargetCheck
{
float _range;
Position const* _position;
@@ -732,7 +732,7 @@ namespace Trinity
bool operator()(WorldObject* target);
};
- struct WorldObjectSpellAreaTargetCheck : public WorldObjectSpellTargetCheck
+ struct TC_GAME_API WorldObjectSpellAreaTargetCheck : public WorldObjectSpellTargetCheck
{
float _range;
Position const* _position;
@@ -741,7 +741,7 @@ namespace Trinity
bool operator()(WorldObject* target);
};
- struct WorldObjectSpellConeTargetCheck : public WorldObjectSpellAreaTargetCheck
+ struct TC_GAME_API WorldObjectSpellConeTargetCheck : public WorldObjectSpellAreaTargetCheck
{
float _coneAngle;
WorldObjectSpellConeTargetCheck(float coneAngle, float range, Unit* caster,
@@ -749,7 +749,7 @@ namespace Trinity
bool operator()(WorldObject* target);
};
- struct WorldObjectSpellTrajTargetCheck : public WorldObjectSpellAreaTargetCheck
+ struct TC_GAME_API WorldObjectSpellTrajTargetCheck : public WorldObjectSpellAreaTargetCheck
{
WorldObjectSpellTrajTargetCheck(float range, Position const* position, Unit* caster, SpellInfo const* spellInfo);
bool operator()(WorldObject* target);
@@ -758,7 +758,7 @@ namespace Trinity
typedef void(Spell::*pEffect)(SpellEffIndex effIndex);
-class SpellEvent : public BasicEvent
+class TC_GAME_API SpellEvent : public BasicEvent
{
public:
SpellEvent(Spell* spell);
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 9535ca291eb..2a9db6f0449 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -250,13 +250,13 @@ void Spell::EffectResurrectNew(SpellEffIndex effIndex)
Player* target = unitTarget->ToPlayer();
- if (target->isResurrectRequested()) // already have one active request
+ if (target->IsResurrectRequested()) // already have one active request
return;
uint32 health = damage;
uint32 mana = m_spellInfo->Effects[effIndex].MiscValue;
ExecuteLogEffectResurrect(effIndex, target);
- target->setResurrectRequestData(m_caster->GetGUID(), m_caster->GetMapId(), m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ(), health, mana);
+ target->SetResurrectRequestData(m_caster, health, mana, 0);
SendResurrectRequest(target);
}
@@ -893,7 +893,7 @@ void Spell::EffectTriggerMissileSpell(SpellEffIndex effIndex)
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
if (!spellInfo)
{
- TC_LOG_ERROR("spells", "Spell::EffectTriggerMissileSpell spell %u tried to trigger unknown spell %u", m_spellInfo->Id, triggered_spell_id);
+ TC_LOG_ERROR("spells", "Spell::EffectTriggerMissileSpell spell %u tried to trigger unknown spell %u.", m_spellInfo->Id, triggered_spell_id);
return;
}
@@ -944,7 +944,7 @@ void Spell::EffectForceCast(SpellEffIndex effIndex)
if (!spellInfo)
{
- TC_LOG_ERROR("spells", "Spell::EffectForceCast of spell %u: triggering unknown spell id %i", m_spellInfo->Id, triggered_spell_id);
+ TC_LOG_ERROR("spells", "Spell::EffectForceCast of spell %u: triggering unknown spell id %i.", m_spellInfo->Id, triggered_spell_id);
return;
}
@@ -996,7 +996,7 @@ void Spell::EffectTriggerRitualOfSummoning(SpellEffIndex effIndex)
if (!spellInfo)
{
- TC_LOG_ERROR("spells", "EffectTriggerRitualOfSummoning of spell %u: triggering unknown spell id %i", m_spellInfo->Id, triggered_spell_id);
+ TC_LOG_ERROR("spells", "EffectTriggerRitualOfSummoning of spell %u: triggering unknown spell id %i.", m_spellInfo->Id, triggered_spell_id);
return;
}
@@ -1062,7 +1062,7 @@ void Spell::EffectTeleportUnits(SpellEffIndex /*effIndex*/)
// If not exist data for dest location - return
if (!m_targets.HasDst())
{
- TC_LOG_ERROR("spells", "Spell::EffectTeleportUnits - does not have destination for spellId %u.", m_spellInfo->Id);
+ TC_LOG_ERROR("spells", "Spell::EffectTeleportUnits - does not have a destination for spellId %u.", m_spellInfo->Id);
return;
}
@@ -1393,7 +1393,7 @@ void Spell::EffectHeal(SpellEffIndex /*effIndex*/)
if (!targetAura)
{
- TC_LOG_ERROR("spells", "Target (%s) has aurastate AURA_STATE_SWIFTMEND but no matching aura.", unitTarget->GetGUID().ToString().c_str());
+ TC_LOG_ERROR("spells", "Target (%s) has the aurastate AURA_STATE_SWIFTMEND, but no matching aura.", unitTarget->GetGUID().ToString().c_str());
return;
}
@@ -1886,7 +1886,7 @@ void Spell::SendLoot(ObjectGuid guid, LootType loottype)
// Players shouldn't be able to loot gameobjects that are currently despawned
if (!gameObjTarget->isSpawned() && !player->IsGameMaster())
{
- TC_LOG_ERROR("spells", "Possible hacking attempt: Player %s [guid: %u] tried to loot a gameobject [entry: %u id: %u] which is on respawn time without being in GM mode!",
+ TC_LOG_ERROR("spells", "Possible hacking attempt: Player %s [guid: %u] tried to loot a gameobject [entry: %u id: %u] which is on respawn timer without being in GM mode!",
player->GetName().c_str(), player->GetGUID().GetCounter(), gameObjTarget->GetEntry(), gameObjTarget->GetGUID().GetCounter());
return;
}
@@ -2191,7 +2191,7 @@ void Spell::EffectSummonType(SpellEffIndex effIndex)
SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[effIndex].MiscValueB);
if (!properties)
{
- TC_LOG_ERROR("spells", "EffectSummonType: Unhandled summon type %u", m_spellInfo->Effects[effIndex].MiscValueB);
+ TC_LOG_ERROR("spells", "EffectSummonType: Unhandled summon type %u.", m_spellInfo->Effects[effIndex].MiscValueB);
return;
}
@@ -2379,7 +2379,7 @@ void Spell::EffectLearnSpell(SpellEffIndex effIndex)
uint32 spellToLearn = (m_spellInfo->Id == 483 || m_spellInfo->Id == 55884) ? damage : m_spellInfo->Effects[effIndex].TriggerSpell;
player->LearnSpell(spellToLearn, false);
- TC_LOG_DEBUG("spells", "Spell: Player %u has learned spell %u from NpcGUID=%u", player->GetGUID().GetCounter(), spellToLearn, m_caster->GetGUID().GetCounter());
+ TC_LOG_DEBUG("spells", "Spell: Player %u has learned spell %u from NpcGUID: %u", player->GetGUID().GetCounter(), spellToLearn, m_caster->GetGUID().GetCounter());
}
void Spell::EffectDispel(SpellEffIndex effIndex)
@@ -2758,7 +2758,7 @@ void Spell::EffectEnchantItemPrismatic(SpellEffIndex effIndex)
}
if (!add_socket)
{
- TC_LOG_ERROR("spells", "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.",
+ TC_LOG_ERROR("spells", "Spell::EffectEnchantItemPrismatic: attempt to apply the enchant spell %u with SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC (%u), but without ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET (%u), not supported yet.",
m_spellInfo->Id, SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC, ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET);
return;
}
@@ -2823,7 +2823,7 @@ void Spell::EffectEnchantItemTmp(SpellEffIndex effIndex)
case 10: spell_id = 36758; break; // 14%
case 11: spell_id = 36760; break; // 20%
default:
- TC_LOG_ERROR("spells", "Spell::EffectEnchantItemTmp: Damage %u not handled in S'RW", damage);
+ TC_LOG_ERROR("spells", "Spell::EffectEnchantItemTmp: Damage %u not handled in S'RW.", damage);
return;
}
@@ -2857,14 +2857,14 @@ void Spell::EffectEnchantItemTmp(SpellEffIndex effIndex)
if (!enchant_id)
{
- TC_LOG_ERROR("spells", "Spell %u Effect %u (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have 0 as enchanting id", m_spellInfo->Id, effIndex);
+ TC_LOG_ERROR("spells", "Spell %u Effect %u (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) has enchanting id 0.", m_spellInfo->Id, effIndex);
return;
}
SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
if (!pEnchant)
{
- TC_LOG_ERROR("spells", "Spell %u Effect %u (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have not existed enchanting id %u ", m_spellInfo->Id, effIndex, enchant_id);
+ TC_LOG_ERROR("spells", "Spell %u Effect %u (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) has a non-existing enchanting id %u ", m_spellInfo->Id, effIndex, enchant_id);
return;
}
@@ -3980,7 +3980,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
case 31893: spell_heal = 48084; break;
case 31883: spell_heal = 48085; break;
default:
- TC_LOG_ERROR("spells", "Unknown Lightwell spell caster %u", m_caster->GetEntry());
+ TC_LOG_ERROR("spells", "Unknown Lightwell spell caster %u.", m_caster->GetEntry());
return;
}
@@ -4219,7 +4219,7 @@ void Spell::EffectStuck(SpellEffIndex /*effIndex*/)
return;
TC_LOG_DEBUG("spells", "Spell Effect: Stuck");
- TC_LOG_DEBUG("spells", "Player %s (guid %u) used auto-unstuck future at map %u (%f, %f, %f)", player->GetName().c_str(), player->GetGUID().GetCounter(), player->GetMapId(), player->GetPositionX(), player->GetPositionY(), player->GetPositionZ());
+ TC_LOG_DEBUG("spells", "Player %s (guid %u) used the auto-unstuck feature at map %u (%f, %f, %f).", player->GetName().c_str(), player->GetGUID().GetCounter(), player->GetMapId(), player->GetPositionX(), player->GetPositionY(), player->GetPositionZ());
if (player->IsInFlight())
return;
@@ -4536,7 +4536,7 @@ void Spell::EffectResurrect(SpellEffIndex effIndex)
Player* target = unitTarget->ToPlayer();
- if (target->isResurrectRequested()) // already have one active request
+ if (target->IsResurrectRequested()) // already have one active request
return;
uint32 health = target->CountPctFromMaxHealth(damage);
@@ -4544,7 +4544,7 @@ void Spell::EffectResurrect(SpellEffIndex effIndex)
ExecuteLogEffectResurrect(effIndex, target);
- target->setResurrectRequestData(m_caster->GetGUID(), m_caster->GetMapId(), m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ(), health, mana);
+ target->SetResurrectRequestData(m_caster, health, mana, 0);
SendResurrectRequest(target);
}
@@ -5101,7 +5101,7 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex)
if (!goinfo)
{
- TC_LOG_ERROR("sql.sql", "Gameobject (Entry: %u) not exist and not created at spell (ID: %u) cast", name_id, m_spellInfo->Id);
+ TC_LOG_ERROR("sql.sql", "Gameobject (Entry: %u) does not exist and is not created by spell (ID: %u) cast.", name_id, m_spellInfo->Id);
return;
}
@@ -5742,7 +5742,7 @@ void Spell::EffectPlayMusic(SpellEffIndex effIndex)
if (!sSoundEntriesStore.LookupEntry(soundid))
{
- TC_LOG_ERROR("spells", "EffectPlayMusic: Sound (Id: %u) not exist in spell %u.", soundid, m_spellInfo->Id);
+ TC_LOG_ERROR("spells", "EffectPlayMusic: Sound (Id: %u) does not exist in spell %u.", soundid, m_spellInfo->Id);
return;
}
@@ -5799,7 +5799,7 @@ void Spell::EffectPlaySound(SpellEffIndex effIndex)
if (!sSoundEntriesStore.LookupEntry(soundId))
{
- TC_LOG_ERROR("spells", "EffectPlaySound: Sound (Id: %u) not exist in spell %u.", soundId, m_spellInfo->Id);
+ TC_LOG_ERROR("spells", "EffectPlaySound: Sound (Id: %u) does not exist in spell %u.", soundId, m_spellInfo->Id);
return;
}
diff --git a/src/server/game/Spells/SpellHistory.h b/src/server/game/Spells/SpellHistory.h
index f0a53fe130d..ccc8a7daa96 100644
--- a/src/server/game/Spells/SpellHistory.h
+++ b/src/server/game/Spells/SpellHistory.h
@@ -31,7 +31,7 @@ class SpellInfo;
class Unit;
struct SpellCategoryEntry;
-class SpellHistory
+class TC_GAME_API SpellHistory
{
public:
typedef std::chrono::system_clock Clock;
diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h
index ba658c885fa..1530235174a 100644
--- a/src/server/game/Spells/SpellInfo.h
+++ b/src/server/game/Spells/SpellInfo.h
@@ -187,13 +187,14 @@ enum SpellCustomAttributes
SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER = 0x00010000,
SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET = 0x00020000,
SPELL_ATTR0_CU_ALLOW_INFLIGHT_TARGET = 0x00040000,
+ SPELL_ATTR0_CU_NEEDS_AMMO_DATA = 0x00080000,
SPELL_ATTR0_CU_NEGATIVE = SPELL_ATTR0_CU_NEGATIVE_EFF0 | SPELL_ATTR0_CU_NEGATIVE_EFF1 | SPELL_ATTR0_CU_NEGATIVE_EFF2
};
uint32 GetTargetFlagMask(SpellTargetObjectTypes objType);
-class SpellImplicitTargetInfo
+class TC_GAME_API SpellImplicitTargetInfo
{
private:
Targets _target;
@@ -224,7 +225,7 @@ private:
static StaticData _data[TOTAL_SPELL_TARGETS];
};
-class SpellEffectInfo
+class TC_GAME_API SpellEffectInfo
{
SpellInfo const* _spellInfo;
uint8 _effIndex;
@@ -290,7 +291,7 @@ private:
static StaticData _data[TOTAL_SPELL_EFFECTS];
};
-class SpellInfo
+class TC_GAME_API SpellInfo
{
public:
uint32 Id;
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index f5bb1c920fe..50f750f2ca5 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -353,6 +353,12 @@ SpellMgr::~SpellMgr()
UnloadSpellInfoStore();
}
+SpellMgr* SpellMgr::instance()
+{
+ static SpellMgr instance;
+ return &instance;
+}
+
/// Some checks for spells, to prevent adding deprecated/broken spells for trainers, spell book, etc
bool SpellMgr::IsSpellValid(SpellInfo const* spellInfo, Player* player, bool msg)
{
@@ -376,29 +382,29 @@ bool SpellMgr::IsSpellValid(SpellInfo const* spellInfo, Player* player, bool msg
{
if (spellInfo->Effects[i].ItemType == 0)
{
- // skip auto-loot crafting spells, its not need explicit item info (but have special fake items sometime)
+ // skip auto-loot crafting spells, it does not need explicit item info (but has special fake items sometimes).
if (!spellInfo->IsLootCrafting())
{
if (msg)
{
if (player)
- ChatHandler(player->GetSession()).PSendSysMessage("Craft spell %u not have create item entry.", spellInfo->Id);
+ ChatHandler(player->GetSession()).PSendSysMessage("The craft spell %u does not have a create item entry.", spellInfo->Id);
else
- TC_LOG_ERROR("sql.sql", "Craft spell %u not have create item entry.", spellInfo->Id);
+ TC_LOG_ERROR("sql.sql", "The craft spell %u does not have a create item entry.", spellInfo->Id);
}
return false;
}
}
- // also possible IsLootCrafting case but fake item must exist anyway
+ // also possible IsLootCrafting case but fake items must exist anyway
else if (!sObjectMgr->GetItemTemplate(spellInfo->Effects[i].ItemType))
{
if (msg)
{
if (player)
- ChatHandler(player->GetSession()).PSendSysMessage("Craft spell %u create not-exist in DB item (Entry: %u) and then...", spellInfo->Id, spellInfo->Effects[i].ItemType);
+ ChatHandler(player->GetSession()).PSendSysMessage("Craft spell %u has created a non-existing item in DB (Entry: %u) and then...", spellInfo->Id, spellInfo->Effects[i].ItemType);
else
- TC_LOG_ERROR("sql.sql", "Craft spell %u create not-exist in DB item (Entry: %u) and then...", spellInfo->Id, spellInfo->Effects[i].ItemType);
+ TC_LOG_ERROR("sql.sql", "Craft spell %u has created a non-existing item in DB (Entry: %u) and then...", spellInfo->Id, spellInfo->Effects[i].ItemType);
}
return false;
}
@@ -434,9 +440,9 @@ bool SpellMgr::IsSpellValid(SpellInfo const* spellInfo, Player* player, bool msg
if (msg)
{
if (player)
- ChatHandler(player->GetSession()).PSendSysMessage("Craft spell %u have not-exist reagent in DB item (Entry: %u) and then...", spellInfo->Id, spellInfo->Reagent[j]);
+ ChatHandler(player->GetSession()).PSendSysMessage("Craft spell %u refers a non-existing reagent in DB item (Entry: %u) and then...", spellInfo->Id, spellInfo->Reagent[j]);
else
- TC_LOG_ERROR("sql.sql", "Craft spell %u have not-exist reagent in DB item (Entry: %u) and then...", spellInfo->Id, spellInfo->Reagent[j]);
+ TC_LOG_ERROR("sql.sql", "Craft spell %u refers to a non-existing reagent in DB, item (Entry: %u) and then...", spellInfo->Id, spellInfo->Reagent[j]);
}
return false;
}
@@ -455,7 +461,7 @@ uint32 SpellMgr::GetSpellDifficultyId(uint32 spellId) const
void SpellMgr::SetSpellDifficultyId(uint32 spellId, uint32 id)
{
if (uint32 i = GetSpellDifficultyId(spellId))
- TC_LOG_ERROR("spells", "SpellMgr::SetSpellDifficultyId: Spell %u has already spellDifficultyId %u. Will override with spellDifficultyId %u.", spellId, i, id);
+ TC_LOG_ERROR("spells", "SpellMgr::SetSpellDifficultyId: The spell %u already has spellDifficultyId %u. Will override with spellDifficultyId %u.", spellId, i, id);
mSpellDifficultySearcherMap[spellId] = id;
}
@@ -470,7 +476,7 @@ uint32 SpellMgr::GetSpellIdForDifficulty(uint32 spellId, Unit const* caster) con
uint32 mode = uint32(caster->GetMap()->GetSpawnMode());
if (mode >= MAX_DIFFICULTY)
{
- TC_LOG_ERROR("spells", "SpellMgr::GetSpellIdForDifficulty: Incorrect Difficulty for spell %u.", spellId);
+ TC_LOG_ERROR("spells", "SpellMgr::GetSpellIdForDifficulty: Incorrect difficulty for spell %u.", spellId);
return spellId; //return source spell
}
@@ -481,7 +487,7 @@ uint32 SpellMgr::GetSpellIdForDifficulty(uint32 spellId, Unit const* caster) con
SpellDifficultyEntry const* difficultyEntry = sSpellDifficultyStore.LookupEntry(difficultyId);
if (!difficultyEntry)
{
- TC_LOG_ERROR("spells", "SpellMgr::GetSpellIdForDifficulty: SpellDifficultyEntry not found for spell %u. This should never happen.", spellId);
+ TC_LOG_ERROR("spells", "SpellMgr::GetSpellIdForDifficulty: SpellDifficultyEntry was not found for spell %u. This should never happen.", spellId);
return spellId; //return source spell
}
@@ -874,7 +880,7 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellInfo const* spellProto, Spell
// For melee triggers
if (procSpell == NULL)
{
- // Check (if set) for school (melee attack have Normal school)
+ // Check (if set) for school (melee attack has Normal school)
if (spellProcEvent->schoolMask && (spellProcEvent->schoolMask & SPELL_SCHOOL_MASK_NORMAL) == 0)
return false;
}
@@ -894,7 +900,7 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellInfo const* spellProto, Spell
if (!(spellProcEvent->spellFamilyMask & procSpell->SpellFamilyFlags))
return false;
hasFamilyMask = true;
- // Some spells are not considered as active even with have spellfamilyflags
+ // Some spells are not considered as active even with spellfamilyflags set
if (!(procEvent_procEx & PROC_EX_ONLY_ACTIVE_SPELL))
active = true;
}
@@ -1121,27 +1127,27 @@ SpellAreaForAreaMapBounds SpellMgr::GetSpellAreaForAreaMapBounds(uint32 area_id)
bool SpellArea::IsFitToRequirements(Player const* player, uint32 newZone, uint32 newArea) const
{
- if (gender != GENDER_NONE) // not in expected gender
+ if (gender != GENDER_NONE) // is not expected gender
if (!player || gender != player->getGender())
return false;
- if (raceMask) // not in expected race
+ if (raceMask) // is not expected race
if (!player || !(raceMask & player->getRaceMask()))
return false;
- if (areaId) // not in expected zone
+ if (areaId) // is not in expected zone
if (newZone != areaId && newArea != areaId)
return false;
- if (questStart) // not in expected required quest state
+ if (questStart) // is not in expected required quest state
if (!player || (((1 << player->GetQuestStatus(questStart)) & questStartStatus) == 0))
return false;
- if (questEnd) // not in expected forbidden quest state
+ if (questEnd) // is not in expected forbidden quest state
if (!player || (((1 << player->GetQuestStatus(questEnd)) & questEndStatus) == 0))
return false;
- if (auraSpell) // not have expected aura
+ if (auraSpell) // does not have expected aura
if (!player || (auraSpell > 0 && !player->HasAura(auraSpell)) || (auraSpell < 0 && player->HasAura(-auraSpell)))
return false;
@@ -1341,7 +1347,7 @@ void SpellMgr::LoadSpellRanks()
SpellInfo const* first = GetSpellInfo(lastSpell);
if (!first)
{
- TC_LOG_ERROR("sql.sql", "Spell rank identifier(first_spell_id) %u listed in `spell_ranks` does not exist!", lastSpell);
+ TC_LOG_ERROR("sql.sql", "The spell rank identifier(first_spell_id) %u listed in `spell_ranks` does not exist!", lastSpell);
continue;
}
// check if chain is long enough
@@ -1358,14 +1364,14 @@ void SpellMgr::LoadSpellRanks()
SpellInfo const* spell = GetSpellInfo(itr->first);
if (!spell)
{
- TC_LOG_ERROR("sql.sql", "Spell %u (rank %u) listed in `spell_ranks` for chain %u does not exist!", itr->first, itr->second, lastSpell);
+ TC_LOG_ERROR("sql.sql", "The spell %u (rank %u) listed in `spell_ranks` for chain %u does not exist!", itr->first, itr->second, lastSpell);
valid = false;
break;
}
++curRank;
if (itr->second != curRank)
{
- TC_LOG_ERROR("sql.sql", "Spell %u (rank %u) listed in `spell_ranks` for chain %u does not have proper rank value(should be %u)!", itr->first, itr->second, lastSpell, curRank);
+ TC_LOG_ERROR("sql.sql", "The spell %u (rank %u) listed in `spell_ranks` for chain %u does not have a proper rank value (should be %u)!", itr->first, itr->second, lastSpell, curRank);
valid = false;
break;
}
@@ -1381,7 +1387,7 @@ void SpellMgr::LoadSpellRanks()
int32 addedSpell = itr->first;
if (mSpellInfoMap[addedSpell]->ChainEntry)
- TC_LOG_ERROR("sql.sql", "Spell %u (rank: %u, first: %u) listed in `spell_ranks` has already ChainEntry from dbc.", addedSpell, itr->second, lastSpell);
+ TC_LOG_ERROR("sql.sql", "The spell %u (rank: %u, first: %u) listed in `spell_ranks` already has ChainEntry from dbc.", addedSpell, itr->second, lastSpell);
mSpellChains[addedSpell].first = GetSpellInfo(lastSpell);
mSpellChains[addedSpell].last = GetSpellInfo(rankChain.back().first);
@@ -1435,26 +1441,26 @@ void SpellMgr::LoadSpellRequired()
SpellInfo const* spell = GetSpellInfo(spell_id);
if (!spell)
{
- TC_LOG_ERROR("sql.sql", "spell_id %u in `spell_required` table is not found in dbcs, skipped", spell_id);
+ TC_LOG_ERROR("sql.sql", "spell_id %u in `spell_required` table could not be found in dbc, skipped.", spell_id);
continue;
}
SpellInfo const* reqSpell = GetSpellInfo(spell_req);
if (!reqSpell)
{
- TC_LOG_ERROR("sql.sql", "req_spell %u in `spell_required` table is not found in dbcs, skipped", spell_req);
+ TC_LOG_ERROR("sql.sql", "req_spell %u in `spell_required` table could not be found in dbc, skipped.", spell_req);
continue;
}
if (spell->IsRankOf(reqSpell))
{
- TC_LOG_ERROR("sql.sql", "req_spell %u and spell_id %u in `spell_required` table are ranks of the same spell, entry not needed, skipped", spell_req, spell_id);
+ TC_LOG_ERROR("sql.sql", "req_spell %u and spell_id %u in `spell_required` table are ranks of the same spell, entry not needed, skipped.", spell_req, spell_id);
continue;
}
if (IsSpellRequiringSpell(spell_id, spell_req))
{
- TC_LOG_ERROR("sql.sql", "duplicated entry of req_spell %u and spell_id %u in `spell_required`, skipped", spell_req, spell_id);
+ TC_LOG_ERROR("sql.sql", "Duplicate entry of req_spell %u and spell_id %u in `spell_required`, skipped.", spell_req, spell_id);
continue;
}
@@ -1532,19 +1538,19 @@ void SpellMgr::LoadSpellLearnSpells()
if (!GetSpellInfo(spell_id))
{
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_learn_spell` does not exist", spell_id);
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_learn_spell` does not exist.", spell_id);
continue;
}
if (!GetSpellInfo(node.spell))
{
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_learn_spell` learning not existed spell %u", spell_id, node.spell);
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_learn_spell` learning non-existing spell %u.", spell_id, node.spell);
continue;
}
if (GetTalentSpellCost(node.spell))
{
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_learn_spell` attempt learning talent spell %u, skipped", spell_id, node.spell);
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_learn_spell` attempts learning talent spell %u, skipped.", spell_id, node.spell);
continue;
}
@@ -1586,7 +1592,7 @@ void SpellMgr::LoadSpellLearnSpells()
{
if (itr->second.spell == dbc_node.spell)
{
- TC_LOG_ERROR("sql.sql", "Spell %u auto-learn spell %u in spell.dbc then the record in `spell_learn_spell` is redundant, please fix DB.",
+ TC_LOG_ERROR("sql.sql", "The spell %u is an auto-learn spell %u in spell.dbc and the record in `spell_learn_spell` is redundant. Please update your DB.",
spell, dbc_node.spell);
found = true;
break;
@@ -1663,7 +1669,7 @@ void SpellMgr::LoadSpellTargetPositions()
}
else
{
- TC_LOG_ERROR("sql.sql", "Spell (Id: %u, effIndex: %u) listed in `spell_target_position` does not have target TARGET_DEST_DB (17).", Spell_ID, effIndex);
+ TC_LOG_ERROR("sql.sql", "Spell (Id: %u, effIndex: %u) listed in `spell_target_position` does not have a target TARGET_DEST_DB (17).", Spell_ID, effIndex);
continue;
}
@@ -1700,7 +1706,7 @@ void SpellMgr::LoadSpellTargetPositions()
if (found)
{
if (!sSpellMgr->GetSpellTargetPosition(i))
- TC_LOG_DEBUG("spells", "Spell (ID: %u) does not have record in `spell_target_position`", i);
+ TC_LOG_DEBUG("spells", "Spell (ID: %u) does not have a record in `spell_target_position`.", i);
}
}*/
@@ -1759,12 +1765,12 @@ void SpellMgr::LoadSpellGroups()
if (!spellInfo)
{
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_group` does not exist", itr->second);
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_group` does not exist", itr->second);
mSpellGroupSpell.erase(itr++);
}
else if (spellInfo->GetRank() > 1)
{
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_group` is not first rank of spell", itr->second);
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_group` is not the first rank of the spell.", itr->second);
mSpellGroupSpell.erase(itr++);
}
else
@@ -1810,7 +1816,7 @@ void SpellMgr::LoadSpellGroupStackRules()
uint8 stack_rule = fields[1].GetInt8();
if (stack_rule >= SPELL_GROUP_STACK_RULE_MAX)
{
- TC_LOG_ERROR("sql.sql", "SpellGroupStackRule %u listed in `spell_group_stack_rules` does not exist", stack_rule);
+ TC_LOG_ERROR("sql.sql", "SpellGroupStackRule %u listed in `spell_group_stack_rules` does not exist.", stack_rule);
continue;
}
@@ -1818,7 +1824,7 @@ void SpellMgr::LoadSpellGroupStackRules()
if (spellGroup.first == spellGroup.second)
{
- TC_LOG_ERROR("sql.sql", "SpellGroup id %u listed in `spell_group_stack_rules` does not exist", group_id);
+ TC_LOG_ERROR("sql.sql", "SpellGroup id %u listed in `spell_group_stack_rules` does not exist.", group_id);
continue;
}
@@ -1862,18 +1868,18 @@ void SpellMgr::LoadSpellProcEvents()
SpellInfo const* spellInfo = GetSpellInfo(spellId);
if (!spellInfo)
{
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_proc_event` does not exist", spellId);
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_proc_event` does not exist.", spellId);
continue;
}
if (allRanks)
{
if (!spellInfo->IsRanked())
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_proc_event` with all ranks, but spell has no ranks.", spellId);
+ TC_LOG_ERROR("sql.sql", "The spell %u is listed in `spell_proc_event` with all ranks, but spell has no ranks.", spellId);
if (spellInfo->GetFirstRankSpell()->Id != uint32(spellId))
{
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_proc_event` is not first rank of spell.", spellId);
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_proc_event` is not first rank of spell.", spellId);
continue;
}
}
@@ -1895,12 +1901,12 @@ void SpellMgr::LoadSpellProcEvents()
{
if (mSpellProcEventMap.find(spellInfo->Id) != mSpellProcEventMap.end())
{
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_proc_event` already has its first rank in table.", spellInfo->Id);
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_proc_event` already has its first rank in table.", spellInfo->Id);
break;
}
if (!spellInfo->ProcFlags && !spellProcEvent.procFlags)
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_proc_event` probably not triggered spell", spellInfo->Id);
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_proc_event` is probably not a triggered spell.", spellInfo->Id);
mSpellProcEventMap[spellInfo->Id] = spellProcEvent;
@@ -1948,18 +1954,18 @@ void SpellMgr::LoadSpellProcs()
SpellInfo const* spellInfo = GetSpellInfo(spellId);
if (!spellInfo)
{
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_proc` does not exist", spellId);
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_proc` does not exist", spellId);
continue;
}
if (allRanks)
{
if (!spellInfo->IsRanked())
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_proc` with all ranks, but spell has no ranks.", spellId);
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_proc` with all ranks, but spell has no ranks.", spellId);
if (spellInfo->GetFirstRankSpell()->Id != uint32(spellId))
{
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_proc` is not first rank of spell.", spellId);
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_proc` is not the first rank of the spell.", spellId);
continue;
}
}
@@ -1986,7 +1992,7 @@ void SpellMgr::LoadSpellProcs()
{
if (mSpellProcMap.find(spellInfo->Id) != mSpellProcMap.end())
{
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_proc` already has its first rank in table.", spellInfo->Id);
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_proc` already has its first rank in the table.", spellInfo->Id);
break;
}
@@ -2007,42 +2013,42 @@ void SpellMgr::LoadSpellProcs()
TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has wrong `spellFamilyName` set: %u", spellInfo->Id, procEntry.spellFamilyName);
if (procEntry.chance < 0)
{
- TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has negative value in `chance` field", spellInfo->Id);
+ TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has negative value in the `chance` field", spellInfo->Id);
procEntry.chance = 0;
}
if (procEntry.ratePerMinute < 0)
{
- TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has negative value in `ratePerMinute` field", spellInfo->Id);
+ TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has negative value in the `ratePerMinute` field", spellInfo->Id);
procEntry.ratePerMinute = 0;
}
if (cooldown < 0)
{
- TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has negative value in `cooldown` field", spellInfo->Id);
+ TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has negative value in the `cooldown` field", spellInfo->Id);
procEntry.cooldown = 0;
}
if (procEntry.chance == 0 && procEntry.ratePerMinute == 0)
- TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u doesn't have `chance` and `ratePerMinute` values defined, proc will not be triggered", spellInfo->Id);
+ TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u doesn't have any `chance` and `ratePerMinute` values defined, proc will not be triggered", spellInfo->Id);
if (procEntry.charges > 99)
{
- TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has too big value in `charges` field", spellInfo->Id);
+ TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has a too big `charges` field value.", spellInfo->Id);
procEntry.charges = 99;
}
if (!procEntry.typeMask)
- TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u doesn't have `typeMask` value defined, proc will not be triggered", spellInfo->Id);
+ TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u doesn't have any `typeMask` value defined, proc will not be triggered.", spellInfo->Id);
if (procEntry.spellTypeMask & ~PROC_SPELL_TYPE_MASK_ALL)
TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has wrong `spellTypeMask` set: %u", spellInfo->Id, procEntry.spellTypeMask);
if (procEntry.spellTypeMask && !(procEntry.typeMask & (SPELL_PROC_FLAG_MASK | PERIODIC_PROC_FLAG_MASK)))
- TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has `spellTypeMask` value defined, but it won't be used for defined `typeMask` value", spellInfo->Id);
+ TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has `spellTypeMask` value defined, but it will not be used for the defined `typeMask` value.", spellInfo->Id);
if (!procEntry.spellPhaseMask && procEntry.typeMask & REQ_SPELL_PHASE_PROC_FLAG_MASK)
- TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u doesn't have `spellPhaseMask` value defined, but it's required for defined `typeMask` value, proc will not be triggered", spellInfo->Id);
+ TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u doesn't have any `spellPhaseMask` value defined, but it is required for the defined `typeMask` value. Proc will not be triggered.", spellInfo->Id);
if (procEntry.spellPhaseMask & ~PROC_SPELL_PHASE_MASK_ALL)
- TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has wrong `spellPhaseMask` set: %u", spellInfo->Id, procEntry.spellPhaseMask);
+ TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has wrong `spellPhaseMask` set: %u", spellInfo->Id, procEntry.spellPhaseMask);
if (procEntry.spellPhaseMask && !(procEntry.typeMask & REQ_SPELL_PHASE_PROC_FLAG_MASK))
- TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has `spellPhaseMask` value defined, but it won't be used for defined `typeMask` value", spellInfo->Id);
+ TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has a `spellPhaseMask` value defined, but it will not be used for the defined `typeMask` value.", spellInfo->Id);
if (procEntry.hitMask & ~PROC_HIT_MASK_ALL)
- TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has wrong `hitMask` set: %u", spellInfo->Id, procEntry.hitMask);
+ TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has wrong `hitMask` set: %u", spellInfo->Id, procEntry.hitMask);
if (procEntry.hitMask && !(procEntry.typeMask & TAKEN_HIT_PROC_FLAG_MASK || (procEntry.typeMask & DONE_HIT_PROC_FLAG_MASK && (!procEntry.spellPhaseMask || procEntry.spellPhaseMask & (PROC_SPELL_PHASE_HIT | PROC_SPELL_PHASE_FINISH)))))
- TC_LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId %u has `hitMask` value defined, but it won't be used for defined `typeMask` and `spellPhaseMask` values", spellInfo->Id);
+ TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has `hitMask` value defined, but it will not be used for defined `typeMask` and `spellPhaseMask` values.", spellInfo->Id);
mSpellProcMap[spellInfo->Id] = procEntry;
@@ -2081,7 +2087,7 @@ void SpellMgr::LoadSpellBonusess()
SpellInfo const* spell = GetSpellInfo(entry);
if (!spell)
{
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_bonus_data` does not exist", entry);
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_bonus_data` does not exist.", entry);
continue;
}
@@ -2120,7 +2126,7 @@ void SpellMgr::LoadSpellThreats()
if (!GetSpellInfo(entry))
{
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_threat` does not exist", entry);
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_threat` does not exist.", entry);
continue;
}
@@ -2189,21 +2195,21 @@ void SpellMgr::LoadSpellPetAuras()
SpellInfo const* spellInfo = GetSpellInfo(spell);
if (!spellInfo)
{
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_pet_auras` does not exist", spell);
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_pet_auras` does not exist.", spell);
continue;
}
if (spellInfo->Effects[eff].Effect != SPELL_EFFECT_DUMMY &&
(spellInfo->Effects[eff].Effect != SPELL_EFFECT_APPLY_AURA ||
spellInfo->Effects[eff].ApplyAuraName != SPELL_AURA_DUMMY))
{
- TC_LOG_ERROR("spells", "Spell %u listed in `spell_pet_auras` does not have dummy aura or dummy effect", spell);
+ TC_LOG_ERROR("spells", "The spell %u listed in `spell_pet_auras` does not have any dummy aura or dummy effect.", spell);
continue;
}
SpellInfo const* spellInfo2 = GetSpellInfo(aura);
if (!spellInfo2)
{
- TC_LOG_ERROR("sql.sql", "Aura %u listed in `spell_pet_auras` does not exist", aura);
+ TC_LOG_ERROR("sql.sql", "The aura %u listed in `spell_pet_auras` does not exist.", aura);
continue;
}
@@ -2281,7 +2287,7 @@ void SpellMgr::LoadSpellEnchantProcData()
SpellItemEnchantmentEntry const* ench = sSpellItemEnchantmentStore.LookupEntry(enchantId);
if (!ench)
{
- TC_LOG_ERROR("sql.sql", "Enchancment %u listed in `spell_enchant_proc_data` does not exist", enchantId);
+ TC_LOG_ERROR("sql.sql", "The enchancment %u listed in `spell_enchant_proc_data` does not exist.", enchantId);
continue;
}
@@ -2325,7 +2331,7 @@ void SpellMgr::LoadSpellLinked()
SpellInfo const* spellInfo = GetSpellInfo(abs(trigger));
if (!spellInfo)
{
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_linked_spell` does not exist", abs(trigger));
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_linked_spell` does not exist.", abs(trigger));
continue;
}
@@ -2333,13 +2339,13 @@ void SpellMgr::LoadSpellLinked()
for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
{
if (spellInfo->Effects[j].CalcValue() == abs(effect))
- TC_LOG_ERROR("sql.sql", "Spell %u Effect: %u listed in `spell_linked_spell` has same bp%u like effect (possible hack)", abs(trigger), abs(effect), j);
+ TC_LOG_ERROR("sql.sql", "The spell %u Effect: %u listed in `spell_linked_spell` has same bp%u like effect (possible hack).", abs(trigger), abs(effect), j);
}
spellInfo = GetSpellInfo(abs(effect));
if (!spellInfo)
{
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_linked_spell` does not exist", abs(effect));
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_linked_spell` does not exist.", abs(effect));
continue;
}
@@ -2584,7 +2590,7 @@ void SpellMgr::LoadSpellAreas()
}
else
{
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_area` does not exist", spell);
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_area` does not exist", spell);
continue;
}
@@ -2613,20 +2619,20 @@ void SpellMgr::LoadSpellAreas()
if (!ok)
{
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_area` already listed with similar requirements.", spell);
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_area` is already listed with similar requirements.", spell);
continue;
}
}
if (spellArea.areaId && !sAreaTableStore.LookupEntry(spellArea.areaId))
{
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_area` have wrong area (%u) requirement", spell, spellArea.areaId);
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_area` has a wrong area (%u) requirement.", spell, spellArea.areaId);
continue;
}
if (spellArea.questStart && !sObjectMgr->GetQuestTemplate(spellArea.questStart))
{
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_area` have wrong start quest (%u) requirement", spell, spellArea.questStart);
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_area` has a wrong start quest (%u) requirement.", spell, spellArea.questStart);
continue;
}
@@ -2634,7 +2640,7 @@ void SpellMgr::LoadSpellAreas()
{
if (!sObjectMgr->GetQuestTemplate(spellArea.questEnd))
{
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_area` have wrong end quest (%u) requirement", spell, spellArea.questEnd);
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_area` has a wrong ending quest (%u) requirement.", spell, spellArea.questEnd);
continue;
}
}
@@ -2644,13 +2650,13 @@ void SpellMgr::LoadSpellAreas()
SpellInfo const* spellInfo = GetSpellInfo(abs(spellArea.auraSpell));
if (!spellInfo)
{
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_area` have wrong aura spell (%u) requirement", spell, abs(spellArea.auraSpell));
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_area` has wrong aura spell (%u) requirement", spell, abs(spellArea.auraSpell));
continue;
}
if (uint32(abs(spellArea.auraSpell)) == spellArea.spellId)
{
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_area` have aura spell (%u) requirement for itself", spell, abs(spellArea.auraSpell));
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_area` has aura spell (%u) requirement for itself", spell, abs(spellArea.auraSpell));
continue;
}
@@ -2670,7 +2676,7 @@ void SpellMgr::LoadSpellAreas()
if (chain)
{
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_area` have aura spell (%u) requirement that itself autocast from aura", spell, spellArea.auraSpell);
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_area` has the aura spell (%u) requirement that it autocasts itself from the aura.", spell, spellArea.auraSpell);
continue;
}
@@ -2686,7 +2692,7 @@ void SpellMgr::LoadSpellAreas()
if (chain)
{
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_area` have aura spell (%u) requirement that itself autocast from aura", spell, spellArea.auraSpell);
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_area` has the aura spell (%u) requirement that the spell itself autocasts from the aura.", spell, spellArea.auraSpell);
continue;
}
}
@@ -2694,13 +2700,13 @@ void SpellMgr::LoadSpellAreas()
if (spellArea.raceMask && (spellArea.raceMask & RACEMASK_ALL_PLAYABLE) == 0)
{
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_area` have wrong race mask (%u) requirement", spell, spellArea.raceMask);
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_area` has wrong race mask (%u) requirement.", spell, spellArea.raceMask);
continue;
}
if (spellArea.gender != GENDER_NONE && spellArea.gender != GENDER_FEMALE && spellArea.gender != GENDER_MALE)
{
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_area` have wrong gender (%u) requirement", spell, spellArea.gender);
+ TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_area` has wrong gender (%u) requirement.", spell, spellArea.gender);
continue;
}
@@ -3050,6 +3056,7 @@ void SpellMgr::LoadSpellInfoCorrections()
case 48246: // Ball of Flame
case 36327: // Shoot Arcane Explosion Arrow
case 55479: // Force Obedience
+ case 28560: // Summon Blizzard (Sapphiron)
spellInfo->MaxAffectedTargets = 1;
break;
case 36384: // Skartax Purple Beam
@@ -3235,6 +3242,8 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->AttributesEx4 = 0;
break;
case 8145: // Tremor Totem (instant pulse)
+ spellInfo->AttributesEx2 |= SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS;
+ /*no break*/
case 6474: // Earthbind Totem (instant pulse)
spellInfo->AttributesEx5 |= SPELL_ATTR5_START_PERIODIC_AT_APPLY;
break;
diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h
index 651a8cde938..269a3a90e9d 100644
--- a/src/server/game/Spells/SpellMgr.h
+++ b/src/server/game/Spells/SpellMgr.h
@@ -441,7 +441,7 @@ enum EffectRadiusIndex
};
// Spell pet auras
-class PetAura
+class TC_GAME_API PetAura
{
private:
typedef std::unordered_map<uint32, uint32> PetAuraMap;
@@ -488,7 +488,7 @@ class PetAura
};
typedef std::map<uint32, PetAura> SpellPetAuraMap;
-struct SpellArea
+struct TC_GAME_API SpellArea
{
uint32 spellId;
uint32 areaId; // zone/subzone/or 0 is not limited to zone
@@ -593,13 +593,13 @@ inline bool IsProfessionOrRidingSkill(uint32 skill)
bool IsPartOfSkillLine(uint32 skillId, uint32 spellId);
// spell diminishing returns
-DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const* spellproto, bool triggered);
-DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group);
-DiminishingLevels GetDiminishingReturnsMaxLevel(DiminishingGroup group);
-int32 GetDiminishingReturnsLimitDuration(DiminishingGroup group, SpellInfo const* spellproto);
-bool IsDiminishingReturnsGroupDurationLimited(DiminishingGroup group);
+TC_GAME_API DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const* spellproto, bool triggered);
+TC_GAME_API DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group);
+TC_GAME_API DiminishingLevels GetDiminishingReturnsMaxLevel(DiminishingGroup group);
+TC_GAME_API int32 GetDiminishingReturnsLimitDuration(DiminishingGroup group, SpellInfo const* spellproto);
+TC_GAME_API bool IsDiminishingReturnsGroupDurationLimited(DiminishingGroup group);
-class SpellMgr
+class TC_GAME_API SpellMgr
{
// Constructors
private:
@@ -608,11 +608,7 @@ class SpellMgr
// Accessors (const or static functions)
public:
- static SpellMgr* instance()
- {
- static SpellMgr instance;
- return &instance;
- }
+ static SpellMgr* instance();
// Spell correctness for client using
static bool IsSpellValid(SpellInfo const* spellInfo, Player* player = NULL, bool msg = true);
diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h
index 77a993fffae..1d4efd8073d 100644
--- a/src/server/game/Spells/SpellScript.h
+++ b/src/server/game/Spells/SpellScript.h
@@ -52,7 +52,7 @@ enum SpellScriptState
#define SPELL_SCRIPT_STATE_END SPELL_SCRIPT_STATE_UNLOADING + 1
// helper class from which SpellScript and SpellAura derive, use these classes instead
-class _SpellScript
+class TC_GAME_API _SpellScript
{
// internal use classes & functions
// DO NOT OVERRIDE THESE IN SCRIPTS
@@ -68,7 +68,7 @@ class _SpellScript
std::string const* _GetScriptName() const;
protected:
- class EffectHook
+ class TC_GAME_API EffectHook
{
public:
EffectHook(uint8 _effIndex);
@@ -82,7 +82,7 @@ class _SpellScript
uint8 effIndex;
};
- class EffectNameCheck
+ class TC_GAME_API EffectNameCheck
{
public:
EffectNameCheck(uint16 _effName) { effName = _effName; }
@@ -92,7 +92,7 @@ class _SpellScript
uint16 effName;
};
- class EffectAuraNameCheck
+ class TC_GAME_API EffectAuraNameCheck
{
public:
EffectAuraNameCheck(uint16 _effAurName) { effAurName = _effAurName; }
@@ -149,7 +149,7 @@ enum SpellScriptHookType
#define HOOK_SPELL_END SPELL_SCRIPT_HOOK_CHECK_CAST + 1
#define HOOK_SPELL_COUNT HOOK_SPELL_END - HOOK_SPELL_START
-class SpellScript : public _SpellScript
+class TC_GAME_API SpellScript : public _SpellScript
{
// internal use classes & functions
// DO NOT OVERRIDE THESE IN SCRIPTS
@@ -165,7 +165,7 @@ class SpellScript : public _SpellScript
SPELLSCRIPT_FUNCTION_TYPE_DEFINES(SpellScript)
- class CastHandler
+ class TC_GAME_API CastHandler
{
public:
CastHandler(SpellCastFnType _pCastHandlerScript);
@@ -174,7 +174,7 @@ class SpellScript : public _SpellScript
SpellCastFnType pCastHandlerScript;
};
- class CheckCastHandler
+ class TC_GAME_API CheckCastHandler
{
public:
CheckCastHandler(SpellCheckCastFnType checkCastHandlerScript);
@@ -183,7 +183,7 @@ class SpellScript : public _SpellScript
SpellCheckCastFnType _checkCastHandlerScript;
};
- class EffectHandler : public _SpellScript::EffectNameCheck, public _SpellScript::EffectHook
+ class TC_GAME_API EffectHandler : public _SpellScript::EffectNameCheck, public _SpellScript::EffectHook
{
public:
EffectHandler(SpellEffectFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName);
@@ -194,7 +194,7 @@ class SpellScript : public _SpellScript
SpellEffectFnType pEffectHandlerScript;
};
- class HitHandler
+ class TC_GAME_API HitHandler
{
public:
HitHandler(SpellHitFnType _pHitHandlerScript);
@@ -203,7 +203,7 @@ class SpellScript : public _SpellScript
SpellHitFnType pHitHandlerScript;
};
- class TargetHook : public _SpellScript::EffectHook
+ class TC_GAME_API TargetHook : public _SpellScript::EffectHook
{
public:
TargetHook(uint8 _effectIndex, uint16 _targetType, bool _area, bool _dest);
@@ -216,7 +216,7 @@ class SpellScript : public _SpellScript
bool dest;
};
- class ObjectAreaTargetSelectHandler : public TargetHook
+ class TC_GAME_API ObjectAreaTargetSelectHandler : public TargetHook
{
public:
ObjectAreaTargetSelectHandler(SpellObjectAreaTargetSelectFnType _pObjectAreaTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType);
@@ -225,7 +225,7 @@ class SpellScript : public _SpellScript
SpellObjectAreaTargetSelectFnType pObjectAreaTargetSelectHandlerScript;
};
- class ObjectTargetSelectHandler : public TargetHook
+ class TC_GAME_API ObjectTargetSelectHandler : public TargetHook
{
public:
ObjectTargetSelectHandler(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType);
@@ -234,7 +234,7 @@ class SpellScript : public _SpellScript
SpellObjectTargetSelectFnType pObjectTargetSelectHandlerScript;
};
- class DestinationTargetSelectHandler : public TargetHook
+ class TC_GAME_API DestinationTargetSelectHandler : public TargetHook
{
public:
DestinationTargetSelectHandler(SpellDestinationTargetSelectFnType _DestinationTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType);
@@ -470,7 +470,7 @@ enum AuraScriptHookType
#define HOOK_AURA_EFFECT_END HOOK_AURA_EFFECT_CALC_SPELLMOD + 1
#define HOOK_AURA_EFFECT_COUNT HOOK_AURA_EFFECT_END - HOOK_AURA_EFFECT_START
*/
-class AuraScript : public _SpellScript
+class TC_GAME_API AuraScript : public _SpellScript
{
// internal use classes & functions
// DO NOT OVERRIDE THESE IN SCRIPTS
@@ -493,7 +493,7 @@ class AuraScript : public _SpellScript
AURASCRIPT_FUNCTION_TYPE_DEFINES(AuraScript)
- class CheckAreaTargetHandler
+ class TC_GAME_API CheckAreaTargetHandler
{
public:
CheckAreaTargetHandler(AuraCheckAreaTargetFnType pHandlerScript);
@@ -501,7 +501,7 @@ class AuraScript : public _SpellScript
private:
AuraCheckAreaTargetFnType pHandlerScript;
};
- class AuraDispelHandler
+ class TC_GAME_API AuraDispelHandler
{
public:
AuraDispelHandler(AuraDispelFnType pHandlerScript);
@@ -509,14 +509,14 @@ class AuraScript : public _SpellScript
private:
AuraDispelFnType pHandlerScript;
};
- class EffectBase : public _SpellScript::EffectAuraNameCheck, public _SpellScript::EffectHook
+ class TC_GAME_API EffectBase : public _SpellScript::EffectAuraNameCheck, public _SpellScript::EffectHook
{
public:
EffectBase(uint8 _effIndex, uint16 _effName);
std::string ToString();
bool CheckEffect(SpellInfo const* spellInfo, uint8 effIndex) override;
};
- class EffectPeriodicHandler : public EffectBase
+ class TC_GAME_API EffectPeriodicHandler : public EffectBase
{
public:
EffectPeriodicHandler(AuraEffectPeriodicFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName);
@@ -524,7 +524,7 @@ class AuraScript : public _SpellScript
private:
AuraEffectPeriodicFnType pEffectHandlerScript;
};
- class EffectUpdatePeriodicHandler : public EffectBase
+ class TC_GAME_API EffectUpdatePeriodicHandler : public EffectBase
{
public:
EffectUpdatePeriodicHandler(AuraEffectUpdatePeriodicFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName);
@@ -532,7 +532,7 @@ class AuraScript : public _SpellScript
private:
AuraEffectUpdatePeriodicFnType pEffectHandlerScript;
};
- class EffectCalcAmountHandler : public EffectBase
+ class TC_GAME_API EffectCalcAmountHandler : public EffectBase
{
public:
EffectCalcAmountHandler(AuraEffectCalcAmountFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName);
@@ -540,7 +540,7 @@ class AuraScript : public _SpellScript
private:
AuraEffectCalcAmountFnType pEffectHandlerScript;
};
- class EffectCalcPeriodicHandler : public EffectBase
+ class TC_GAME_API EffectCalcPeriodicHandler : public EffectBase
{
public:
EffectCalcPeriodicHandler(AuraEffectCalcPeriodicFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName);
@@ -548,7 +548,7 @@ class AuraScript : public _SpellScript
private:
AuraEffectCalcPeriodicFnType pEffectHandlerScript;
};
- class EffectCalcSpellModHandler : public EffectBase
+ class TC_GAME_API EffectCalcSpellModHandler : public EffectBase
{
public:
EffectCalcSpellModHandler(AuraEffectCalcSpellModFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName);
@@ -556,7 +556,7 @@ class AuraScript : public _SpellScript
private:
AuraEffectCalcSpellModFnType pEffectHandlerScript;
};
- class EffectApplyHandler : public EffectBase
+ class TC_GAME_API EffectApplyHandler : public EffectBase
{
public:
EffectApplyHandler(AuraEffectApplicationModeFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName, AuraEffectHandleModes _mode);
@@ -565,7 +565,7 @@ class AuraScript : public _SpellScript
AuraEffectApplicationModeFnType pEffectHandlerScript;
AuraEffectHandleModes mode;
};
- class EffectAbsorbHandler : public EffectBase
+ class TC_GAME_API EffectAbsorbHandler : public EffectBase
{
public:
EffectAbsorbHandler(AuraEffectAbsorbFnType _pEffectHandlerScript, uint8 _effIndex);
@@ -573,7 +573,7 @@ class AuraScript : public _SpellScript
private:
AuraEffectAbsorbFnType pEffectHandlerScript;
};
- class EffectManaShieldHandler : public EffectBase
+ class TC_GAME_API EffectManaShieldHandler : public EffectBase
{
public:
EffectManaShieldHandler(AuraEffectAbsorbFnType _pEffectHandlerScript, uint8 _effIndex);
@@ -581,7 +581,7 @@ class AuraScript : public _SpellScript
private:
AuraEffectAbsorbFnType pEffectHandlerScript;
};
- class EffectSplitHandler : public EffectBase
+ class TC_GAME_API EffectSplitHandler : public EffectBase
{
public:
EffectSplitHandler(AuraEffectSplitFnType _pEffectHandlerScript, uint8 _effIndex);
@@ -589,7 +589,7 @@ class AuraScript : public _SpellScript
private:
AuraEffectSplitFnType pEffectHandlerScript;
};
- class CheckProcHandler
+ class TC_GAME_API CheckProcHandler
{
public:
CheckProcHandler(AuraCheckProcFnType handlerScript);
@@ -597,7 +597,7 @@ class AuraScript : public _SpellScript
private:
AuraCheckProcFnType _HandlerScript;
};
- class AuraProcHandler
+ class TC_GAME_API AuraProcHandler
{
public:
AuraProcHandler(AuraProcFnType handlerScript);
@@ -605,7 +605,7 @@ class AuraScript : public _SpellScript
private:
AuraProcFnType _HandlerScript;
};
- class EffectProcHandler : public EffectBase
+ class TC_GAME_API EffectProcHandler : public EffectBase
{
public:
EffectProcHandler(AuraEffectProcFnType effectHandlerScript, uint8 effIndex, uint16 effName);
@@ -645,7 +645,7 @@ class AuraScript : public _SpellScript
AuraApplication const* m_auraApplication;
bool m_defaultActionPrevented;
- class ScriptStateStore
+ class TC_GAME_API ScriptStateStore
{
public:
AuraApplication const* _auraApplication;
diff --git a/src/server/game/Texts/CreatureTextMgr.cpp b/src/server/game/Texts/CreatureTextMgr.cpp
index 499f0c9cbf0..d8df3310765 100644
--- a/src/server/game/Texts/CreatureTextMgr.cpp
+++ b/src/server/game/Texts/CreatureTextMgr.cpp
@@ -72,6 +72,12 @@ class PlayerTextBuilder
WorldObject const* _target;
};
+CreatureTextMgr* CreatureTextMgr::instance()
+{
+ static CreatureTextMgr instance;
+ return &instance;
+}
+
void CreatureTextMgr::LoadCreatureTexts()
{
uint32 oldMSTime = getMSTime();
diff --git a/src/server/game/Texts/CreatureTextMgr.h b/src/server/game/Texts/CreatureTextMgr.h
index 28fd98f21a8..d7953463a97 100644
--- a/src/server/game/Texts/CreatureTextMgr.h
+++ b/src/server/game/Texts/CreatureTextMgr.h
@@ -75,18 +75,14 @@ typedef std::unordered_map<uint32, CreatureTextHolder> CreatureTextMap; // a
typedef std::map<CreatureTextId, CreatureTextLocale> LocaleCreatureTextMap;
-class CreatureTextMgr
+class TC_GAME_API CreatureTextMgr
{
private:
CreatureTextMgr() { }
~CreatureTextMgr() { }
public:
- static CreatureTextMgr* instance()
- {
- static CreatureTextMgr instance;
- return &instance;
- }
+ static CreatureTextMgr* instance();
void LoadCreatureTexts();
void LoadCreatureTextLocales();
diff --git a/src/server/game/Tickets/TicketMgr.cpp b/src/server/game/Tickets/TicketMgr.cpp
index 1cf68eec9c7..94e4427fe10 100644
--- a/src/server/game/Tickets/TicketMgr.cpp
+++ b/src/server/game/Tickets/TicketMgr.cpp
@@ -284,6 +284,12 @@ void TicketMgr::ResetTickets()
CharacterDatabase.Execute(stmt);
}
+TicketMgr* TicketMgr::instance()
+{
+ static TicketMgr instance;
+ return &instance;
+}
+
void TicketMgr::LoadTickets()
{
uint32 oldMSTime = getMSTime();
diff --git a/src/server/game/Tickets/TicketMgr.h b/src/server/game/Tickets/TicketMgr.h
index 9cc1d20b122..ff2cd656dce 100644
--- a/src/server/game/Tickets/TicketMgr.h
+++ b/src/server/game/Tickets/TicketMgr.h
@@ -84,7 +84,7 @@ enum TicketType
TICKET_TYPE_CHARACTER_DELETED = 2,
};
-class GmTicket
+class TC_GAME_API GmTicket
{
public:
GmTicket();
@@ -181,18 +181,14 @@ private:
};
typedef std::map<uint32, GmTicket*> GmTicketList;
-class TicketMgr
+class TC_GAME_API TicketMgr
{
private:
TicketMgr();
~TicketMgr();
public:
- static TicketMgr* instance()
- {
- static TicketMgr instance;
- return &instance;
- }
+ static TicketMgr* instance();
void LoadTickets();
void LoadSurveys();
diff --git a/src/server/game/Tools/CharacterDatabaseCleaner.h b/src/server/game/Tools/CharacterDatabaseCleaner.h
index ecbd6d0a790..f1e6900a6bb 100644
--- a/src/server/game/Tools/CharacterDatabaseCleaner.h
+++ b/src/server/game/Tools/CharacterDatabaseCleaner.h
@@ -30,20 +30,20 @@ namespace CharacterDatabaseCleaner
CLEANING_FLAG_QUESTSTATUS = 0x10
};
- void CleanDatabase();
+ TC_GAME_API void CleanDatabase();
- void CheckUnique(const char* column, const char* table, bool (*check)(uint32));
+ TC_GAME_API void CheckUnique(const char* column, const char* table, bool (*check)(uint32));
- bool AchievementProgressCheck(uint32 criteria);
- bool SkillCheck(uint32 skill);
- bool SpellCheck(uint32 spell_id);
- bool TalentCheck(uint32 talent_id);
+ TC_GAME_API bool AchievementProgressCheck(uint32 criteria);
+ TC_GAME_API bool SkillCheck(uint32 skill);
+ TC_GAME_API bool SpellCheck(uint32 spell_id);
+ TC_GAME_API bool TalentCheck(uint32 talent_id);
- void CleanCharacterAchievementProgress();
- void CleanCharacterSkills();
- void CleanCharacterSpell();
- void CleanCharacterTalent();
- void CleanCharacterQuestStatus();
+ TC_GAME_API void CleanCharacterAchievementProgress();
+ TC_GAME_API void CleanCharacterSkills();
+ TC_GAME_API void CleanCharacterSpell();
+ TC_GAME_API void CleanCharacterTalent();
+ TC_GAME_API void CleanCharacterQuestStatus();
}
#endif
diff --git a/src/server/game/Tools/PlayerDump.cpp b/src/server/game/Tools/PlayerDump.cpp
index 113fea2ea35..4c5ac1dab5e 100644
--- a/src/server/game/Tools/PlayerDump.cpp
+++ b/src/server/game/Tools/PlayerDump.cpp
@@ -315,10 +315,10 @@ bool PlayerDumpWriter::DumpTable(std::string& dump, ObjectGuid::LowType guid, ch
break;
case DTT_CHARACTER:
{
- if (result->GetFieldCount() <= 68) // avoid crashes on next check
+ if (result->GetFieldCount() <= 73) // avoid crashes on next check
TC_LOG_FATAL("misc", "PlayerDumpWriter::DumpTable - Trying to access non-existing or wrong positioned field (`deleteInfos_Account`) in `characters` table.");
- if (result->Fetch()[68].GetUInt32()) // characters.deleteInfos_Account - if filled error
+ if (result->Fetch()[73].GetUInt32()) // characters.deleteInfos_Account - if filled error
return false;
break;
}
@@ -549,11 +549,11 @@ DumpReturn PlayerDumpReader::LoadDump(std::string const& file, uint32 account, s
ROLLBACK(DUMP_FILE_BROKEN);
const char null[5] = "NULL";
- if (!ChangeNth(line, 69, null)) // characters.deleteInfos_Account
+ if (!ChangeNth(line, 74, null)) // characters.deleteInfos_Account
ROLLBACK(DUMP_FILE_BROKEN);
- if (!ChangeNth(line, 70, null)) // characters.deleteInfos_Name
+ if (!ChangeNth(line, 75, null)) // characters.deleteInfos_Name
ROLLBACK(DUMP_FILE_BROKEN);
- if (!ChangeNth(line, 71, null)) // characters.deleteDate
+ if (!ChangeNth(line, 76, null)) // characters.deleteDate
ROLLBACK(DUMP_FILE_BROKEN);
break;
}
diff --git a/src/server/game/Tools/PlayerDump.h b/src/server/game/Tools/PlayerDump.h
index 95d6ed2d04b..12cafc6ad48 100644
--- a/src/server/game/Tools/PlayerDump.h
+++ b/src/server/game/Tools/PlayerDump.h
@@ -62,7 +62,7 @@ enum DumpReturn
DUMP_CHARACTER_DELETED
};
-class PlayerDump
+class TC_GAME_API PlayerDump
{
public:
typedef std::set<ObjectGuid::LowType> DumpGuidSet;
@@ -72,7 +72,7 @@ class PlayerDump
PlayerDump() { }
};
-class PlayerDumpWriter : public PlayerDump
+class TC_GAME_API PlayerDumpWriter : public PlayerDump
{
public:
PlayerDumpWriter() { }
@@ -90,7 +90,7 @@ class PlayerDumpWriter : public PlayerDump
DumpGuidSet items;
};
-class PlayerDumpReader : public PlayerDump
+class TC_GAME_API PlayerDumpReader : public PlayerDump
{
public:
PlayerDumpReader() { }
diff --git a/src/server/game/Warden/Warden.h b/src/server/game/Warden/Warden.h
index 35ee18d4c02..b0aa496cbe8 100644
--- a/src/server/game/Warden/Warden.h
+++ b/src/server/game/Warden/Warden.h
@@ -92,7 +92,7 @@ struct ClientWardenModule
class WorldSession;
-class Warden
+class TC_GAME_API Warden
{
friend class WardenWin;
friend class WardenMac;
diff --git a/src/server/game/Warden/WardenCheckMgr.cpp b/src/server/game/Warden/WardenCheckMgr.cpp
index 5c4b0fc05b7..13ddae012fe 100644
--- a/src/server/game/Warden/WardenCheckMgr.cpp
+++ b/src/server/game/Warden/WardenCheckMgr.cpp
@@ -189,6 +189,12 @@ void WardenCheckMgr::LoadWardenOverrides()
TC_LOG_INFO("server.loading", ">> Loaded %u warden action overrides.", count);
}
+WardenCheckMgr* WardenCheckMgr::instance()
+{
+ static WardenCheckMgr instance;
+ return &instance;
+}
+
WardenCheck* WardenCheckMgr::GetWardenDataById(uint16 Id)
{
if (Id < CheckStore.size())
diff --git a/src/server/game/Warden/WardenCheckMgr.h b/src/server/game/Warden/WardenCheckMgr.h
index 4107ccc3aff..7349fd5b589 100644
--- a/src/server/game/Warden/WardenCheckMgr.h
+++ b/src/server/game/Warden/WardenCheckMgr.h
@@ -48,18 +48,14 @@ struct WardenCheckResult
BigNumber Result; // MEM_CHECK
};
-class WardenCheckMgr
+class TC_GAME_API WardenCheckMgr
{
private:
WardenCheckMgr();
~WardenCheckMgr();
public:
- static WardenCheckMgr* instance()
- {
- static WardenCheckMgr instance;
- return &instance;
- }
+ static WardenCheckMgr* instance();
// We have a linear key without any gaps, so we use vector for fast access
typedef std::vector<WardenCheck*> CheckContainer;
diff --git a/src/server/game/Warden/WardenMac.h b/src/server/game/Warden/WardenMac.h
index 26a2d86524e..c7435502f63 100644
--- a/src/server/game/Warden/WardenMac.h
+++ b/src/server/game/Warden/WardenMac.h
@@ -28,7 +28,7 @@
class WorldSession;
class Warden;
-class WardenMac : public Warden
+class TC_GAME_API WardenMac : public Warden
{
public:
WardenMac();
diff --git a/src/server/game/Warden/WardenWin.h b/src/server/game/Warden/WardenWin.h
index 4bf1af77c47..b3e6d7c586c 100644
--- a/src/server/game/Warden/WardenWin.h
+++ b/src/server/game/Warden/WardenWin.h
@@ -62,7 +62,7 @@ struct WardenInitModuleRequest
class WorldSession;
class Warden;
-class WardenWin : public Warden
+class TC_GAME_API WardenWin : public Warden
{
public:
WardenWin();
diff --git a/src/server/game/Weather/Weather.cpp b/src/server/game/Weather/Weather.cpp
index f774916f4a5..7ef16e32031 100644
--- a/src/server/game/Weather/Weather.cpp
+++ b/src/server/game/Weather/Weather.cpp
@@ -152,7 +152,7 @@ bool Weather::ReGenerate()
uint32 chance2 = chance1+ m_weatherChances->data[season].snowChance;
uint32 chance3 = chance2+ m_weatherChances->data[season].stormChance;
- uint32 rnd = urand(0, 99);
+ uint32 rnd = urand(1, 100);
if (rnd <= chance1)
m_type = WEATHER_TYPE_RAIN;
else if (rnd <= chance2)
diff --git a/src/server/game/Weather/Weather.h b/src/server/game/Weather/Weather.h
index c1f029d6264..6a770615308 100644
--- a/src/server/game/Weather/Weather.h
+++ b/src/server/game/Weather/Weather.h
@@ -62,7 +62,7 @@ enum WeatherState
};
/// Weather for one zone
-class Weather
+class TC_GAME_API Weather
{
public:
diff --git a/src/server/game/Weather/WeatherMgr.h b/src/server/game/Weather/WeatherMgr.h
index 97c541fd3c0..e3dd4ac9ec4 100644
--- a/src/server/game/Weather/WeatherMgr.h
+++ b/src/server/game/Weather/WeatherMgr.h
@@ -30,15 +30,15 @@ class Player;
namespace WeatherMgr
{
- void LoadWeatherData();
+ TC_GAME_API void LoadWeatherData();
- Weather* FindWeather(uint32 id);
- Weather* AddWeather(uint32 zone_id);
- void RemoveWeather(uint32 zone_id);
+ TC_GAME_API Weather* FindWeather(uint32 id);
+ TC_GAME_API Weather* AddWeather(uint32 zone_id);
+ TC_GAME_API void RemoveWeather(uint32 zone_id);
- void SendFineWeatherUpdateToPlayer(Player* player);
+ TC_GAME_API void SendFineWeatherUpdateToPlayer(Player* player);
- void Update(uint32 diff);
+ TC_GAME_API void Update(uint32 diff);
}
#endif
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 289a4d47666..cc699e26d60 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -38,6 +38,7 @@
#include "DatabaseEnv.h"
#include "DisableMgr.h"
#include "GameEventMgr.h"
+#include "GameObjectModel.h"
#include "GridNotifiersImpl.h"
#include "GroupMgr.h"
#include "GuildMgr.h"
@@ -66,17 +67,18 @@
#include "WorldSession.h"
-std::atomic<bool> World::m_stopEvent(false);
-uint8 World::m_ExitCode = SHUTDOWN_EXIT_CODE;
-std::atomic<uint32> World::m_worldLoopCounter(0);
+TC_GAME_API std::atomic<bool> World::m_stopEvent(false);
+TC_GAME_API uint8 World::m_ExitCode = SHUTDOWN_EXIT_CODE;
-float World::m_MaxVisibleDistanceOnContinents = DEFAULT_VISIBILITY_DISTANCE;
-float World::m_MaxVisibleDistanceInInstances = DEFAULT_VISIBILITY_INSTANCE;
-float World::m_MaxVisibleDistanceInBGArenas = DEFAULT_VISIBILITY_BGARENAS;
+TC_GAME_API std::atomic<uint32> World::m_worldLoopCounter(0);
-int32 World::m_visibility_notify_periodOnContinents = DEFAULT_VISIBILITY_NOTIFY_PERIOD;
-int32 World::m_visibility_notify_periodInInstances = DEFAULT_VISIBILITY_NOTIFY_PERIOD;
-int32 World::m_visibility_notify_periodInBGArenas = DEFAULT_VISIBILITY_NOTIFY_PERIOD;
+TC_GAME_API float World::m_MaxVisibleDistanceOnContinents = DEFAULT_VISIBILITY_DISTANCE;
+TC_GAME_API float World::m_MaxVisibleDistanceInInstances = DEFAULT_VISIBILITY_INSTANCE;
+TC_GAME_API float World::m_MaxVisibleDistanceInBGArenas = DEFAULT_VISIBILITY_BGARENAS;
+
+TC_GAME_API int32 World::m_visibility_notify_periodOnContinents = DEFAULT_VISIBILITY_NOTIFY_PERIOD;
+TC_GAME_API int32 World::m_visibility_notify_periodInInstances = DEFAULT_VISIBILITY_NOTIFY_PERIOD;
+TC_GAME_API int32 World::m_visibility_notify_periodInBGArenas = DEFAULT_VISIBILITY_NOTIFY_PERIOD;
/// World constructor
World::World()
@@ -139,6 +141,12 @@ World::~World()
/// @todo free addSessQueue
}
+World* World::instance()
+{
+ static World instance;
+ return &instance;
+}
+
/// Find a player in a specified zone
Player* World::FindPlayerInZone(uint32 zone)
{
@@ -592,6 +600,18 @@ void World::LoadConfigSettings(bool reload)
m_bool_configs[CONFIG_PRESERVE_CUSTOM_CHANNELS] = sConfigMgr->GetBoolDefault("PreserveCustomChannels", false);
m_int_configs[CONFIG_PRESERVE_CUSTOM_CHANNEL_DURATION] = sConfigMgr->GetIntDefault("PreserveCustomChannelDuration", 14);
m_bool_configs[CONFIG_GRID_UNLOAD] = sConfigMgr->GetBoolDefault("GridUnload", true);
+ m_bool_configs[CONFIG_BASEMAP_LOAD_GRIDS] = sConfigMgr->GetBoolDefault("BaseMapLoadAllGrids", false);
+ if (m_bool_configs[CONFIG_BASEMAP_LOAD_GRIDS] && m_bool_configs[CONFIG_GRID_UNLOAD])
+ {
+ TC_LOG_ERROR("server.loading", "BaseMapLoadAllGrids enabled, but GridUnload also enabled. GridUnload must be disabled to enable base map pre-loading. Base map pre-loading disabled");
+ m_bool_configs[CONFIG_BASEMAP_LOAD_GRIDS] = false;
+ }
+ m_bool_configs[CONFIG_INSTANCEMAP_LOAD_GRIDS] = sConfigMgr->GetBoolDefault("InstanceMapLoadAllGrids", false);
+ if (m_bool_configs[CONFIG_INSTANCEMAP_LOAD_GRIDS] && m_bool_configs[CONFIG_GRID_UNLOAD])
+ {
+ TC_LOG_ERROR("server.loading", "InstanceMapLoadAllGrids enabled, but GridUnload also enabled. GridUnload must be disabled to enable instance map pre-loading. Instance map pre-loading disabled");
+ m_bool_configs[CONFIG_INSTANCEMAP_LOAD_GRIDS] = false;
+ }
m_int_configs[CONFIG_INTERVAL_SAVE] = sConfigMgr->GetIntDefault("PlayerSaveInterval", 15 * MINUTE * IN_MILLISECONDS);
m_int_configs[CONFIG_INTERVAL_DISCONNECT_TOLERANCE] = sConfigMgr->GetIntDefault("DisconnectToleranceInterval", 0);
m_bool_configs[CONFIG_STATS_SAVE_ONLY_ON_LOGOUT] = sConfigMgr->GetBoolDefault("PlayerSave.Stats.SaveOnlyOnLogout", true);
@@ -1003,7 +1023,7 @@ void World::LoadConfigSettings(bool reload)
m_bool_configs[CONFIG_DETECT_POS_COLLISION] = sConfigMgr->GetBoolDefault("DetectPosCollision", true);
m_bool_configs[CONFIG_RESTRICTED_LFG_CHANNEL] = sConfigMgr->GetBoolDefault("Channel.RestrictedLfg", true);
- m_bool_configs[CONFIG_TALENTS_INSPECTING] = sConfigMgr->GetBoolDefault("TalentsInspecting", true);
+ m_int_configs[CONFIG_TALENTS_INSPECTING] = sConfigMgr->GetIntDefault("TalentsInspecting", 1);
m_bool_configs[CONFIG_CHAT_FAKE_MESSAGE_PREVENTING] = sConfigMgr->GetBoolDefault("ChatFakeMessagePreventing", false);
m_int_configs[CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY] = sConfigMgr->GetIntDefault("ChatStrictLinkChecking.Severity", 0);
m_int_configs[CONFIG_CHAT_STRICT_LINK_CHECKING_KICK] = sConfigMgr->GetIntDefault("ChatStrictLinkChecking.Kick", 0);
@@ -1305,8 +1325,6 @@ void World::LoadConfigSettings(bool reload)
sScriptMgr->OnConfigLoad(reload);
}
-extern void LoadGameObjectModelList(std::string const& dataPath);
-
/// Initialize the World
void World::SetInitialWorldSettings()
{
@@ -1369,7 +1387,7 @@ void World::SetInitialWorldSettings()
uint32 server_type = IsFFAPvPRealm() ? uint32(REALM_TYPE_PVP) : getIntConfig(CONFIG_GAME_TYPE);
uint32 realm_zone = getIntConfig(CONFIG_REALM_ZONE);
- LoginDatabase.PExecute("UPDATE realmlist SET icon = %u, timezone = %u WHERE id = '%d'", server_type, realm_zone, realmID); // One-time query
+ LoginDatabase.PExecute("UPDATE realmlist SET icon = %u, timezone = %u WHERE id = '%d'", server_type, realm_zone, realm.Id.Realm); // One-time query
///- Load the DBC files
TC_LOG_INFO("server.loading", "Initialize data stores...");
@@ -1790,7 +1808,7 @@ void World::SetInitialWorldSettings()
m_startTime = m_gameTime;
LoginDatabase.PExecute("INSERT INTO uptime (realmid, starttime, uptime, revision) VALUES(%u, %u, 0, '%s')",
- realmID, uint32(m_startTime), GitRevision::GetFullVersion()); // One-time query
+ realm.Id.Realm, uint32(m_startTime), GitRevision::GetFullVersion()); // One-time query
m_timers[WUPDATE_WEATHERS].SetInterval(1*IN_MILLISECONDS);
m_timers[WUPDATE_AUCTIONS].SetInterval(MINUTE*IN_MILLISECONDS);
@@ -1888,6 +1906,19 @@ void World::SetInitialWorldSettings()
LoadCharacterInfoStore();
+ // Preload all cells, if required for the base maps
+ if (sWorld->getBoolConfig(CONFIG_BASEMAP_LOAD_GRIDS))
+ {
+ sMapMgr->DoForAllMaps([](Map* map)
+ {
+ if (!map->Instanceable())
+ {
+ TC_LOG_INFO("server.loading", "Pre-loading base map data for map %u", map->GetId());
+ map->LoadAllCells();
+ }
+ });
+ }
+
uint32 startupDuration = GetMSTimeDiffToNow(startupBegin);
TC_LOG_INFO("server.worldserver", "World initialized in %u minutes %u seconds", (startupDuration / 60000), ((startupDuration % 60000) / 1000));
@@ -2103,7 +2134,7 @@ void World::Update(uint32 diff)
stmt->setUInt32(0, tmpDiff);
stmt->setUInt16(1, uint16(maxOnlinePlayers));
- stmt->setUInt32(2, realmID);
+ stmt->setUInt32(2, realm.Id.Realm);
stmt->setUInt32(3, uint32(m_startTime));
LoginDatabase.Execute(stmt);
@@ -2826,13 +2857,13 @@ void World::_UpdateRealmCharCount(PreparedQueryResult resultCharCount)
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_REALM_CHARACTERS_BY_REALM);
stmt->setUInt32(0, accountId);
- stmt->setUInt32(1, realmID);
+ stmt->setUInt32(1, realm.Id.Realm);
LoginDatabase.Execute(stmt);
stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_REALM_CHARACTERS);
stmt->setUInt8(0, charCount);
stmt->setUInt32(1, accountId);
- stmt->setUInt32(2, realmID);
+ stmt->setUInt32(2, realm.Id.Realm);
LoginDatabase.Execute(stmt);
}
}
@@ -2960,7 +2991,7 @@ void World::ResetDailyQuests()
void World::LoadDBAllowedSecurityLevel()
{
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST_SECURITY_LEVEL);
- stmt->setInt32(0, int32(realmID));
+ stmt->setInt32(0, int32(realm.Id.Realm));
PreparedQueryResult result = LoginDatabase.Query(stmt);
if (result)
@@ -3290,3 +3321,4 @@ void World::RemoveOldCorpses()
m_timers[WUPDATE_CORPSES].SetCurrent(m_timers[WUPDATE_CORPSES].GetInterval());
}
+Realm realm;
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index 00b244c9efb..d849705dc65 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -29,6 +29,7 @@
#include "SharedDefines.h"
#include "QueryResult.h"
#include "Callback.h"
+#include "Realm/Realm.h"
#include <atomic>
#include <map>
@@ -113,7 +114,6 @@ enum WorldBoolConfigs
CONFIG_QUEST_IGNORE_RAID,
CONFIG_DETECT_POS_COLLISION,
CONFIG_RESTRICTED_LFG_CHANNEL,
- CONFIG_TALENTS_INSPECTING,
CONFIG_CHAT_FAKE_MESSAGE_PREVENTING,
CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVP,
CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVE,
@@ -166,6 +166,8 @@ enum WorldBoolConfigs
CONFIG_CALCULATE_GAMEOBJECT_ZONE_AREA_DATA,
CONFIG_RESET_DUEL_COOLDOWNS,
CONFIG_RESET_DUEL_HEALTH_MANA,
+ CONFIG_BASEMAP_LOAD_GRIDS,
+ CONFIG_INSTANCEMAP_LOAD_GRIDS,
BOOL_CONFIG_VALUE_COUNT
};
@@ -358,6 +360,7 @@ enum WorldIntConfigs
CONFIG_NO_GRAY_AGGRO_BELOW,
CONFIG_AUCTION_GETALL_DELAY,
CONFIG_AUCTION_SEARCH_DELAY,
+ CONFIG_TALENTS_INSPECTING,
INT_CONFIG_VALUE_COUNT
};
@@ -446,18 +449,6 @@ enum BillingPlanFlags
SESSION_ENABLE_CAIS = 0x80
};
-/// Type of server, this is values from second column of Cfg_Configs.dbc
-enum RealmType
-{
- REALM_TYPE_NORMAL = 0,
- REALM_TYPE_PVP = 1,
- REALM_TYPE_NORMAL2 = 4,
- REALM_TYPE_RP = 6,
- REALM_TYPE_RPPVP = 8,
- REALM_TYPE_FFA_PVP = 16 // custom, free for all pvp mode like arena PvP in all zones except rest activated places and sanctuaries
- // replaced by REALM_PVP in realm list
-};
-
enum RealmZone
{
REALM_ZONE_UNKNOWN = 0, // any language
@@ -546,14 +537,10 @@ struct CharacterInfo
};
/// The World
-class World
+class TC_GAME_API World
{
public:
- static World* instance()
- {
- static World instance;
- return &instance;
- }
+ static World* instance();
static std::atomic<uint32> m_worldLoopCounter;
@@ -882,8 +869,9 @@ class World
std::deque<std::future<PreparedQueryResult>> m_realmCharCallbacks;
};
-extern uint32 realmID;
+TC_GAME_API extern Realm realm;
#define sWorld World::instance()
+
#endif
/// @}
diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt
index a15b6f8ad07..d12c44c447c 100644
--- a/src/server/scripts/CMakeLists.txt
+++ b/src/server/scripts/CMakeLists.txt
@@ -10,136 +10,67 @@
# Enable precompiled headers when using the GCC compiler.
-if (USE_SCRIPTPCH)
- set(scripts_STAT_PCH_HDR PrecompiledHeaders/ScriptPCH.h)
- set(scripts_STAT_PCH_SRC PrecompiledHeaders/ScriptPCH.cpp)
-endif ()
-
message(STATUS "SCRIPT PREPARATIONS")
-include(Spells/CMakeLists.txt)
-include(Commands/CMakeLists.txt)
+macro(PrepareScripts name out)
+ file(GLOB_RECURSE found
+ ${name}/*.h
+ ${name}/*.cpp
+ )
+ list(APPEND ${out} ${found})
+ message(STATUS " -> Prepared: ${name}")
+endmacro(PrepareScripts)
-set(scripts_STAT_SRCS
- ${scripts_STAT_SRCS}
- ../game/AI/ScriptedAI/ScriptedEscortAI.cpp
- ../game/AI/ScriptedAI/ScriptedCreature.cpp
- ../game/AI/ScriptedAI/ScriptedFollowerAI.cpp
- ../game/Maps/AreaBoundary.cpp
-)
+PrepareScripts(Spells PRIVATE_SOURCES)
+PrepareScripts(Commands PRIVATE_SOURCES)
if(SCRIPTS)
- include(Custom/CMakeLists.txt)
- include(World/CMakeLists.txt)
- include(OutdoorPvP/CMakeLists.txt)
- include(EasternKingdoms/CMakeLists.txt)
- include(Kalimdor/CMakeLists.txt)
- include(Outland/CMakeLists.txt)
- include(Northrend/CMakeLists.txt)
- include(Events/CMakeLists.txt)
- include(Pet/CMakeLists.txt)
+ PrepareScripts(Custom PRIVATE_SOURCES)
+ PrepareScripts(World PRIVATE_SOURCES)
+ PrepareScripts(OutdoorPvP PRIVATE_SOURCES)
+ PrepareScripts(EasternKingdoms PRIVATE_SOURCES)
+ PrepareScripts(Kalimdor PRIVATE_SOURCES)
+ PrepareScripts(Outland PRIVATE_SOURCES)
+ PrepareScripts(Northrend PRIVATE_SOURCES)
+ PrepareScripts(Events PRIVATE_SOURCES)
+ PrepareScripts(Pet PRIVATE_SOURCES)
endif()
message(STATUS "SCRIPT PREPARATION COMPLETE")
message("")
-include_directories(
- ${CMAKE_SOURCE_DIR}/dep/cppformat
- ${CMAKE_SOURCE_DIR}/dep/g3dlite/include
- ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour/Include
- ${CMAKE_SOURCE_DIR}/src/common/
- ${CMAKE_SOURCE_DIR}/src/common/Collision
- ${CMAKE_SOURCE_DIR}/src/common/Collision/Management
- ${CMAKE_SOURCE_DIR}/src/common/Collision/Maps
- ${CMAKE_SOURCE_DIR}/src/common/Collision/Models
- ${CMAKE_SOURCE_DIR}/src/common/Configuration
- ${CMAKE_SOURCE_DIR}/src/common/Debugging
- ${CMAKE_SOURCE_DIR}/src/common/Logging
- ${CMAKE_SOURCE_DIR}/src/common/Threading
- ${CMAKE_SOURCE_DIR}/src/common/Utilities
- ${CMAKE_SOURCE_DIR}/src/server/database/Database
- ${CMAKE_SOURCE_DIR}/src/server/game/Accounts
- ${CMAKE_SOURCE_DIR}/src/server/game/Achievements
- ${CMAKE_SOURCE_DIR}/src/server/game/Addons
- ${CMAKE_SOURCE_DIR}/src/server/game/AI
- ${CMAKE_SOURCE_DIR}/src/server/game/AI/CoreAI
- ${CMAKE_SOURCE_DIR}/src/server/game/AI/ScriptedAI
- ${CMAKE_SOURCE_DIR}/src/server/game/AI/SmartScripts
- ${CMAKE_SOURCE_DIR}/src/server/game/AuctionHouse
- ${CMAKE_SOURCE_DIR}/src/server/game/AuctionHouseBot
- ${CMAKE_SOURCE_DIR}/src/server/game/Battlefield
- ${CMAKE_SOURCE_DIR}/src/server/game/Battlefield/Zones
- ${CMAKE_SOURCE_DIR}/src/server/game/Battlegrounds
- ${CMAKE_SOURCE_DIR}/src/server/game/Battlegrounds/Zones
- ${CMAKE_SOURCE_DIR}/src/server/game/Chat
- ${CMAKE_SOURCE_DIR}/src/server/game/Chat/Channels
- ${CMAKE_SOURCE_DIR}/src/server/game/Combat
- ${CMAKE_SOURCE_DIR}/src/server/game/Conditions
- ${CMAKE_SOURCE_DIR}/src/server/game/DataStores
- ${CMAKE_SOURCE_DIR}/src/server/game/DungeonFinding
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Corpse
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Creature
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/DynamicObject
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/GameObject
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Item
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Item/Container
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Object
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Object/Updates
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Pet
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Player
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Transport
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Unit
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Vehicle
- ${CMAKE_SOURCE_DIR}/src/server/game/Events
- ${CMAKE_SOURCE_DIR}/src/server/game/Globals
- ${CMAKE_SOURCE_DIR}/src/server/game/Grids
- ${CMAKE_SOURCE_DIR}/src/server/game/Grids/Cells
- ${CMAKE_SOURCE_DIR}/src/server/game/Grids/Notifiers
- ${CMAKE_SOURCE_DIR}/src/server/game/Groups
- ${CMAKE_SOURCE_DIR}/src/server/game/Guilds
- ${CMAKE_SOURCE_DIR}/src/server/game/Handlers
- ${CMAKE_SOURCE_DIR}/src/server/game/Instances
- ${CMAKE_SOURCE_DIR}/src/server/game/Loot
- ${CMAKE_SOURCE_DIR}/src/server/game/Mails
- ${CMAKE_SOURCE_DIR}/src/server/game/Maps
- ${CMAKE_SOURCE_DIR}/src/server/game/Miscellaneous
- ${CMAKE_SOURCE_DIR}/src/server/game/Movement
- ${CMAKE_SOURCE_DIR}/src/server/game/Movement/MovementGenerators
- ${CMAKE_SOURCE_DIR}/src/server/game/Movement/Spline
- ${CMAKE_SOURCE_DIR}/src/server/game/Movement/Waypoints
- ${CMAKE_SOURCE_DIR}/src/server/game/OutdoorPvP
- ${CMAKE_SOURCE_DIR}/src/server/game/Pools
- ${CMAKE_SOURCE_DIR}/src/server/game/Quests
- ${CMAKE_SOURCE_DIR}/src/server/game/Reputation
- ${CMAKE_SOURCE_DIR}/src/server/game/Scripting
- ${CMAKE_SOURCE_DIR}/src/server/game/Server
- ${CMAKE_SOURCE_DIR}/src/server/game/Server/Protocol
- ${CMAKE_SOURCE_DIR}/src/server/game/Skills
- ${CMAKE_SOURCE_DIR}/src/server/game/Spells
- ${CMAKE_SOURCE_DIR}/src/server/game/Spells/Auras
- ${CMAKE_SOURCE_DIR}/src/server/game/Texts
- ${CMAKE_SOURCE_DIR}/src/server/game/Tickets
- ${CMAKE_SOURCE_DIR}/src/server/game/Tools
- ${CMAKE_SOURCE_DIR}/src/server/game/Warden
- ${CMAKE_SOURCE_DIR}/src/server/game/Weather
- ${CMAKE_SOURCE_DIR}/src/server/game/World
- ${CMAKE_SOURCE_DIR}/src/server/shared
- ${CMAKE_SOURCE_DIR}/src/server/shared/DataStores
- ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic
- ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference
- ${CMAKE_SOURCE_DIR}/src/server/shared/Packets
- ${MYSQL_INCLUDE_DIR}
- ${VALGRIND_INCLUDE_DIR}
-)
+list(APPEND PRIVATE_SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/ScriptLoader.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/ScriptLoader.cpp)
+
+if (USE_SCRIPTPCH)
+ set(PRIVATE_PCH_HEADER PrecompiledHeaders/ScriptPCH.h)
+ set(PRIVATE_PCH_SOURCE PrecompiledHeaders/ScriptPCH.cpp)
+endif ()
GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
add_library(scripts STATIC
- ${scripts_STAT_SRCS}
- ${scripts_STAT_PCH_SRC}
+ ${PRIVATE_SOURCES}
+ ${PRIVATE_PCH_SOURCE}
)
+target_include_directories(scripts
+ PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ PRIVATE
+ ${CMAKE_CURRENT_BINARY_DIR})
+
+target_link_libraries(scripts
+ PUBLIC
+ game)
+
+set_target_properties(scripts
+ PROPERTIES
+ FOLDER
+ "server")
+
# Generate precompiled header
if (USE_SCRIPTPCH)
- add_cxx_pch(scripts ${scripts_STAT_PCH_HDR} ${scripts_STAT_PCH_SRC})
+ add_cxx_pch(scripts ${PRIVATE_PCH_HEADER} ${PRIVATE_PCH_SOURCE})
endif()
diff --git a/src/server/scripts/Commands/CMakeLists.txt b/src/server/scripts/Commands/CMakeLists.txt
deleted file mode 100644
index d4d75cd175f..00000000000
--- a/src/server/scripts/Commands/CMakeLists.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
-#
-# This file is free software; as a special exception the author gives
-# unlimited permission to copy and/or distribute it, with or without
-# modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-file(GLOB_RECURSE sources_Commands Commands/*.cpp Commands/*.h)
-
-set(scripts_STAT_SRCS
- ${scripts_STAT_SRCS}
- ${sources_Commands}
-)
-
-message(" -> Prepared: Commands")
diff --git a/src/server/scripts/Commands/cs_account.cpp b/src/server/scripts/Commands/cs_account.cpp
index f25e91ee3e6..6ffb92d9684 100644
--- a/src/server/scripts/Commands/cs_account.cpp
+++ b/src/server/scripts/Commands/cs_account.cpp
@@ -124,7 +124,7 @@ public:
AccountOpResult result = sAccountMgr->CreateAccount(std::string(accountName), std::string(password), email);
switch (result)
{
- case AOR_OK:
+ case AccountOpResult::AOR_OK:
handler->PSendSysMessage(LANG_ACCOUNT_CREATED, accountName);
if (handler->GetSession())
{
@@ -134,15 +134,15 @@ public:
accountName, email.c_str());
}
break;
- case AOR_NAME_TOO_LONG:
+ case AccountOpResult::AOR_NAME_TOO_LONG:
handler->SendSysMessage(LANG_ACCOUNT_TOO_LONG);
handler->SetSentErrorMessage(true);
return false;
- case AOR_NAME_ALREADY_EXIST:
+ case AccountOpResult::AOR_NAME_ALREADY_EXIST:
handler->SendSysMessage(LANG_ACCOUNT_ALREADY_EXIST);
handler->SetSentErrorMessage(true);
return false;
- case AOR_DB_INTERNAL_ERROR:
+ case AccountOpResult::AOR_DB_INTERNAL_ERROR:
handler->PSendSysMessage(LANG_ACCOUNT_NOT_CREATED_SQL_ERROR, accountName);
handler->SetSentErrorMessage(true);
return false;
@@ -168,7 +168,7 @@ public:
return false;
std::string accountName = account;
- if (!AccountMgr::normalizeString(accountName))
+ if (!Utf8ToUpperOnlyLatin(accountName))
{
handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str());
handler->SetSentErrorMessage(true);
@@ -192,14 +192,14 @@ public:
AccountOpResult result = AccountMgr::DeleteAccount(accountId);
switch (result)
{
- case AOR_OK:
+ case AccountOpResult::AOR_OK:
handler->PSendSysMessage(LANG_ACCOUNT_DELETED, accountName.c_str());
break;
- case AOR_NAME_NOT_EXIST:
+ case AccountOpResult::AOR_NAME_NOT_EXIST:
handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str());
handler->SetSentErrorMessage(true);
return false;
- case AOR_DB_INTERNAL_ERROR:
+ case AccountOpResult::AOR_DB_INTERNAL_ERROR:
handler->PSendSysMessage(LANG_ACCOUNT_NOT_DELETED_SQL_ERROR, accountName.c_str());
handler->SetSentErrorMessage(true);
return false;
@@ -415,7 +415,7 @@ public:
AccountOpResult result = AccountMgr::ChangeEmail(handler->GetSession()->GetAccountId(), std::string(email));
switch (result)
{
- case AOR_OK:
+ case AccountOpResult::AOR_OK:
handler->SendSysMessage(LANG_COMMAND_EMAIL);
sScriptMgr->OnEmailChange(handler->GetSession()->GetAccountId());
TC_LOG_INFO("entities.player.character", "Account: %u (IP: %s) Character:[%s] (GUID: %u) Changed Email from [%s] to [%s].",
@@ -423,7 +423,7 @@ public:
handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUID().GetCounter(),
oldEmail, email);
break;
- case AOR_EMAIL_TOO_LONG:
+ case AccountOpResult::AOR_EMAIL_TOO_LONG:
handler->SendSysMessage(LANG_EMAIL_TOO_LONG);
sScriptMgr->OnFailedEmailChange(handler->GetSession()->GetAccountId());
handler->SetSentErrorMessage(true);
@@ -505,14 +505,14 @@ public:
AccountOpResult result = AccountMgr::ChangePassword(handler->GetSession()->GetAccountId(), std::string(newPassword));
switch (result)
{
- case AOR_OK:
+ case AccountOpResult::AOR_OK:
handler->SendSysMessage(LANG_COMMAND_PASSWORD);
sScriptMgr->OnPasswordChange(handler->GetSession()->GetAccountId());
TC_LOG_INFO("entities.player.character", "Account: %u (IP: %s) Character:[%s] (GUID: %u) Changed Password.",
handler->GetSession()->GetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(),
handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUID().GetCounter());
break;
- case AOR_PASS_TOO_LONG:
+ case AccountOpResult::AOR_PASS_TOO_LONG:
handler->SendSysMessage(LANG_PASSWORD_TOO_LONG);
sScriptMgr->OnFailedPasswordChange(handler->GetSession()->GetAccountId());
handler->SetSentErrorMessage(true);
@@ -592,7 +592,7 @@ public:
{
///- Convert Account name to Upper Format
accountName = account;
- if (!AccountMgr::normalizeString(accountName))
+ if (!Utf8ToUpperOnlyLatin(accountName))
{
handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str());
handler->SetSentErrorMessage(true);
@@ -662,7 +662,7 @@ public:
if (isAccountNameGiven)
{
targetAccountName = arg1;
- if (!AccountMgr::normalizeString(targetAccountName) || !AccountMgr::GetId(targetAccountName))
+ if (!Utf8ToUpperOnlyLatin(targetAccountName) || !AccountMgr::GetId(targetAccountName))
{
handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, targetAccountName.c_str());
handler->SetSentErrorMessage(true);
@@ -750,7 +750,7 @@ public:
return false;
std::string accountName = account;
- if (!AccountMgr::normalizeString(accountName))
+ if (!Utf8ToUpperOnlyLatin(accountName))
{
handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str());
handler->SetSentErrorMessage(true);
@@ -781,14 +781,14 @@ public:
switch (result)
{
- case AOR_OK:
+ case AccountOpResult::AOR_OK:
handler->SendSysMessage(LANG_COMMAND_PASSWORD);
break;
- case AOR_NAME_NOT_EXIST:
+ case AccountOpResult::AOR_NAME_NOT_EXIST:
handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str());
handler->SetSentErrorMessage(true);
return false;
- case AOR_PASS_TOO_LONG:
+ case AccountOpResult::AOR_PASS_TOO_LONG:
handler->SendSysMessage(LANG_PASSWORD_TOO_LONG);
handler->SetSentErrorMessage(true);
return false;
@@ -819,7 +819,7 @@ public:
}
std::string accountName = account;
- if (!AccountMgr::normalizeString(accountName))
+ if (!Utf8ToUpperOnlyLatin(accountName))
{
handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str());
handler->SetSentErrorMessage(true);
@@ -849,16 +849,16 @@ public:
AccountOpResult result = AccountMgr::ChangeEmail(targetAccountId, email);
switch (result)
{
- case AOR_OK:
+ case AccountOpResult::AOR_OK:
handler->SendSysMessage(LANG_COMMAND_EMAIL);
TC_LOG_INFO("entities.player.character", "ChangeEmail: Account %s [Id: %u] had it's email changed to %s.",
accountName.c_str(), targetAccountId, email);
break;
- case AOR_NAME_NOT_EXIST:
+ case AccountOpResult::AOR_NAME_NOT_EXIST:
handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str());
handler->SetSentErrorMessage(true);
return false;
- case AOR_EMAIL_TOO_LONG:
+ case AccountOpResult::AOR_EMAIL_TOO_LONG:
handler->SendSysMessage(LANG_EMAIL_TOO_LONG);
handler->SetSentErrorMessage(true);
return false;
@@ -895,7 +895,7 @@ public:
}
std::string accountName = account;
- if (!AccountMgr::normalizeString(accountName))
+ if (!Utf8ToUpperOnlyLatin(accountName))
{
handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str());
handler->SetSentErrorMessage(true);
@@ -925,16 +925,16 @@ public:
AccountOpResult result = AccountMgr::ChangeRegEmail(targetAccountId, email);
switch (result)
{
- case AOR_OK:
+ case AccountOpResult::AOR_OK:
handler->SendSysMessage(LANG_COMMAND_EMAIL);
TC_LOG_INFO("entities.player.character", "ChangeRegEmail: Account %s [Id: %u] had it's Registration Email changed to %s.",
accountName.c_str(), targetAccountId, email);
break;
- case AOR_NAME_NOT_EXIST:
+ case AccountOpResult::AOR_NAME_NOT_EXIST:
handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str());
handler->SetSentErrorMessage(true);
return false;
- case AOR_EMAIL_TOO_LONG:
+ case AccountOpResult::AOR_EMAIL_TOO_LONG:
handler->SendSysMessage(LANG_EMAIL_TOO_LONG);
handler->SetSentErrorMessage(true);
return false;
diff --git a/src/server/scripts/Commands/cs_ahbot.cpp b/src/server/scripts/Commands/cs_ahbot.cpp
index 65e90394261..47553d085b1 100644
--- a/src/server/scripts/Commands/cs_ahbot.cpp
+++ b/src/server/scripts/Commands/cs_ahbot.cpp
@@ -33,7 +33,7 @@ class ahbot_commandscript : public CommandScript
public:
ahbot_commandscript(): CommandScript("ahbot_commandscript") {}
- std::vector<ChatCommand> GetCommands() const
+ std::vector<ChatCommand> GetCommands() const override
{
static std::vector<ChatCommand> ahbotItemsAmountCommandTable =
{
diff --git a/src/server/scripts/Commands/cs_ban.cpp b/src/server/scripts/Commands/cs_ban.cpp
index 4a1bf71e1d8..ba512dbf8eb 100644
--- a/src/server/scripts/Commands/cs_ban.cpp
+++ b/src/server/scripts/Commands/cs_ban.cpp
@@ -171,7 +171,7 @@ public:
switch (mode)
{
case BAN_ACCOUNT:
- if (!AccountMgr::normalizeString(nameOrIP))
+ if (!Utf8ToUpperOnlyLatin(nameOrIP))
{
handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, nameOrIP.c_str());
handler->SetSentErrorMessage(true);
@@ -244,7 +244,7 @@ public:
return false;
std::string accountName = nameStr;
- if (!AccountMgr::normalizeString(accountName))
+ if (!Utf8ToUpperOnlyLatin(accountName))
{
handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str());
handler->SetSentErrorMessage(true);
@@ -712,7 +712,7 @@ public:
switch (mode)
{
case BAN_ACCOUNT:
- if (!AccountMgr::normalizeString(nameOrIP))
+ if (!Utf8ToUpperOnlyLatin(nameOrIP))
{
handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, nameOrIP.c_str());
handler->SetSentErrorMessage(true);
diff --git a/src/server/scripts/Commands/cs_character.cpp b/src/server/scripts/Commands/cs_character.cpp
index e048aabd4d7..9557d182df1 100644
--- a/src/server/scripts/Commands/cs_character.cpp
+++ b/src/server/scripts/Commands/cs_character.cpp
@@ -133,7 +133,7 @@ public:
info.name = fields[1].GetString();
info.accountId = fields[2].GetUInt32();
- // account name will be empty for not existed account
+ // account name will be empty for nonexisting account
AccountMgr::GetName(info.accountId, info.accountName);
info.deleteDate = time_t(fields[3].GetUInt32());
foundList.push_back(info);
@@ -169,11 +169,11 @@ public:
if (!handler->GetSession())
handler->PSendSysMessage(LANG_CHARACTER_DELETED_LIST_LINE_CONSOLE,
- itr->guid.GetCounter(), itr->name.c_str(), itr->accountName.empty() ? "<Not existed>" : itr->accountName.c_str(),
+ itr->guid.GetCounter(), itr->name.c_str(), itr->accountName.empty() ? "<Not existing>" : itr->accountName.c_str(),
itr->accountId, dateStr.c_str());
else
handler->PSendSysMessage(LANG_CHARACTER_DELETED_LIST_LINE_CHAT,
- itr->guid.GetCounter(), itr->name.c_str(), itr->accountName.empty() ? "<Not existed>" : itr->accountName.c_str(),
+ itr->guid.GetCounter(), itr->name.c_str(), itr->accountName.empty() ? "<Not existing>" : itr->accountName.c_str(),
itr->accountId, dateStr.c_str());
}
@@ -193,7 +193,7 @@ public:
*/
static void HandleCharacterDeletedRestoreHelper(DeletedInfo const& delInfo, ChatHandler* handler)
{
- if (delInfo.accountName.empty()) // account not exist
+ if (delInfo.accountName.empty()) // account does not exist
{
handler->PSendSysMessage(LANG_CHARACTER_DELETED_SKIP_ACCOUNT, delInfo.name.c_str(), delInfo.guid.GetCounter(), delInfo.accountId);
return;
@@ -660,7 +660,7 @@ public:
if (newCharName.empty())
{
- // Drop not existed account cases
+ // Drop nonexisting account cases
for (DeletedInfoList::iterator itr = foundList.begin(); itr != foundList.end(); ++itr)
HandleCharacterDeletedRestoreHelper(*itr, handler);
}
@@ -810,7 +810,7 @@ public:
if (levelStr && isalpha(levelStr[0]))
{
nameStr = levelStr;
- levelStr = NULL; // current level will used
+ levelStr = NULL; // current level will be used
}
Player* target;
@@ -854,7 +854,7 @@ public:
return false;
std::string accountName = accountStr;
- if (!AccountMgr::normalizeString(accountName))
+ if (!Utf8ToUpperOnlyLatin(accountName))
{
handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str());
handler->SetSentErrorMessage(true);
diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp
index b937fc4e0a4..01a048c8795 100644
--- a/src/server/scripts/Commands/cs_debug.cpp
+++ b/src/server/scripts/Commands/cs_debug.cpp
@@ -1045,7 +1045,8 @@ public:
return false;
uint32 animId = atoi((char*)args);
- handler->GetSession()->GetPlayer()->HandleEmoteCommand(animId);
+ if (Unit* unit = handler->getSelectedUnit())
+ unit->HandleEmoteCommand(animId);
return true;
}
@@ -1409,10 +1410,7 @@ public:
map = player->GetMap();
handler->PSendSysMessage("Loading all cells (mapId: %u). Current next GameObject %u, Creature %u", map->GetId(), map->GetMaxLowGuid<HighGuid::GameObject>(), map->GetMaxLowGuid<HighGuid::Unit>());
- for (uint32 cellX = 0; cellX < TOTAL_NUMBER_OF_CELLS_PER_MAP; cellX++)
- for (uint32 cellY = 0; cellY < TOTAL_NUMBER_OF_CELLS_PER_MAP; cellY++)
- map->LoadGrid((cellX + 0.5f - CENTER_GRID_CELL_ID) * SIZE_OF_GRID_CELL, (cellY + 0.5f - CENTER_GRID_CELL_ID) * SIZE_OF_GRID_CELL);
-
+ map->LoadAllCells();
handler->PSendSysMessage("Cells loaded (mapId: %u) After load - Next GameObject %u, Creature %u", map->GetId(), map->GetMaxLowGuid<HighGuid::GameObject>(), map->GetMaxLowGuid<HighGuid::Unit>());
return true;
}
@@ -1436,7 +1434,7 @@ public:
duration = 3 * MINUTE;
bool doFill = fill_str ? (stricmp(fill_str, "FILL") == 0) : false;
-
+
int32 errMsg = target->AI()->VisualizeBoundary(duration, player, doFill);
if (errMsg > 0)
handler->PSendSysMessage(errMsg);
diff --git a/src/server/scripts/Commands/cs_gm.cpp b/src/server/scripts/Commands/cs_gm.cpp
index e03942bc247..ffe8ea67816 100644
--- a/src/server/scripts/Commands/cs_gm.cpp
+++ b/src/server/scripts/Commands/cs_gm.cpp
@@ -164,7 +164,7 @@ public:
///- Get the accounts with GM Level >0
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_GM_ACCOUNTS);
stmt->setUInt8(0, uint8(SEC_MODERATOR));
- stmt->setInt32(1, int32(realmID));
+ stmt->setInt32(1, int32(realm.Id.Realm));
PreparedQueryResult result = LoginDatabase.Query(stmt);
if (result)
diff --git a/src/server/scripts/Commands/cs_lookup.cpp b/src/server/scripts/Commands/cs_lookup.cpp
index 61e6acfb4d8..161ade1a30f 100644
--- a/src/server/scripts/Commands/cs_lookup.cpp
+++ b/src/server/scripts/Commands/cs_lookup.cpp
@@ -1343,7 +1343,7 @@ public:
char* limitStr = strtok(NULL, " ");
int32 limit = limitStr ? atoi(limitStr) : -1;
- if (!AccountMgr::normalizeString
+ if (!Utf8ToUpperOnlyLatin
(account))
return false;
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index c70246f7fb5..3e35a721162 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -36,6 +36,7 @@
#include "MMapFactory.h"
#include "DisableMgr.h"
#include "SpellHistory.h"
+#include "Transport.h"
class misc_commandscript : public CommandScript
{
@@ -237,6 +238,10 @@ public:
areaId, (areaEntry ? areaEntry->area_name[handler->GetSessionDbcLocale()] : unknown),
object->GetPhaseMask(),
object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), object->GetOrientation());
+ if (Transport* transport = object->GetTransport())
+ handler->PSendSysMessage(LANG_TRANSPORT_POSITION,
+ transport->GetGOInfo()->moTransport.mapID, object->GetTransOffsetX(), object->GetTransOffsetY(), object->GetTransOffsetZ(), object->GetTransOffsetO(),
+ transport->GetEntry(), transport->GetName().c_str());
handler->PSendSysMessage(LANG_GRID_POSITION,
cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), object->GetInstanceId(),
zoneX, zoneY, groundZ, floorZ, haveMap, haveVMap, haveMMap);
@@ -1588,7 +1593,7 @@ public:
// Query the prepared statement for login data
stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO);
- stmt->setInt32(0, int32(realmID));
+ stmt->setInt32(0, int32(realm.Id.Realm));
stmt->setUInt32(1, accId);
PreparedQueryResult result = LoginDatabase.Query(stmt);
@@ -1964,7 +1969,7 @@ public:
return false;
std::string accountName = nameStr;
- if (!AccountMgr::normalizeString(accountName))
+ if (!Utf8ToUpperOnlyLatin(accountName))
{
handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str());
handler->SetSentErrorMessage(true);
diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp
index 761b4c9e0e6..3a062b21c3e 100644
--- a/src/server/scripts/Commands/cs_modify.cpp
+++ b/src/server/scripts/Commands/cs_modify.cpp
@@ -473,7 +473,7 @@ public:
return false;
}
- handler->PSendSysMessage(LANG_YOU_CHANGE_ASPEED, ASpeed, targetNameLink.c_str());
+ handler->PSendSysMessage(LANG_YOU_CHANGE_ASPEED, targetNameLink.c_str(), ASpeed);
if (handler->needReportToTarget(target))
ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_ASPEED_CHANGED, handler->GetNameLink().c_str(), ASpeed);
@@ -521,7 +521,7 @@ public:
return false;
}
- handler->PSendSysMessage(LANG_YOU_CHANGE_SPEED, Speed, targetNameLink.c_str());
+ handler->PSendSysMessage(LANG_YOU_CHANGE_SPEED, targetNameLink.c_str(), Speed);
if (handler->needReportToTarget(target))
ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_SPEED_CHANGED, handler->GetNameLink().c_str(), Speed);
@@ -566,7 +566,7 @@ public:
return false;
}
- handler->PSendSysMessage(LANG_YOU_CHANGE_SWIM_SPEED, Swim, targetNameLink.c_str());
+ handler->PSendSysMessage(LANG_YOU_CHANGE_SWIM_SPEED, targetNameLink.c_str(), Swim);
if (handler->needReportToTarget(target))
ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_SWIM_SPEED_CHANGED, handler->GetNameLink().c_str(), Swim);
@@ -611,7 +611,7 @@ public:
return false;
}
- handler->PSendSysMessage(LANG_YOU_CHANGE_BACK_SPEED, BSpeed, targetNameLink.c_str());
+ handler->PSendSysMessage(LANG_YOU_CHANGE_BACK_SPEED, targetNameLink.c_str(), BSpeed);
if (handler->needReportToTarget(target))
ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_BACK_SPEED_CHANGED, handler->GetNameLink().c_str(), BSpeed);
@@ -647,7 +647,7 @@ public:
if (handler->HasLowerSecurity(target, ObjectGuid::Empty))
return false;
- handler->PSendSysMessage(LANG_YOU_CHANGE_FLY_SPEED, FSpeed, handler->GetNameLink(target).c_str());
+ handler->PSendSysMessage(LANG_YOU_CHANGE_FLY_SPEED, handler->GetNameLink(target).c_str(), FSpeed);
if (handler->needReportToTarget(target))
ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_FLY_SPEED_CHANGED, handler->GetNameLink().c_str(), FSpeed);
@@ -684,7 +684,7 @@ public:
if (handler->HasLowerSecurity(player, ObjectGuid::Empty))
return false;
- handler->PSendSysMessage(LANG_YOU_CHANGE_SIZE, Scale, handler->GetNameLink(player).c_str());
+ handler->PSendSysMessage(LANG_YOU_CHANGE_SIZE, handler->GetNameLink(player).c_str(), Scale);
if (handler->needReportToTarget(player))
ChatHandler(player->GetSession()).PSendSysMessage(LANG_YOURS_SIZE_CHANGED, handler->GetNameLink().c_str(), Scale);
}
diff --git a/src/server/scripts/Commands/cs_rbac.cpp b/src/server/scripts/Commands/cs_rbac.cpp
index f7c2d21c12d..64692c4d0ed 100644
--- a/src/server/scripts/Commands/cs_rbac.cpp
+++ b/src/server/scripts/Commands/cs_rbac.cpp
@@ -49,7 +49,7 @@ class rbac_commandscript : public CommandScript
public:
rbac_commandscript() : CommandScript("rbac_commandscript") { }
- std::vector<ChatCommand> GetCommands() const
+ std::vector<ChatCommand> GetCommands() const override
{
static std::vector<ChatCommand> rbacAccountCommandTable =
{
@@ -139,7 +139,7 @@ public:
{
accountName = param1;
- if (AccountMgr::normalizeString(accountName))
+ if (Utf8ToUpperOnlyLatin(accountName))
accountId = AccountMgr::GetId(accountName);
if (!accountId)
@@ -157,7 +157,7 @@ public:
if (!rdata)
{
- data->rbac = new rbac::RBACData(accountId, accountName, realmID, AccountMgr::GetSecurity(accountId, realmID));
+ data->rbac = new rbac::RBACData(accountId, accountName, realm.Id.Realm, AccountMgr::GetSecurity(accountId, realm.Id.Realm));
data->rbac->LoadFromDB();
data->needDelete = true;
}
diff --git a/src/server/scripts/Commands/cs_script_loader.cpp b/src/server/scripts/Commands/cs_script_loader.cpp
new file mode 100644
index 00000000000..449e7053942
--- /dev/null
+++ b/src/server/scripts/Commands/cs_script_loader.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// This is where scripts' loading functions should be declared:
+void AddSC_account_commandscript();
+void AddSC_achievement_commandscript();
+void AddSC_ahbot_commandscript();
+void AddSC_arena_commandscript();
+void AddSC_ban_commandscript();
+void AddSC_bf_commandscript();
+void AddSC_cast_commandscript();
+void AddSC_character_commandscript();
+void AddSC_cheat_commandscript();
+void AddSC_debug_commandscript();
+void AddSC_deserter_commandscript();
+void AddSC_disable_commandscript();
+void AddSC_event_commandscript();
+void AddSC_gm_commandscript();
+void AddSC_go_commandscript();
+void AddSC_gobject_commandscript();
+void AddSC_group_commandscript();
+void AddSC_guild_commandscript();
+void AddSC_honor_commandscript();
+void AddSC_instance_commandscript();
+void AddSC_learn_commandscript();
+void AddSC_lfg_commandscript();
+void AddSC_list_commandscript();
+void AddSC_lookup_commandscript();
+void AddSC_message_commandscript();
+void AddSC_misc_commandscript();
+void AddSC_mmaps_commandscript();
+void AddSC_modify_commandscript();
+void AddSC_npc_commandscript();
+void AddSC_pet_commandscript();
+void AddSC_quest_commandscript();
+void AddSC_rbac_commandscript();
+void AddSC_reload_commandscript();
+void AddSC_reset_commandscript();
+void AddSC_send_commandscript();
+void AddSC_server_commandscript();
+void AddSC_tele_commandscript();
+void AddSC_ticket_commandscript();
+void AddSC_titles_commandscript();
+void AddSC_wp_commandscript();
+
+// The name of this function should match:
+// void Add${NameOfDirectory}Scripts()
+void AddCommandsScripts()
+{
+ AddSC_account_commandscript();
+ AddSC_achievement_commandscript();
+ AddSC_ahbot_commandscript();
+ AddSC_arena_commandscript();
+ AddSC_ban_commandscript();
+ AddSC_bf_commandscript();
+ AddSC_cast_commandscript();
+ AddSC_character_commandscript();
+ AddSC_cheat_commandscript();
+ AddSC_debug_commandscript();
+ AddSC_deserter_commandscript();
+ AddSC_disable_commandscript();
+ AddSC_event_commandscript();
+ AddSC_gm_commandscript();
+ AddSC_go_commandscript();
+ AddSC_gobject_commandscript();
+ AddSC_group_commandscript();
+ AddSC_guild_commandscript();
+ AddSC_honor_commandscript();
+ AddSC_instance_commandscript();
+ AddSC_learn_commandscript();
+ AddSC_lookup_commandscript();
+ AddSC_lfg_commandscript();
+ AddSC_list_commandscript();
+ AddSC_message_commandscript();
+ AddSC_misc_commandscript();
+ AddSC_mmaps_commandscript();
+ AddSC_modify_commandscript();
+ AddSC_npc_commandscript();
+ AddSC_quest_commandscript();
+ AddSC_pet_commandscript();
+ AddSC_rbac_commandscript();
+ AddSC_reload_commandscript();
+ AddSC_reset_commandscript();
+ AddSC_send_commandscript();
+ AddSC_server_commandscript();
+ AddSC_tele_commandscript();
+ AddSC_ticket_commandscript();
+ AddSC_titles_commandscript();
+ AddSC_wp_commandscript();
+}
diff --git a/src/server/scripts/Commands/cs_send.cpp b/src/server/scripts/Commands/cs_send.cpp
index 672db3a3ab0..31544543426 100644
--- a/src/server/scripts/Commands/cs_send.cpp
+++ b/src/server/scripts/Commands/cs_send.cpp
@@ -74,7 +74,7 @@ public:
std::string subject = msgSubject;
std::string text = msgText;
- // from console show not existed sender
+ // from console, use non-existing sender
MailSender sender(MAIL_NORMAL, handler->GetSession() ? handler->GetSession()->GetPlayer()->GetGUID().GetCounter() : 0, MAIL_STATIONERY_GM);
/// @todo Fix poor design
@@ -173,7 +173,7 @@ public:
}
}
- // from console show not existed sender
+ // from console show nonexisting sender
MailSender sender(MAIL_NORMAL, handler->GetSession() ? handler->GetSession()->GetPlayer()->GetGUID().GetCounter() : 0, MAIL_STATIONERY_GM);
// fill mail
@@ -185,7 +185,7 @@ public:
{
if (Item* item = Item::CreateItem(itr->first, itr->second, handler->GetSession() ? handler->GetSession()->GetPlayer() : 0))
{
- item->SaveToDB(trans); // save for prevent lost at next mail load, if send fail then item will deleted
+ item->SaveToDB(trans); // Save to prevent being lost at next mail load. If send fails, the item will be deleted.
draft.AddItem(item);
}
}
@@ -233,7 +233,7 @@ public:
std::string subject = msgSubject;
std::string text = msgText;
- // from console show not existed sender
+ // from console show nonexisting sender
MailSender sender(MAIL_NORMAL, handler->GetSession() ? handler->GetSession()->GetPlayer()->GetGUID().GetCounter() : 0, MAIL_STATIONERY_GM);
SQLTransaction trans = CharacterDatabase.BeginTransaction();
@@ -260,7 +260,7 @@ public:
if (!msgStr)
return false;
- ///- Check that he is not logging out.
+ /// - Check if player is logging out.
if (player->GetSession()->isLogingOut())
{
handler->SendSysMessage(LANG_PLAYER_NOT_FOUND);
diff --git a/src/server/scripts/Commands/cs_ticket.cpp b/src/server/scripts/Commands/cs_ticket.cpp
index c5c85f5f3cc..899c5615206 100644
--- a/src/server/scripts/Commands/cs_ticket.cpp
+++ b/src/server/scripts/Commands/cs_ticket.cpp
@@ -95,7 +95,7 @@ public:
ObjectGuid targetGuid = sObjectMgr->GetPlayerGUIDByName(target);
uint32 accountId = sObjectMgr->GetPlayerAccountIdByGUID(targetGuid);
// Target must exist and have administrative rights
- if (!AccountMgr::HasPermission(accountId, rbac::RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET, realmID))
+ if (!AccountMgr::HasPermission(accountId, rbac::RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET, realm.Id.Realm))
{
handler->SendSysMessage(LANG_COMMAND_TICKETASSIGNERROR_A);
return true;
@@ -119,7 +119,7 @@ public:
// Assign ticket
SQLTransaction trans = SQLTransaction(NULL);
- ticket->SetAssignedTo(targetGuid, AccountMgr::IsAdminAccount(AccountMgr::GetSecurity(accountId, realmID)));
+ ticket->SetAssignedTo(targetGuid, AccountMgr::IsAdminAccount(AccountMgr::GetSecurity(accountId, realm.Id.Realm)));
ticket->SaveToDB(trans);
sTicketMgr->UpdateLastChange();
@@ -387,7 +387,7 @@ public:
{
ObjectGuid guid = ticket->GetAssignedToGUID();
uint32 accountId = sObjectMgr->GetPlayerAccountIdByGUID(guid);
- security = AccountMgr::GetSecurity(accountId, realmID);
+ security = AccountMgr::GetSecurity(accountId, realm.Id.Realm);
}
// Check security
diff --git a/src/server/scripts/Commands/cs_titles.cpp b/src/server/scripts/Commands/cs_titles.cpp
index 2f5d7b8364c..6309e7279c9 100644
--- a/src/server/scripts/Commands/cs_titles.cpp
+++ b/src/server/scripts/Commands/cs_titles.cpp
@@ -225,7 +225,7 @@ public:
if (CharTitlesEntry const* tEntry = sCharTitlesStore.LookupEntry(i))
titles2 &= ~(uint64(1) << tEntry->bit_index);
- titles &= ~titles2; // remove not existed titles
+ titles &= ~titles2; // remove non-existing titles
target->SetUInt64Value(PLAYER__FIELD_KNOWN_TITLES, titles);
handler->SendSysMessage(LANG_DONE);
diff --git a/src/server/scripts/Commands/cs_wp.cpp b/src/server/scripts/Commands/cs_wp.cpp
index ef61c231104..424f94f7385 100644
--- a/src/server/scripts/Commands/cs_wp.cpp
+++ b/src/server/scripts/Commands/cs_wp.cpp
@@ -561,29 +561,24 @@ public:
// -> variable lowguid is filled with the GUID of the NPC
uint32 pathid = 0;
uint32 point = 0;
- uint32 wpGuid = 0;
Creature* target = handler->getSelectedCreature();
PreparedStatement* stmt = NULL;
+ // User did select a visual waypoint?
if (!target || target->GetEntry() != VISUAL_WAYPOINT)
{
handler->SendSysMessage("|cffff33ffERROR: You must select a waypoint.|r");
return false;
}
- // The visual waypoint
- wpGuid = target->GetGUID().GetCounter();
-
- // User did select a visual waypoint?
-
// Check the creature
stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_BY_WPGUID);
- stmt->setUInt32(0, wpGuid);
+ stmt->setUInt32(0, target->GetSpawnId());
PreparedQueryResult result = WorldDatabase.Query(stmt);
if (!result)
{
- handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUID().GetCounter());
+ handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetSpawnId());
// Select waypoint number from database
// Since we compare float values, we have to deal with
// some difficulties.
@@ -599,11 +594,11 @@ public:
stmt->setString(3, maxDiff);
stmt->setFloat(4, target->GetPositionZ());
stmt->setString(5, maxDiff);
- PreparedQueryResult queryResult = WorldDatabase.Query(stmt);
+ result = WorldDatabase.Query(stmt);
- if (!queryResult)
+ if (!result)
{
- handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, wpGuid);
+ handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, target->GetSpawnId());
return true;
}
}
@@ -631,13 +626,8 @@ public:
{
handler->PSendSysMessage("|cff00ff00DEBUG: wp modify del, PathID: |r|cff00ffff%u|r", pathid);
- if (wpGuid != 0)
- if (Creature* wpCreature = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(ObjectGuid(HighGuid::Unit, VISUAL_WAYPOINT, wpGuid)))
- {
- wpCreature->CombatStop();
- wpCreature->DeleteFromDB();
- wpCreature->AddObjectToRemoveList();
- }
+ target->DeleteFromDB();
+ target->AddObjectToRemoveList();
stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_WAYPOINT_DATA);
stmt->setUInt32(0, pathid);
@@ -659,51 +649,40 @@ public:
Player* chr = handler->GetSession()->GetPlayer();
Map* map = chr->GetMap();
+ // What to do:
+ // Move the visual spawnpoint
+ // Respawn the owner of the waypoints
+ target->DeleteFromDB();
+ target->AddObjectToRemoveList();
+
+ // re-create
+ Creature* wpCreature = new Creature();
+ if (!wpCreature->Create(map->GenerateLowGuid<HighGuid::Unit>(), map, chr->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation()))
{
- // What to do:
- // Move the visual spawnpoint
- // Respawn the owner of the waypoints
- if (wpGuid != 0)
- {
- if (Creature* wpCreature = map->GetCreature(ObjectGuid(HighGuid::Unit, VISUAL_WAYPOINT, wpGuid)))
- {
- wpCreature->CombatStop();
- wpCreature->DeleteFromDB();
- wpCreature->AddObjectToRemoveList();
- }
- // re-create
- Creature* wpCreature2 = new Creature();
- if (!wpCreature2->Create(map->GenerateLowGuid<HighGuid::Unit>(), map, chr->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation()))
- {
- handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
- delete wpCreature2;
- wpCreature2 = NULL;
- return false;
- }
+ handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
+ delete wpCreature;
+ return false;
+ }
- wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
- // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
- /// @todo Should we first use "Create" then use "LoadFromDB"?
- if (!wpCreature2->LoadCreatureFromDB(wpCreature2->GetSpawnId(), map))
- {
- handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
- delete wpCreature2;
- wpCreature2 = NULL;
- return false;
- }
- //sMapMgr->GetMap(npcCreature->GetMapId())->Add(wpCreature2);
- }
+ wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
+ // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
+ /// @todo Should we first use "Create" then use "LoadFromDB"?
+ if (!wpCreature->LoadCreatureFromDB(wpCreature->GetSpawnId(), map))
+ {
+ handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
+ delete wpCreature;
+ return false;
+ }
- stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_POSITION);
- stmt->setFloat(0, chr->GetPositionX());
- stmt->setFloat(1, chr->GetPositionY());
- stmt->setFloat(2, chr->GetPositionZ());
- stmt->setUInt32(3, pathid);
- stmt->setUInt32(4, point);
- WorldDatabase.Execute(stmt);
+ stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_POSITION);
+ stmt->setFloat(0, chr->GetPositionX());
+ stmt->setFloat(1, chr->GetPositionY());
+ stmt->setFloat(2, chr->GetPositionZ());
+ stmt->setUInt32(3, pathid);
+ stmt->setUInt32(4, point);
+ WorldDatabase.Execute(stmt);
- handler->PSendSysMessage(LANG_WAYPOINT_CHANGED);
- }
+ handler->PSendSysMessage(LANG_WAYPOINT_CHANGED);
return true;
} // move
@@ -897,14 +876,15 @@ public:
return false;
}
+ wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
+
// Set "wpguid" column to the visual waypoint
stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_WPGUID);
- stmt->setInt32(0, int32(wpCreature->GetGUID().GetCounter()));
+ stmt->setInt32(0, int32(wpCreature->GetSpawnId()));
stmt->setUInt32(1, pathid);
stmt->setUInt32(2, point);
WorldDatabase.Execute(stmt);
- wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
// To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
if (!wpCreature->LoadCreatureFromDB(wpCreature->GetSpawnId(), map))
{
diff --git a/src/server/scripts/Custom/CMakeLists.txt b/src/server/scripts/Custom/CMakeLists.txt
deleted file mode 100644
index 595ff801813..00000000000
--- a/src/server/scripts/Custom/CMakeLists.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
-#
-# This file is free software; as a special exception the author gives
-# unlimited permission to copy and/or distribute it, with or without
-# modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-# file(GLOB_RECURSE sources_Custom Custom/*.cpp Custom/*.h)
-
-set(scripts_STAT_SRCS
- ${scripts_STAT_SRCS}
-# ${sources_Custom}
-)
-
-message(" -> Prepared: Custom")
diff --git a/src/server/scripts/Custom/custom_script_loader.cpp b/src/server/scripts/Custom/custom_script_loader.cpp
new file mode 100644
index 00000000000..dd4b5e99d77
--- /dev/null
+++ b/src/server/scripts/Custom/custom_script_loader.cpp
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// This is where scripts' loading functions should be declared:
+
+
+// The name of this function should match:
+// void Add${NameOfDirectory}Scripts()
+void AddCustomScripts()
+{
+}
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp
index 9cd724e5596..79709734e18 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp
@@ -508,19 +508,11 @@ public:
};
// npc_lokhtos_darkbargainer
-enum LokhtosItems
+enum Lokhtos
{
+ QUEST_A_BINDING_CONTRACT = 7604,
+ ITEM_SULFURON_INGOT = 17203,
ITEM_THRORIUM_BROTHERHOOD_CONTRACT = 18628,
- ITEM_SULFURON_INGOT = 17203
-};
-
-enum LokhtosQuests
-{
- QUEST_A_BINDING_CONTRACT = 7604
-};
-
-enum LokhtosSpells
-{
SPELL_CREATE_THORIUM_BROTHERHOOD_CONTRACT_DND = 23059
};
@@ -570,67 +562,12 @@ public:
}
};
-// npc_dughal_stormwing
-enum DughalQuests
-{
- QUEST_JAIL_BREAK = 4322
-};
-
-#define SAY_DUGHAL_FREE "Thank you, $N! I'm free!!!"
-#define GOSSIP_DUGHAL "You're free, Dughal! Get out of here!"
-
-// npc_marshal_windsor
-#define SAY_WINDSOR_AGGRO1 "You locked up the wrong Marshal. Prepare to be destroyed!"
-#define SAY_WINDSOR_AGGRO2 "I bet you're sorry now, aren't you !?!!"
-#define SAY_WINDSOR_AGGRO3 "You better hold me back $N or they are going to feel some prison house beatings."
-#define SAY_WINDSOR_1 "Let's get a move on. My gear should be in the storage area up this way..."
-#define SAY_WINDSOR_4_1 "Check that cell, $N. If someone is alive in there, we need to get them out."
-#define SAY_WINDSOR_4_2 "Get him out of there!"
-#define SAY_WINDSOR_4_3 "Good work! We're almost there, $N. This way."
-#define SAY_WINDSOR_6 "This is it, $N. My stuff should be in that room. Cover me, I'm going in!"
-#define SAY_WINDSOR_9 "Ah, there it is!"
-
-enum MarshalWindsor
-{
- NPC_REGINALD_WINDSOR = 9682
-};
-
-// npc_marshal_reginald_windsor
-#define SAY_REGINALD_WINDSOR_0_1 "Can you feel the power, $N??? It's time to ROCK!"
-#define SAY_REGINALD_WINDSOR_0_2 "Now we just have to free Tobias and we can get out of here. This way!"
-#define SAY_REGINALD_WINDSOR_5_1 "Open it."
-#define SAY_REGINALD_WINDSOR_5_2 "I never did like those two. Let's get moving."
-#define SAY_REGINALD_WINDSOR_7_1 "Open it and be careful this time!"
-#define SAY_REGINALD_WINDSOR_7_2 "That intolerant dirtbag finally got what was coming to him. Good riddance!"
-#define SAY_REGINALD_WINDSOR_7_3 "Alright, let's go."
-#define SAY_REGINALD_WINDSOR_13_1 "Open it. We need to hurry up. I can smell those Dark Irons coming a mile away and I can tell you one thing, they're COMING!"
-#define SAY_REGINALD_WINDSOR_13_2 "Administering fists of fury on Crest Killer!"
-#define SAY_REGINALD_WINDSOR_13_3 "He has to be in the last cell. Unless... they killed him."
-#define SAY_REGINALD_WINDSOR_14_1 "Get him out of there!"
-#define SAY_REGINALD_WINDSOR_14_2 "Excellent work, $N. Let's find the exit. I think I know the way. Follow me!"
-#define SAY_REGINALD_WINDSOR_20_1 "We made it!"
-#define SAY_REGINALD_WINDSOR_20_2 "Meet me at Maxwell's encampment. We'll go over the next stages of the plan there and figure out a way to decode my tablets without the decryption ring."
-
-enum MarshalReginaldWindor
-{
- NPC_SHILL_DINGER = 9678,
- NPC_CREST_KILLER = 9680
-};
-
// npc_rocknot
-enum RocknotSays
-{
- SAY_GOT_BEER = 0
-};
-
-enum RocknotSpells
-{
- SPELL_DRUNKEN_RAGE = 14872
-};
-
-enum RocknotQuests
+enum Rocknot
{
- QUEST_ALE = 4295
+ SAY_GOT_BEER = 0,
+ QUEST_ALE = 4295,
+ SPELL_DRUNKEN_RAGE = 14872
};
class npc_rocknot : public CreatureScript
diff --git a/src/server/scripts/EasternKingdoms/CMakeLists.txt b/src/server/scripts/EasternKingdoms/CMakeLists.txt
deleted file mode 100644
index 8e6616347f9..00000000000
--- a/src/server/scripts/EasternKingdoms/CMakeLists.txt
+++ /dev/null
@@ -1,204 +0,0 @@
-# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
-#
-# This file is free software; as a special exception the author gives
-# unlimited permission to copy and/or distribute it, with or without
-# modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-set(scripts_STAT_SRCS
- ${scripts_STAT_SRCS}
- EasternKingdoms/zone_ghostlands.cpp
- EasternKingdoms/AlteracValley/boss_galvangar.cpp
- EasternKingdoms/AlteracValley/boss_balinda.cpp
- EasternKingdoms/AlteracValley/boss_drekthar.cpp
- EasternKingdoms/AlteracValley/boss_vanndar.cpp
- EasternKingdoms/AlteracValley/alterac_valley.cpp
- EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_high_interrogator_gerstahn.cpp
- EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp
- EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_tomb_of_seven.cpp
- EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_general_angerforge.cpp
- EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_ambassador_flamelash.cpp
- EasternKingdoms/BlackrockMountain/BlackrockDepths/instance_blackrock_depths.cpp
- EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_moira_bronzebeard.cpp
- EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.h
- EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp
- EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_magmus.cpp
- EasternKingdoms/BlackrockMountain/BlackwingLair/boss_chromaggus.cpp
- EasternKingdoms/BlackrockMountain/BlackwingLair/boss_razorgore.cpp
- EasternKingdoms/BlackrockMountain/BlackwingLair/boss_firemaw.cpp
- EasternKingdoms/BlackrockMountain/BlackwingLair/boss_broodlord_lashlayer.cpp
- EasternKingdoms/BlackrockMountain/BlackwingLair/boss_ebonroc.cpp
- EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp
- EasternKingdoms/BlackrockMountain/BlackwingLair/boss_vaelastrasz.cpp
- EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp
- EasternKingdoms/BlackrockMountain/BlackwingLair/boss_flamegor.cpp
- EasternKingdoms/BlackrockMountain/BlackwingLair/blackwing_lair.h
- EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_pyroguard_emberseer.cpp
- EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_drakkisath.cpp
- EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_warmaster_voone.cpp
- EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_mother_smolderweb.cpp
- EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_quartermaster_zigris.cpp
- EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_halycon.cpp
- EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_overlord_wyrmthalak.cpp
- EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_shadow_hunter_voshgajin.cpp
- EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_gyth.cpp
- EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_rend_blackhand.cpp
- EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_highlord_omokk.cpp
- EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_the_beast.cpp
- EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_gizrul_the_slavener.cpp
- EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_urok_doomhowl.cpp
- EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_lord_valthalak.cpp
- EasternKingdoms/BlackrockMountain/BlackrockSpire/blackrock_spire.h
- EasternKingdoms/BlackrockMountain/BlackrockSpire/instance_blackrock_spire.cpp
- EasternKingdoms/BlackrockMountain/MoltenCore/boss_gehennas.cpp
- EasternKingdoms/BlackrockMountain/MoltenCore/boss_lucifron.cpp
- EasternKingdoms/BlackrockMountain/MoltenCore/boss_golemagg.cpp
- EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp
- EasternKingdoms/BlackrockMountain/MoltenCore/boss_baron_geddon.cpp
- EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp
- EasternKingdoms/BlackrockMountain/MoltenCore/boss_garr.cpp
- EasternKingdoms/BlackrockMountain/MoltenCore/molten_core.h
- EasternKingdoms/BlackrockMountain/MoltenCore/instance_molten_core.cpp
- EasternKingdoms/BlackrockMountain/MoltenCore/boss_sulfuron_harbinger.cpp
- EasternKingdoms/BlackrockMountain/MoltenCore/boss_magmadar.cpp
- EasternKingdoms/BlackrockMountain/MoltenCore/boss_shazzrah.cpp
- EasternKingdoms/Scholomance/boss_the_ravenian.cpp
- EasternKingdoms/Scholomance/boss_instructor_malicia.cpp
- EasternKingdoms/Scholomance/boss_death_knight_darkreaver.cpp
- EasternKingdoms/Scholomance/boss_illucia_barov.cpp
- EasternKingdoms/Scholomance/scholomance.h
- EasternKingdoms/Scholomance/boss_vectus.cpp
- EasternKingdoms/Scholomance/boss_jandice_barov.cpp
- EasternKingdoms/Scholomance/boss_kormok.cpp
- EasternKingdoms/Scholomance/boss_lord_alexei_barov.cpp
- EasternKingdoms/Scholomance/boss_doctor_theolen_krastinov.cpp
- EasternKingdoms/Scholomance/boss_darkmaster_gandling.cpp
- EasternKingdoms/Scholomance/instance_scholomance.cpp
- EasternKingdoms/Scholomance/boss_lorekeeper_polkelt.cpp
- EasternKingdoms/Scholomance/boss_ras_frostwhisper.cpp
- EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp
- EasternKingdoms/zone_isle_of_queldanas.cpp
- EasternKingdoms/ZulGurub/boss_hakkar.cpp
- EasternKingdoms/ZulGurub/boss_mandokir.cpp
- EasternKingdoms/ZulGurub/boss_marli.cpp
- EasternKingdoms/ZulGurub/boss_hazzarah.cpp
- EasternKingdoms/ZulGurub/boss_jeklik.cpp
- EasternKingdoms/ZulGurub/boss_grilek.cpp
- EasternKingdoms/ZulGurub/zulgurub.h
- EasternKingdoms/ZulGurub/boss_renataki.cpp
- EasternKingdoms/ZulGurub/boss_arlokk.cpp
- EasternKingdoms/ZulGurub/boss_gahzranka.cpp
- EasternKingdoms/ZulGurub/boss_venoxis.cpp
- EasternKingdoms/ZulGurub/instance_zulgurub.cpp
- EasternKingdoms/ZulGurub/boss_jindo.cpp
- EasternKingdoms/ZulGurub/boss_wushoolay.cpp
- EasternKingdoms/ZulGurub/boss_thekal.cpp
- EasternKingdoms/zone_wetlands.cpp
- EasternKingdoms/zone_arathi_highlands.cpp
- EasternKingdoms/Gnomeregan/instance_gnomeregan.cpp
- EasternKingdoms/Gnomeregan/gnomeregan.cpp
- EasternKingdoms/Gnomeregan/gnomeregan.h
- EasternKingdoms/zone_redridge_mountains.cpp
- EasternKingdoms/ScarletEnclave/chapter2.cpp
- EasternKingdoms/ScarletEnclave/chapter5.cpp
- EasternKingdoms/ScarletEnclave/chapter1.cpp
- EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp
- EasternKingdoms/zone_eastern_plaguelands.cpp
- EasternKingdoms/Stratholme/boss_baroness_anastari.cpp
- EasternKingdoms/Stratholme/boss_nerubenkan.cpp
- EasternKingdoms/Stratholme/instance_stratholme.cpp
- EasternKingdoms/Stratholme/boss_dathrohan_balnazzar.cpp
- EasternKingdoms/Stratholme/boss_timmy_the_cruel.cpp
- EasternKingdoms/Stratholme/boss_baron_rivendare.cpp
- EasternKingdoms/Stratholme/boss_magistrate_barthilas.cpp
- EasternKingdoms/Stratholme/boss_order_of_silver_hand.cpp
- EasternKingdoms/Stratholme/boss_ramstein_the_gorger.cpp
- EasternKingdoms/Stratholme/boss_cannon_master_willey.cpp
- EasternKingdoms/Stratholme/boss_maleki_the_pallid.cpp
- EasternKingdoms/Stratholme/boss_postmaster_malown.cpp
- EasternKingdoms/Stratholme/stratholme.h
- EasternKingdoms/Stratholme/stratholme.cpp
- EasternKingdoms/zone_tirisfal_glades.cpp
- EasternKingdoms/SunkenTemple/sunken_temple.cpp
- EasternKingdoms/SunkenTemple/sunken_temple.h
- EasternKingdoms/SunkenTemple/instance_sunken_temple.cpp
- EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp
- EasternKingdoms/MagistersTerrace/magisters_terrace.h
- EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp
- EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp
- EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp
- EasternKingdoms/MagistersTerrace/boss_vexallus.cpp
- EasternKingdoms/MagistersTerrace/magisters_terrace.cpp
- EasternKingdoms/Uldaman/uldaman.cpp
- EasternKingdoms/Uldaman/boss_ironaya.cpp
- EasternKingdoms/Uldaman/uldaman.h
- EasternKingdoms/Uldaman/instance_uldaman.cpp
- EasternKingdoms/Uldaman/boss_archaedas.cpp
- EasternKingdoms/zone_swamp_of_sorrows.cpp
- EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp
- EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp
- EasternKingdoms/SunwellPlateau/sunwell_plateau.h
- EasternKingdoms/SunwellPlateau/boss_muru.cpp
- EasternKingdoms/SunwellPlateau/instance_sunwell_plateau.cpp
- EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp
- EasternKingdoms/SunwellPlateau/boss_brutallus.cpp
- EasternKingdoms/SunwellPlateau/sunwell_plateau.cpp
- EasternKingdoms/SunwellPlateau/boss_felmyst.cpp
- EasternKingdoms/zone_stranglethorn_vale.cpp
- EasternKingdoms/Deadmines/deadmines.h
- EasternKingdoms/Deadmines/deadmines.cpp
- EasternKingdoms/Deadmines/boss_mr_smite.cpp
- EasternKingdoms/Deadmines/instance_deadmines.cpp
- EasternKingdoms/zone_duskwood.cpp
- EasternKingdoms/ScarletMonastery/boss_azshir_the_sleepless.cpp
- EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp
- EasternKingdoms/ScarletMonastery/boss_bloodmage_thalnos.cpp
- EasternKingdoms/ScarletMonastery/boss_interrogator_vishas.cpp
- EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp
- EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp
- EasternKingdoms/ScarletMonastery/boss_houndmaster_loksey.cpp
- EasternKingdoms/ScarletMonastery/scarlet_monastery.h
- EasternKingdoms/ScarletMonastery/boss_high_inquisitor_fairbanks.cpp
- EasternKingdoms/ScarletMonastery/boss_arcanist_doan.cpp
- EasternKingdoms/ScarletMonastery/boss_herod.cpp
- EasternKingdoms/ScarletMonastery/boss_scorn.cpp
- EasternKingdoms/zone_undercity.cpp
- EasternKingdoms/zone_loch_modan.cpp
- EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp
- EasternKingdoms/ShadowfangKeep/instance_shadowfang_keep.cpp
- EasternKingdoms/ShadowfangKeep/shadowfang_keep.h
- EasternKingdoms/zone_burning_steppes.cpp
- EasternKingdoms/zone_blasted_lands.cpp
- EasternKingdoms/zone_stormwind_city.cpp
- EasternKingdoms/ZulAman/boss_halazzi.cpp
- EasternKingdoms/ZulAman/boss_hexlord.cpp
- EasternKingdoms/ZulAman/boss_zuljin.cpp
- EasternKingdoms/ZulAman/boss_akilzon.cpp
- EasternKingdoms/ZulAman/instance_zulaman.cpp
- EasternKingdoms/ZulAman/boss_janalai.cpp
- EasternKingdoms/ZulAman/boss_nalorakk.cpp
- EasternKingdoms/ZulAman/zulaman.cpp
- EasternKingdoms/ZulAman/zulaman.h
- EasternKingdoms/zone_hinterlands.cpp
- EasternKingdoms/zone_western_plaguelands.cpp
- EasternKingdoms/zone_silverpine_forest.cpp
- EasternKingdoms/Karazhan/instance_karazhan.cpp
- EasternKingdoms/Karazhan/boss_nightbane.cpp
- EasternKingdoms/Karazhan/karazhan.cpp
- EasternKingdoms/Karazhan/boss_curator.cpp
- EasternKingdoms/Karazhan/boss_shade_of_aran.cpp
- EasternKingdoms/Karazhan/boss_netherspite.cpp
- EasternKingdoms/Karazhan/boss_maiden_of_virtue.cpp
- EasternKingdoms/Karazhan/boss_midnight.cpp
- EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp
- EasternKingdoms/Karazhan/bosses_opera.cpp
- EasternKingdoms/Karazhan/boss_moroes.cpp
- EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp
- EasternKingdoms/Karazhan/karazhan.h
- EasternKingdoms/TheStockade/instance_the_stockade.cpp
-)
-
-message(" -> Prepared: Eastern Kingdoms")
diff --git a/src/server/scripts/EasternKingdoms/Deadmines/boss_mr_smite.cpp b/src/server/scripts/EasternKingdoms/Deadmines/boss_mr_smite.cpp
index 541ddc0e1c8..8f246ab9bf0 100644
--- a/src/server/scripts/EasternKingdoms/Deadmines/boss_mr_smite.cpp
+++ b/src/server/scripts/EasternKingdoms/Deadmines/boss_mr_smite.cpp
@@ -25,17 +25,25 @@ EndScriptData */
#include "ScriptedCreature.h"
#include "deadmines.h"
-enum Spels
+enum Spells
{
SPELL_TRASH = 3391,
SPELL_SMITE_STOMP = 6432,
SPELL_SMITE_SLAM = 6435,
- SPELL_NIMBLE_REFLEXES = 6264,
+ SPELL_NIMBLE_REFLEXES = 6264
+};
+enum Equips
+{
EQUIP_SWORD = 5191,
- EQUIP_MACE = 7230,
+ EQUIP_AXE = 5196,
+ EQUIP_MACE = 7230
+};
- SAY_AGGRO = 0,
+enum Texts
+{
+ SAY_PHASE_1 = 2,
+ SAY_PHASE_2 = 3
};
class boss_mr_smite : public CreatureScript
@@ -66,6 +74,8 @@ public:
uiPhase = 0;
uiTimer = 0;
+
+ uiIsMoving = false;
}
InstanceScript* instance;
@@ -79,16 +89,19 @@ public:
uint32 uiPhase;
uint32 uiTimer;
+ bool uiIsMoving;
+
void Reset() override
{
Initialize();
SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_UNEQUIP, EQUIP_NO_CHANGE);
+ me->SetStandState(UNIT_STAND_STATE_STAND);
+ me->SetReactState(REACT_AGGRESSIVE);
}
void EnterCombat(Unit* /*who*/) override
{
- Talk(SAY_AGGRO);
}
bool bCheckChances()
@@ -105,38 +118,52 @@ public:
if (!UpdateVictim())
return;
- /*START ACID-AI*/
- if (uiTrashTimer <= uiDiff)
+ if (!uiIsMoving) // halt abilities in between phases
{
- if (bCheckChances())
- DoCast(me, SPELL_TRASH);
- uiTrashTimer = urand(6000, 15500);
- } else uiTrashTimer -= uiDiff;
+ if (uiTrashTimer <= uiDiff)
+ {
+ if (bCheckChances())
+ DoCast(me, SPELL_TRASH);
+ uiTrashTimer = urand(6000, 15500);
+ }
+ else uiTrashTimer -= uiDiff;
- if (uiSlamTimer <= uiDiff)
- {
- if (bCheckChances())
- DoCastVictim(SPELL_SMITE_SLAM);
- uiSlamTimer = 11000;
- } else uiSlamTimer -= uiDiff;
+ if (uiSlamTimer <= uiDiff)
+ {
+ if (bCheckChances())
+ DoCastVictim(SPELL_SMITE_SLAM);
+ uiSlamTimer = 11000;
+ }
+ else uiSlamTimer -= uiDiff;
- if (uiNimbleReflexesTimer <= uiDiff)
- {
- if (bCheckChances())
- DoCast(me, SPELL_NIMBLE_REFLEXES);
- uiNimbleReflexesTimer = urand(27300, 60100);
- } else uiNimbleReflexesTimer -= uiDiff;
- /*END ACID-AI*/
+ if (uiNimbleReflexesTimer <= uiDiff)
+ {
+ if (bCheckChances())
+ DoCast(me, SPELL_NIMBLE_REFLEXES);
+ uiNimbleReflexesTimer = urand(27300, 60100);
+ }
+ else uiNimbleReflexesTimer -= uiDiff;
+ }
if ((uiHealth == 0 && !HealthAbovePct(66)) || (uiHealth == 1 && !HealthAbovePct(33)))
{
++uiHealth;
DoCastAOE(SPELL_SMITE_STOMP, false);
SetCombatMovement(false);
- if (GameObject* go = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_SMITE_CHEST)))
+ me->AttackStop();
+ me->InterruptNonMeleeSpells(false);
+ me->SetReactState(REACT_PASSIVE);
+ uiTimer = 2500;
+ uiPhase = 1;
+
+ switch (uiHealth)
{
- me->GetMotionMaster()->Clear();
- me->GetMotionMaster()->MovePoint(1, go->GetPositionX() - 3.0f, go->GetPositionY(), go->GetPositionZ());
+ case 1:
+ Talk(SAY_PHASE_1);
+ break;
+ case 2:
+ Talk(SAY_PHASE_2);
+ break;
}
}
@@ -147,21 +174,36 @@ public:
switch (uiPhase)
{
case 1:
- me->HandleEmoteCommand(EMOTE_STATE_KNEEL); //dosen't work?
- uiTimer = 1000;
- uiPhase = 2;
+ {
+ if (uiIsMoving)
+ break;
+
+ if (GameObject* go = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_SMITE_CHEST)))
+ {
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MovePoint(1, go->GetPositionX() - 1.5f, go->GetPositionY() + 1.4f, go->GetPositionZ());
+ uiIsMoving = true;
+ }
break;
+ }
case 2:
if (uiHealth == 1)
- SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SWORD, EQUIP_NO_CHANGE);
+ SetEquipmentSlots(false, EQUIP_AXE, EQUIP_AXE, EQUIP_NO_CHANGE);
else
SetEquipmentSlots(false, EQUIP_MACE, EQUIP_UNEQUIP, EQUIP_NO_CHANGE);
uiTimer = 500;
uiPhase = 3;
break;
case 3:
+ me->SetStandState(UNIT_STAND_STATE_STAND);
+ uiTimer = 750;
+ uiPhase = 4;
+ break;
+ case 4:
+ me->SetReactState(REACT_AGGRESSIVE);
SetCombatMovement(true);
me->GetMotionMaster()->MoveChase(me->GetVictim(), me->m_CombatDistance);
+ uiIsMoving = false;
uiPhase = 0;
break;
}
@@ -176,8 +218,11 @@ public:
if (uiType != POINT_MOTION_TYPE)
return;
- uiTimer = 1500;
- uiPhase = 1;
+ me->SetFacingTo(5.47f);
+ me->SetStandState(UNIT_STAND_STATE_KNEEL);
+
+ uiTimer = 2000;
+ uiPhase = 2;
}
};
};
diff --git a/src/server/scripts/EasternKingdoms/Deadmines/deadmines.h b/src/server/scripts/EasternKingdoms/Deadmines/deadmines.h
index dff4243617e..01ebabb160e 100644
--- a/src/server/scripts/EasternKingdoms/Deadmines/deadmines.h
+++ b/src/server/scripts/EasternKingdoms/Deadmines/deadmines.h
@@ -26,6 +26,7 @@ enum CannonState
CANNON_GUNPOWDER_USED,
CANNON_BLAST_INITIATED,
PIRATES_ATTACK,
+ SMITE_ALARMED,
EVENT_DONE
};
@@ -48,4 +49,16 @@ enum GameObjects
GO_DOOR_LEVER = 101833,
GO_MR_SMITE_CHEST = 144111
};
+
+enum CreaturesIds
+{
+ NPC_MR_SMITE = 646
+};
+
+enum InstanceTexts
+{
+ SAY_ALARM1 = 0,
+ SAY_ALARM2 = 1
+};
+
#endif
diff --git a/src/server/scripts/EasternKingdoms/Deadmines/instance_deadmines.cpp b/src/server/scripts/EasternKingdoms/Deadmines/instance_deadmines.cpp
index 6714b243765..7599cf38f08 100644
--- a/src/server/scripts/EasternKingdoms/Deadmines/instance_deadmines.cpp
+++ b/src/server/scripts/EasternKingdoms/Deadmines/instance_deadmines.cpp
@@ -32,18 +32,14 @@ EndScriptData */
enum Sounds
{
SOUND_CANNONFIRE = 1400,
- SOUND_DESTROYDOOR = 3079,
- SOUND_MR_SMITE_ALARM1 = 5775,
- SOUND_MR_SMITE_ALARM2 = 5777
+ SOUND_DESTROYDOOR = 3079
};
-#define SAY_MR_SMITE_ALARM1 "You there, check out that noise!"
-#define SAY_MR_SMITE_ALARM2 "We're under attack! A vast, ye swabs! Repel the invaders!"
-
enum Misc
{
DATA_CANNON_BLAST_TIMER = 3000,
- DATA_PIRATES_DELAY_TIMER = 1000
+ DATA_PIRATES_DELAY_TIMER = 1000,
+ DATA_SMITE_ALARM_DELAY_TIMER = 5000
};
class instance_deadmines : public InstanceMapScript
@@ -63,6 +59,7 @@ class instance_deadmines : public InstanceMapScript
State = CANNON_NOT_USED;
CannonBlast_Timer = 0;
PiratesDelay_Timer = 0;
+ SmiteAlarmDelay_Timer = 0;
}
ObjectGuid FactoryDoorGUID;
@@ -72,10 +69,12 @@ class instance_deadmines : public InstanceMapScript
ObjectGuid DefiasPirate1GUID;
ObjectGuid DefiasPirate2GUID;
ObjectGuid DefiasCompanionGUID;
+ ObjectGuid MrSmiteGUID;
uint32 State;
uint32 CannonBlast_Timer;
uint32 PiratesDelay_Timer;
+ uint32 SmiteAlarmDelay_Timer;
ObjectGuid uiSmiteChestGUID;
virtual void Update(uint32 diff) override
@@ -91,22 +90,20 @@ class instance_deadmines : public InstanceMapScript
{
case CANNON_GUNPOWDER_USED:
CannonBlast_Timer = DATA_CANNON_BLAST_TIMER;
- // it's a hack - Mr. Smite should do that but his too far away
- //pIronCladDoor->SetName("Mr. Smite");
- //pIronCladDoor->MonsterYell(SAY_MR_SMITE_ALARM1, LANG_UNIVERSAL, NULL);
- pIronCladDoor->PlayDirectSound(SOUND_MR_SMITE_ALARM1);
State = CANNON_BLAST_INITIATED;
break;
case CANNON_BLAST_INITIATED:
PiratesDelay_Timer = DATA_PIRATES_DELAY_TIMER;
+ SmiteAlarmDelay_Timer = DATA_SMITE_ALARM_DELAY_TIMER;
if (CannonBlast_Timer <= diff)
{
SummonCreatures();
ShootCannon();
BlastOutDoor();
LeverStucked();
- //pIronCladDoor->MonsterYell(SAY_MR_SMITE_ALARM2, LANG_UNIVERSAL, NULL);
- pIronCladDoor->PlayDirectSound(SOUND_MR_SMITE_ALARM2);
+ instance->LoadGrid(-22.8f, -797.24f); // Loads Mr. Smite's grid.
+ if (Creature* smite = instance->GetCreature(MrSmiteGUID)) // goes off when door blows up
+ smite->AI()->Talk(SAY_ALARM1);
State = PIRATES_ATTACK;
} else CannonBlast_Timer -= diff;
break;
@@ -114,9 +111,17 @@ class instance_deadmines : public InstanceMapScript
if (PiratesDelay_Timer <= diff)
{
MoveCreaturesInside();
- State = EVENT_DONE;
+ State = SMITE_ALARMED;
} else PiratesDelay_Timer -= diff;
break;
+ case SMITE_ALARMED:
+ if (SmiteAlarmDelay_Timer <= diff)
+ {
+ if (Creature* smite = instance->GetCreature(MrSmiteGUID))
+ smite->AI()->Talk(SAY_ALARM2);
+ State = EVENT_DONE;
+ } else SmiteAlarmDelay_Timer -= diff;
+ break;
}
}
@@ -180,6 +185,18 @@ class instance_deadmines : public InstanceMapScript
pDoorLever->SetUInt32Value(GAMEOBJECT_FLAGS, 4);
}
+ void OnCreatureCreate(Creature* creature) override
+ {
+ switch (creature->GetEntry())
+ {
+ case NPC_MR_SMITE:
+ MrSmiteGUID = creature->GetGUID();
+ break;
+ default:
+ break;
+ }
+ }
+
void OnGameObjectCreate(GameObject* go) override
{
switch (go->GetEntry())
diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_maiden_of_virtue.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_maiden_of_virtue.cpp
index 9f4a31fdbbc..b694c074879 100644
--- a/src/server/scripts/EasternKingdoms/Karazhan/boss_maiden_of_virtue.cpp
+++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_maiden_of_virtue.cpp
@@ -50,19 +50,9 @@ class boss_maiden_of_virtue : public CreatureScript
public:
boss_maiden_of_virtue() : CreatureScript("boss_maiden_of_virtue") { }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new boss_maiden_of_virtueAI(creature);
- }
-
struct boss_maiden_of_virtueAI : public BossAI
{
- boss_maiden_of_virtueAI(Creature* creature) : BossAI(creature, TYPE_MAIDEN) { }
-
- void Reset() override
- {
- _Reset();
- }
+ boss_maiden_of_virtueAI(Creature* creature) : BossAI(creature, DATA_MAIDEN_OF_VIRTUE) { }
void KilledUnit(Unit* /*Victim*/) override
{
@@ -132,6 +122,11 @@ public:
DoMeleeAttackIfReady();
}
};
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new boss_maiden_of_virtueAI(creature);
+ }
};
void AddSC_boss_maiden_of_virtue()
diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp
index ced8dd8f37e..43ef7e006ef 100644
--- a/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp
+++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp
@@ -26,6 +26,7 @@ EndScriptData */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellInfo.h"
+#include "karazhan.h"
enum Midnight
{
@@ -109,6 +110,9 @@ public:
Talk(SAY_DEATH);
if (Unit* midnight = ObjectAccessor::GetUnit(*me, Midnight))
midnight->KillSelf();
+
+ if (InstanceScript* instance = me->GetInstanceScript())
+ instance->SetBossState(DATA_ATTUMEN, DONE);
}
void UpdateAI(uint32 diff) override;
@@ -157,7 +161,11 @@ public:
me->SetVisible(true);
}
- void EnterCombat(Unit* /*who*/) override { }
+ void EnterCombat(Unit* /*who*/) override
+ {
+ if (InstanceScript* instance = me->GetInstanceScript())
+ instance->SetBossState(DATA_ATTUMEN, IN_PROGRESS);
+ }
void KilledUnit(Unit* /*victim*/) override
{
diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp
index 79e36442f4b..e667141fa29 100644
--- a/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp
+++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp
@@ -143,12 +143,12 @@ public:
if (me->IsAlive())
SpawnAdds();
- instance->SetData(TYPE_MOROES, NOT_STARTED);
+ instance->SetBossState(DATA_MOROES, NOT_STARTED);
}
void StartEvent()
{
- instance->SetData(TYPE_MOROES, IN_PROGRESS);
+ instance->SetBossState(DATA_MOROES, IN_PROGRESS);
DoZoneInCombat();
}
@@ -171,7 +171,7 @@ public:
{
Talk(SAY_DEATH);
- instance->SetData(TYPE_MOROES, DONE);
+ instance->SetBossState(DATA_MOROES, DONE);
DeSpawnAdds();
@@ -257,12 +257,6 @@ public:
if (!UpdateVictim())
return;
- if (!instance->GetData(TYPE_MOROES))
- {
- EnterEvadeMode();
- return;
- }
-
if (!Enrage && HealthBelowPct(30))
{
DoCast(me, SPELL_FRENZY);
@@ -347,7 +341,7 @@ struct boss_moroes_guestAI : public ScriptedAI
void Reset() override
{
- instance->SetData(TYPE_MOROES, NOT_STARTED);
+ instance->SetBossState(DATA_MOROES, NOT_STARTED);
}
void AcquireGUID()
@@ -373,7 +367,7 @@ struct boss_moroes_guestAI : public ScriptedAI
void UpdateAI(uint32 /*diff*/) override
{
- if (!instance->GetData(TYPE_MOROES))
+ if (instance->GetBossState(DATA_MOROES) != IN_PROGRESS)
EnterEvadeMode();
DoMeleeAttackIfReady();
diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp
index 6f5f2b8f65f..7d7c60ac419 100644
--- a/src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp
+++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp
@@ -143,10 +143,10 @@ public:
me->SetWalk(false);
me->setActive(true);
- if (instance->GetData(TYPE_NIGHTBANE) == DONE || instance->GetData(TYPE_NIGHTBANE) == IN_PROGRESS)
+ if (instance->GetBossState(DATA_NIGHTBANE) == DONE || instance->GetBossState(DATA_NIGHTBANE) == IN_PROGRESS)
me->DisappearAndDie();
else
- instance->SetData(TYPE_NIGHTBANE, NOT_STARTED);
+ instance->SetBossState(DATA_NIGHTBANE, NOT_STARTED);
HandleTerraceDoors(true);
@@ -165,10 +165,10 @@ public:
void EnterCombat(Unit* /*who*/) override
{
- instance->SetData(TYPE_NIGHTBANE, IN_PROGRESS);
+ instance->SetBossState(DATA_NIGHTBANE, IN_PROGRESS);
HandleTerraceDoors(false);
- Talk(YELL_AGGRO);
+ Talk(YELL_AGGRO);
}
void AttackStart(Unit* who) override
@@ -179,7 +179,7 @@ public:
void JustDied(Unit* /*killer*/) override
{
- instance->SetData(TYPE_NIGHTBANE, DONE);
+ instance->SetBossState(DATA_NIGHTBANE, DONE);
HandleTerraceDoors(true);
}
diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp
index 450678a0f86..17a23a0b2e7 100644
--- a/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp
+++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp
@@ -154,7 +154,7 @@ public:
Initialize();
// Not in progress
- instance->SetData(TYPE_ARAN, NOT_STARTED);
+ instance->SetBossState(DATA_ARAN, NOT_STARTED);
instance->HandleGameObject(instance->GetGuidData(DATA_GO_LIBRARY_DOOR), true);
}
@@ -167,7 +167,7 @@ public:
{
Talk(SAY_DEATH);
- instance->SetData(TYPE_ARAN, DONE);
+ instance->SetBossState(DATA_ARAN, DONE);
instance->HandleGameObject(instance->GetGuidData(DATA_GO_LIBRARY_DOOR), true);
}
@@ -175,7 +175,7 @@ public:
{
Talk(SAY_AGGRO);
- instance->SetData(TYPE_ARAN, IN_PROGRESS);
+ instance->SetBossState(DATA_ARAN, IN_PROGRESS);
instance->HandleGameObject(instance->GetGuidData(DATA_GO_LIBRARY_DOOR), false);
}
diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp
index 7bc835dcced..2e33f0933e3 100644
--- a/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp
+++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp
@@ -61,7 +61,6 @@ enum Creatures
NPC_DEMONCHAINS = 17248,
NPC_FIENDISHIMP = 17267,
NPC_PORTAL = 17265,
- NPC_KILREK = 17229
};
@@ -316,7 +315,7 @@ public:
Initialize();
- instance->SetData(TYPE_TERESTIAN, NOT_STARTED);
+ instance->SetBossState(DATA_TERESTIAN, NOT_STARTED);
me->RemoveAurasDueToSpell(SPELL_BROKEN_PACT);
@@ -371,7 +370,7 @@ public:
Talk(SAY_DEATH);
- instance->SetData(TYPE_TERESTIAN, DONE);
+ instance->SetBossState(DATA_TERESTIAN, DONE);
}
void UpdateAI(uint32 diff) override
diff --git a/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp b/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp
index d4d0e6fa70d..3f236c060d7 100644
--- a/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp
+++ b/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp
@@ -674,6 +674,12 @@ public:
void Initialize()
{
+ // Hello, developer from the future! It's me again!
+ // This time, you're fixing Karazhan scripts. Awesome. These are a mess of hacks. An amalgamation of hacks, so to speak. Maybe even a Patchwerk thereof.
+ // Anyway, I digress.
+ // @todo This line below is obviously a hack. Duh. I'm just coming in here to hackfix the encounter to actually be completable.
+ // It needs a rewrite. Badly. Please, take good care of it.
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE);
CycloneTimer = 30000;
ChainLightningTimer = 10000;
}
@@ -701,20 +707,12 @@ public:
void EnterCombat(Unit* /*who*/) override
{
Talk(SAY_CRONE_AGGRO);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_CRONE_DEATH);
-
- instance->SetData(TYPE_OPERA, DONE);
- instance->HandleGameObject(instance->GetGuidData(DATA_GO_STAGEDOORLEFT), true);
- instance->HandleGameObject(instance->GetGuidData(DATA_GO_STAGEDOORRIGHT), true);
-
- if (GameObject* pSideEntrance = instance->instance->GetGameObject(instance->GetGuidData(DATA_GO_SIDE_ENTRANCE_DOOR)))
- pSideEntrance->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
+ instance->SetBossState(DATA_OPERA_PERFORMANCE, DONE);
}
void UpdateAI(uint32 diff) override
@@ -722,9 +720,6 @@ public:
if (!UpdateVictim())
return;
- if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
-
if (CycloneTimer <= diff)
{
if (Creature* Cyclone = DoSpawnCreature(CREATURE_CYCLONE, float(urand(0, 9)), float(urand(0, 9)), 0, 0, TEMPSUMMON_TIMED_DESPAWN, 15000))
@@ -908,13 +903,7 @@ public:
void JustDied(Unit* /*killer*/) override
{
DoPlaySoundToSet(me, SOUND_WOLF_DEATH);
-
- instance->SetData(TYPE_OPERA, DONE);
- instance->HandleGameObject(instance->GetGuidData(DATA_GO_STAGEDOORLEFT), true);
- instance->HandleGameObject(instance->GetGuidData(DATA_GO_STAGEDOORRIGHT), true);
-
- if (GameObject* pSideEntrance = instance->instance->GetGameObject(instance->GetGuidData(DATA_GO_SIDE_ENTRANCE_DOOR)))
- pSideEntrance->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
+ instance->SetBossState(DATA_OPERA_PERFORMANCE, DONE);
}
void UpdateAI(uint32 diff) override
@@ -1158,12 +1147,7 @@ public:
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_JULIANNE_DEATH02);
-
- instance->SetData(TYPE_OPERA, DONE);
- instance->HandleGameObject(instance->GetGuidData(DATA_GO_STAGEDOORLEFT), true);
- instance->HandleGameObject(instance->GetGuidData(DATA_GO_STAGEDOORRIGHT), true);
- if (GameObject* pSideEntrance = instance->instance->GetGameObject(instance->GetGuidData(DATA_GO_SIDE_ENTRANCE_DOOR)))
- pSideEntrance->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
+ instance->SetBossState(DATA_OPERA_PERFORMANCE, DONE);
}
void KilledUnit(Unit* /*victim*/) override
@@ -1316,13 +1300,7 @@ public:
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_ROMULO_DEATH);
-
- instance->SetData(TYPE_OPERA, DONE);
- instance->HandleGameObject(instance->GetGuidData(DATA_GO_STAGEDOORLEFT), true);
- instance->HandleGameObject(instance->GetGuidData(DATA_GO_STAGEDOORRIGHT), true);
-
- if (GameObject* pSideEntrance = instance->instance->GetGameObject(instance->GetGuidData(DATA_GO_SIDE_ENTRANCE_DOOR)))
- pSideEntrance->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
+ instance->SetBossState(DATA_OPERA_PERFORMANCE, DONE);
}
void KilledUnit(Unit* /*victim*/) override
diff --git a/src/server/scripts/EasternKingdoms/Karazhan/instance_karazhan.cpp b/src/server/scripts/EasternKingdoms/Karazhan/instance_karazhan.cpp
index b725f421c8f..ad403e6aeed 100644
--- a/src/server/scripts/EasternKingdoms/Karazhan/instance_karazhan.cpp
+++ b/src/server/scripts/EasternKingdoms/Karazhan/instance_karazhan.cpp
@@ -27,8 +27,6 @@ EndScriptData */
#include "InstanceScript.h"
#include "karazhan.h"
-#define MAX_ENCOUNTER 12
-
/*
0 - Attumen + Midnight (optional)
1 - Moroes
@@ -47,8 +45,8 @@ EndScriptData */
const Position OptionalSpawn[] =
{
{ -10960.981445f, -1940.138428f, 46.178097f, 4.12f }, // Hyakiss the Lurker
- { -10899.903320f, -2085.573730f, 49.474449f, 1.38f }, // Rokad the Ravager
- { -10945.769531f, -2040.153320f, 49.474438f, 0.077f } // Shadikith the Glider
+ { -10945.769531f, -2040.153320f, 49.474438f, 0.077f }, // Shadikith the Glider
+ { -10899.903320f, -2085.573730f, 49.474449f, 1.38f } // Rokad the Ravager
};
class instance_karazhan : public InstanceMapScript
@@ -66,53 +64,27 @@ public:
instance_karazhan_InstanceMapScript(Map* map) : InstanceScript(map)
{
SetHeaders(DataHeader);
- memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
+ SetBossNumber(EncounterCount);
// 1 - OZ, 2 - HOOD, 3 - RAJ, this never gets altered.
- m_uiOperaEvent = urand(1, 3);
- m_uiOzDeathCount = 0;
+ OperaEvent = urand(EVENT_OZ, EVENT_RAJ);
+ OzDeathCount = 0;
OptionalBossCount = 0;
}
- uint32 m_auiEncounter[MAX_ENCOUNTER];
- std::string strSaveData;
-
- uint32 m_uiOperaEvent;
- uint32 m_uiOzDeathCount;
- uint32 OptionalBossCount;
-
- ObjectGuid m_uiCurtainGUID;
- ObjectGuid m_uiStageDoorLeftGUID;
- ObjectGuid m_uiStageDoorRightGUID;
- ObjectGuid m_uiKilrekGUID;
- ObjectGuid m_uiTerestianGUID;
- ObjectGuid m_uiMoroesGUID;
- ObjectGuid m_uiLibraryDoor; // Door at Shade of Aran
- ObjectGuid m_uiMassiveDoor; // Door at Netherspite
- ObjectGuid m_uiSideEntranceDoor; // Side Entrance
- ObjectGuid m_uiGamesmansDoor; // Door before Chess
- ObjectGuid m_uiGamesmansExitDoor; // Door after Chess
- ObjectGuid m_uiNetherspaceDoor; // Door at Malchezaar
- ObjectGuid MastersTerraceDoor[2];
- ObjectGuid ImageGUID;
- ObjectGuid DustCoveredChest;
-
- bool IsEncounterInProgress() const override
- {
- for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
- if (m_auiEncounter[i] == IN_PROGRESS)
- return true;
-
- return false;
- }
-
void OnCreatureCreate(Creature* creature) override
{
switch (creature->GetEntry())
{
- case 17229: m_uiKilrekGUID = creature->GetGUID(); break;
- case 15688: m_uiTerestianGUID = creature->GetGUID(); break;
- case 15687: m_uiMoroesGUID = creature->GetGUID(); break;
+ case NPC_KILREK:
+ KilrekGUID = creature->GetGUID();
+ break;
+ case NPC_TERESTIAN_ILLHOOF:
+ TerestianGUID = creature->GetGUID();
+ break;
+ case NPC_MOROES:
+ MoroesGUID = creature->GetGUID();
+ break;
}
}
@@ -132,130 +104,129 @@ public:
case NPC_PHASE_HOUND:
case NPC_DREADBEAST:
case NPC_SHADOWBEAST:
- SetData(TYPE_OPTIONAL_BOSS, NOT_STARTED);
- break;
- default:
- break;
- }
- }
-
- void SetData(uint32 type, uint32 uiData) override
- {
- switch (type)
- {
- case TYPE_ATTUMEN: m_auiEncounter[0] = uiData; break;
- case TYPE_MOROES:
- if (m_auiEncounter[1] == DONE)
- break;
- m_auiEncounter[1] = uiData;
- break;
- case TYPE_MAIDEN: m_auiEncounter[2] = uiData; break;
- case TYPE_OPTIONAL_BOSS:
- m_auiEncounter[3] = uiData;
- if (uiData == NOT_STARTED)
+ if (GetBossState(DATA_OPTIONAL_BOSS) == TO_BE_DECIDED)
{
++OptionalBossCount;
- if (OptionalBossCount == 50)
+ if (OptionalBossCount == OPTIONAL_BOSS_REQUIRED_DEATH_COUNT)
{
- switch (urand(0, 2))
+ switch (urand(NPC_HYAKISS_THE_LURKER, NPC_ROKAD_THE_RAVAGER))
{
- case 0:
+ case NPC_HYAKISS_THE_LURKER:
instance->SummonCreature(NPC_HYAKISS_THE_LURKER, OptionalSpawn[0]);
break;
- case 1:
- instance->SummonCreature(NPC_ROKAD_THE_RAVAGER, OptionalSpawn[1]);
+ case NPC_SHADIKITH_THE_GLIDER:
+ instance->SummonCreature(NPC_SHADIKITH_THE_GLIDER, OptionalSpawn[1]);
break;
- case 2:
- instance->SummonCreature(NPC_SHADIKITH_THE_GLIDER, OptionalSpawn[2]);
+ case NPC_ROKAD_THE_RAVAGER:
+ instance->SummonCreature(NPC_ROKAD_THE_RAVAGER, OptionalSpawn[2]);
break;
}
}
}
break;
- case TYPE_OPERA:
- m_auiEncounter[4] = uiData;
- if (uiData == DONE)
- UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, 16812, NULL);
- break;
- case TYPE_CURATOR: m_auiEncounter[5] = uiData; break;
- case TYPE_ARAN: m_auiEncounter[6] = uiData; break;
- case TYPE_TERESTIAN: m_auiEncounter[7] = uiData; break;
- case TYPE_NETHERSPITE: m_auiEncounter[8] = uiData; break;
- case TYPE_CHESS:
- if (uiData == DONE)
- DoRespawnGameObject(DustCoveredChest, DAY);
- m_auiEncounter[9] = uiData;
- break;
- case TYPE_MALCHEZZAR: m_auiEncounter[10] = uiData; break;
- case TYPE_NIGHTBANE:
- if (m_auiEncounter[11] != DONE)
- m_auiEncounter[11] = uiData;
- break;
- case DATA_OPERA_OZ_DEATHCOUNT:
- if (uiData == SPECIAL)
- ++m_uiOzDeathCount;
- else if (uiData == IN_PROGRESS)
- m_uiOzDeathCount = 0;
+ default:
break;
}
+ }
- if (uiData == DONE)
+ void SetData(uint32 type, uint32 data) override
+ {
+ switch (type)
{
- OUT_SAVE_INST_DATA;
-
- std::ostringstream saveStream;
- saveStream << m_auiEncounter[0] << ' ' << m_auiEncounter[1] << ' ' << m_auiEncounter[2] << ' '
- << m_auiEncounter[3] << ' ' << m_auiEncounter[4] << ' ' << m_auiEncounter[5] << ' ' << m_auiEncounter[6] << ' '
- << m_auiEncounter[7] << ' ' << m_auiEncounter[8] << ' ' << m_auiEncounter[9] << ' ' << m_auiEncounter[10] << ' ' << m_auiEncounter[11];
+ case DATA_OPERA_OZ_DEATHCOUNT:
+ if (data == SPECIAL)
+ ++OzDeathCount;
+ else if (data == IN_PROGRESS)
+ OzDeathCount = 0;
+ break;
+ }
+ }
- strSaveData = saveStream.str();
+ bool SetBossState(uint32 type, EncounterState state) override
+ {
+ if (!InstanceScript::SetBossState(type, state))
+ return false;
- SaveToDB();
- OUT_SAVE_INST_DATA_COMPLETE;
+ switch (type)
+ {
+ case DATA_OPERA_PERFORMANCE:
+ if (state == DONE)
+ {
+ HandleGameObject(StageDoorLeftGUID, true);
+ HandleGameObject(StageDoorRightGUID, true);
+ if (GameObject* sideEntrance = instance->GetGameObject(SideEntranceDoor))
+ sideEntrance->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
+ UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, 16812, NULL);
+ }
+ break;
+ case DATA_CHESS:
+ if (state == DONE)
+ DoRespawnGameObject(DustCoveredChest, DAY);
+ break;
+ default:
+ break;
}
+
+ return true;
}
- void SetGuidData(uint32 identifier, ObjectGuid data) override
+ void SetGuidData(uint32 type, ObjectGuid data) override
{
- switch (identifier)
- {
- case DATA_IMAGE_OF_MEDIVH: ImageGUID = data;
- }
+ if (type == DATA_IMAGE_OF_MEDIVH)
+ ImageGUID = data;
}
void OnGameObjectCreate(GameObject* go) override
{
switch (go->GetEntry())
{
- case 183932: m_uiCurtainGUID = go->GetGUID(); break;
- case 184278:
- m_uiStageDoorLeftGUID = go->GetGUID();
- if (m_auiEncounter[4] == DONE)
+ case GO_STAGE_CURTAIN:
+ CurtainGUID = go->GetGUID();
+ break;
+ case GO_STAGE_DOOR_LEFT:
+ StageDoorLeftGUID = go->GetGUID();
+ if (GetBossState(DATA_OPERA_PERFORMANCE) == DONE)
go->SetGoState(GO_STATE_ACTIVE);
break;
- case 184279:
- m_uiStageDoorRightGUID = go->GetGUID();
- if (m_auiEncounter[4] == DONE)
+ case GO_STAGE_DOOR_RIGHT:
+ StageDoorRightGUID = go->GetGUID();
+ if (GetBossState(DATA_OPERA_PERFORMANCE) == DONE)
go->SetGoState(GO_STATE_ACTIVE);
break;
- case 184517: m_uiLibraryDoor = go->GetGUID(); break;
- case 185521: m_uiMassiveDoor = go->GetGUID(); break;
- case 184276: m_uiGamesmansDoor = go->GetGUID(); break;
- case 184277: m_uiGamesmansExitDoor = go->GetGUID(); break;
- case 185134: m_uiNetherspaceDoor = go->GetGUID(); break;
- case 184274: MastersTerraceDoor[0] = go->GetGUID(); break;
- case 184280: MastersTerraceDoor[1] = go->GetGUID(); break;
- case 184275:
- m_uiSideEntranceDoor = go->GetGUID();
- if (m_auiEncounter[4] == DONE)
+ case GO_PRIVATE_LIBRARY_DOOR:
+ LibraryDoor = go->GetGUID();
+ break;
+ case GO_MASSIVE_DOOR:
+ MassiveDoor = go->GetGUID();
+ break;
+ case GO_GAMESMAN_HALL_DOOR:
+ GamesmansDoor = go->GetGUID();
+ break;
+ case GO_GAMESMAN_HALL_EXIT_DOOR:
+ GamesmansExitDoor = go->GetGUID();
+ break;
+ case GO_NETHERSPACE_DOOR:
+ NetherspaceDoor = go->GetGUID();
+ break;
+ case GO_MASTERS_TERRACE_DOOR:
+ MastersTerraceDoor[0] = go->GetGUID();
+ break;
+ case GO_MASTERS_TERRACE_DOOR2:
+ MastersTerraceDoor[1] = go->GetGUID();
+ break;
+ case GO_SIDE_ENTRANCE_DOOR:
+ SideEntranceDoor = go->GetGUID();
+ if (GetBossState(DATA_OPERA_PERFORMANCE) == DONE)
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
else
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
break;
- case 185119: DustCoveredChest = go->GetGUID(); break;
+ case GO_DUST_COVERED_CHEST:
+ DustCoveredChest = go->GetGUID();
+ break;
}
- switch (m_uiOperaEvent)
+ switch (OperaEvent)
{
/// @todo Set Object visibilities for Opera based on performance
case EVENT_OZ:
@@ -269,77 +240,77 @@ public:
}
}
- std::string GetSaveData() override
- {
- return strSaveData;
- }
-
- uint32 GetData(uint32 uiData) const override
+ uint32 GetData(uint32 type) const override
{
- switch (uiData)
+ switch (type)
{
- case TYPE_ATTUMEN: return m_auiEncounter[0];
- case TYPE_MOROES: return m_auiEncounter[1];
- case TYPE_MAIDEN: return m_auiEncounter[2];
- case TYPE_OPTIONAL_BOSS: return m_auiEncounter[3];
- case TYPE_OPERA: return m_auiEncounter[4];
- case TYPE_CURATOR: return m_auiEncounter[5];
- case TYPE_ARAN: return m_auiEncounter[6];
- case TYPE_TERESTIAN: return m_auiEncounter[7];
- case TYPE_NETHERSPITE: return m_auiEncounter[8];
- case TYPE_CHESS: return m_auiEncounter[9];
- case TYPE_MALCHEZZAR: return m_auiEncounter[10];
- case TYPE_NIGHTBANE: return m_auiEncounter[11];
- case DATA_OPERA_PERFORMANCE: return m_uiOperaEvent;
- case DATA_OPERA_OZ_DEATHCOUNT: return m_uiOzDeathCount;
+ case DATA_OPERA_PERFORMANCE:
+ return OperaEvent;
+ case DATA_OPERA_OZ_DEATHCOUNT:
+ return OzDeathCount;
}
return 0;
}
- ObjectGuid GetGuidData(uint32 uiData) const override
+ ObjectGuid GetGuidData(uint32 type) const override
{
- switch (uiData)
+ switch (type)
{
- case DATA_KILREK: return m_uiKilrekGUID;
- case DATA_TERESTIAN: return m_uiTerestianGUID;
- case DATA_MOROES: return m_uiMoroesGUID;
- case DATA_GO_STAGEDOORLEFT: return m_uiStageDoorLeftGUID;
- case DATA_GO_STAGEDOORRIGHT: return m_uiStageDoorRightGUID;
- case DATA_GO_CURTAINS: return m_uiCurtainGUID;
- case DATA_GO_LIBRARY_DOOR: return m_uiLibraryDoor;
- case DATA_GO_MASSIVE_DOOR: return m_uiMassiveDoor;
- case DATA_GO_SIDE_ENTRANCE_DOOR: return m_uiSideEntranceDoor;
- case DATA_GO_GAME_DOOR: return m_uiGamesmansDoor;
- case DATA_GO_GAME_EXIT_DOOR: return m_uiGamesmansExitDoor;
- case DATA_GO_NETHER_DOOR: return m_uiNetherspaceDoor;
- case DATA_MASTERS_TERRACE_DOOR_1: return MastersTerraceDoor[0];
- case DATA_MASTERS_TERRACE_DOOR_2: return MastersTerraceDoor[1];
- case DATA_IMAGE_OF_MEDIVH: return ImageGUID;
+ case DATA_KILREK:
+ return KilrekGUID;
+ case DATA_TERESTIAN:
+ return TerestianGUID;
+ case DATA_MOROES:
+ return MoroesGUID;
+ case DATA_GO_STAGEDOORLEFT:
+ return StageDoorLeftGUID;
+ case DATA_GO_STAGEDOORRIGHT:
+ return StageDoorRightGUID;
+ case DATA_GO_CURTAINS:
+ return CurtainGUID;
+ case DATA_GO_LIBRARY_DOOR:
+ return LibraryDoor;
+ case DATA_GO_MASSIVE_DOOR:
+ return MassiveDoor;
+ case DATA_GO_SIDE_ENTRANCE_DOOR:
+ return SideEntranceDoor;
+ case DATA_GO_GAME_DOOR:
+ return GamesmansDoor;
+ case DATA_GO_GAME_EXIT_DOOR:
+ return GamesmansExitDoor;
+ case DATA_GO_NETHER_DOOR:
+ return NetherspaceDoor;
+ case DATA_MASTERS_TERRACE_DOOR_1:
+ return MastersTerraceDoor[0];
+ case DATA_MASTERS_TERRACE_DOOR_2:
+ return MastersTerraceDoor[1];
+ case DATA_IMAGE_OF_MEDIVH:
+ return ImageGUID;
}
return ObjectGuid::Empty;
}
- void Load(char const* chrIn) override
- {
- if (!chrIn)
- {
- OUT_LOAD_INST_DATA_FAIL;
- return;
- }
-
- OUT_LOAD_INST_DATA(chrIn);
- std::istringstream loadStream(chrIn);
-
- loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3]
- >> m_auiEncounter[4] >> m_auiEncounter[5] >> m_auiEncounter[6] >> m_auiEncounter[7]
- >> m_auiEncounter[8] >> m_auiEncounter[9] >> m_auiEncounter[10] >> m_auiEncounter[11];
- for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
- if (m_auiEncounter[i] == IN_PROGRESS) // Do not load an encounter as "In Progress" - reset it instead.
- m_auiEncounter[i] = NOT_STARTED;
- OUT_LOAD_INST_DATA_COMPLETE;
- }
+ private:
+ uint32 OperaEvent;
+ uint32 OzDeathCount;
+ uint32 OptionalBossCount;
+ ObjectGuid CurtainGUID;
+ ObjectGuid StageDoorLeftGUID;
+ ObjectGuid StageDoorRightGUID;
+ ObjectGuid KilrekGUID;
+ ObjectGuid TerestianGUID;
+ ObjectGuid MoroesGUID;
+ ObjectGuid LibraryDoor; // Door at Shade of Aran
+ ObjectGuid MassiveDoor; // Door at Netherspite
+ ObjectGuid SideEntranceDoor; // Side Entrance
+ ObjectGuid GamesmansDoor; // Door before Chess
+ ObjectGuid GamesmansExitDoor; // Door after Chess
+ ObjectGuid NetherspaceDoor; // Door at Malchezaar
+ ObjectGuid MastersTerraceDoor[2];
+ ObjectGuid ImageGUID;
+ ObjectGuid DustCoveredChest;
};
};
diff --git a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp
index aa2da8cc391..4aef3c8d4a3 100644
--- a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp
+++ b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp
@@ -168,7 +168,7 @@ public:
void StartEvent()
{
- instance->SetData(TYPE_OPERA, IN_PROGRESS);
+ instance->SetBossState(DATA_OPERA_PERFORMANCE, IN_PROGRESS);
//resets count for this event, in case earlier failed
if (m_uiEventId == EVENT_OZ)
@@ -377,7 +377,7 @@ public:
if (InstanceScript* instance = creature->GetInstanceScript())
{
// Check for death of Moroes and if opera event is not done already
- if (instance->GetData(TYPE_MOROES) == DONE && instance->GetData(TYPE_OPERA) != DONE)
+ if (instance->GetBossState(DATA_MOROES) == DONE && instance->GetBossState(DATA_OPERA_PERFORMANCE) != DONE)
{
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, OZ_GOSSIP1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
diff --git a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.h b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.h
index 4d86492257c..05de9e43a91 100644
--- a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.h
+++ b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.h
@@ -21,27 +21,26 @@
#define DataHeader "KZ"
+uint32 const EncounterCount = 12;
+
enum DataTypes
{
- TYPE_ATTUMEN = 1,
- TYPE_MOROES = 2,
- TYPE_MAIDEN = 3,
- TYPE_OPTIONAL_BOSS = 4,
- TYPE_OPERA = 5,
- TYPE_CURATOR = 6,
- TYPE_ARAN = 7,
- TYPE_TERESTIAN = 8,
- TYPE_NETHERSPITE = 9,
- TYPE_CHESS = 10,
- TYPE_MALCHEZZAR = 11,
- TYPE_NIGHTBANE = 12,
+ DATA_ATTUMEN = 0,
+ DATA_MOROES = 1,
+ DATA_MAIDEN_OF_VIRTUE = 2,
+ DATA_OPTIONAL_BOSS = 3,
+ DATA_OPERA_PERFORMANCE = 4,
+ DATA_CURATOR = 5,
+ DATA_ARAN = 6,
+ DATA_TERESTIAN = 7,
+ DATA_NETHERSPITE = 8,
+ DATA_CHESS = 9,
+ DATA_MALCHEZZAR = 10,
+ DATA_NIGHTBANE = 11,
- DATA_OPERA_PERFORMANCE = 13,
DATA_OPERA_OZ_DEATHCOUNT = 14,
DATA_KILREK = 15,
- DATA_TERESTIAN = 16,
- DATA_MOROES = 17,
DATA_GO_CURTAINS = 18,
DATA_GO_STAGEDOORLEFT = 19,
DATA_GO_STAGEDOORRIGHT = 20,
@@ -69,6 +68,8 @@ enum MiscCreatures
NPC_HYAKISS_THE_LURKER = 16179,
NPC_ROKAD_THE_RAVAGER = 16181,
NPC_SHADIKITH_THE_GLIDER = 16180,
+ NPC_TERESTIAN_ILLHOOF = 15688,
+ NPC_MOROES = 15687,
// Trash
NPC_COLDMIST_WIDOW = 16171,
@@ -78,6 +79,29 @@ enum MiscCreatures
NPC_GREATER_SHADOWBAT = 16174,
NPC_PHASE_HOUND = 16178,
NPC_DREADBEAST = 16177,
- NPC_SHADOWBEAST = 16176
+ NPC_SHADOWBEAST = 16176,
+ NPC_KILREK = 17229
+};
+
+enum GameObjectIds
+{
+ GO_STAGE_CURTAIN = 183932,
+ GO_STAGE_DOOR_LEFT = 184278,
+ GO_STAGE_DOOR_RIGHT = 184279,
+ GO_PRIVATE_LIBRARY_DOOR = 184517,
+ GO_MASSIVE_DOOR = 185521,
+ GO_GAMESMAN_HALL_DOOR = 184276,
+ GO_GAMESMAN_HALL_EXIT_DOOR = 184277,
+ GO_NETHERSPACE_DOOR = 185134,
+ GO_MASTERS_TERRACE_DOOR = 184274,
+ GO_MASTERS_TERRACE_DOOR2 = 184280,
+ GO_SIDE_ENTRANCE_DOOR = 184275,
+ GO_DUST_COVERED_CHEST = 185119
};
+
+enum Misc
+{
+ OPTIONAL_BOSS_REQUIRED_DEATH_COUNT = 50
+};
+
#endif
diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp
index 53b6d2be8dd..9abd0c049d8 100644
--- a/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp
@@ -109,7 +109,7 @@ public:
FlyBackTimer = 4500;
break;
case 2:
- if (!player->isResurrectRequested())
+ if (!player->IsResurrectRequested())
{
me->HandleEmoteCommand(EMOTE_ONESHOT_CUSTOM_SPELL_01);
DoCast(player, SPELL_REVIVE, true);
diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp
index dff0a66cec0..74b300919d8 100644
--- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp
@@ -134,8 +134,6 @@ static char const* Text[]=
"Now, know demise!"
};
-#define EMOTE_LAUGHS "Headless Horseman laughs" // needs assigned to db.
-
class npc_wisp_invis : public CreatureScript
{
public:
@@ -347,7 +345,6 @@ public:
Creature* speaker = DoSpawnCreature(HELPER, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 1000);
if (speaker)
speaker->CastSpell(speaker, SPELL_HEAD_SPEAKS, false);
- me->TextEmote(EMOTE_LAUGHS);
}
else laugh -= diff;
}
@@ -724,7 +721,6 @@ public:
if (laugh <= diff)
{
laugh = urand(11000, 22000);
- me->TextEmote(EMOTE_LAUGHS);
DoPlaySoundToSet(me, RandomLaugh[rand32() % 3]);
}
else laugh -= diff;
diff --git a/src/server/scripts/EasternKingdoms/SunkenTemple/instance_sunken_temple.cpp b/src/server/scripts/EasternKingdoms/SunkenTemple/instance_sunken_temple.cpp
index 118d28e2142..6a6a0b0994b 100644
--- a/src/server/scripts/EasternKingdoms/SunkenTemple/instance_sunken_temple.cpp
+++ b/src/server/scripts/EasternKingdoms/SunkenTemple/instance_sunken_temple.cpp
@@ -35,15 +35,25 @@ enum Gameobject
GO_ATALAI_STATUE4 = 148833,
GO_ATALAI_STATUE5 = 148834,
GO_ATALAI_STATUE6 = 148835,
- GO_ATALAI_IDOL = 148836,
GO_ATALAI_LIGHT1 = 148883,
GO_ATALAI_LIGHT2 = 148937
-
};
enum CreatureIds
{
- NPC_MALFURION_STORMRAGE = 15362
+ NPC_ATALALARION = 8580
+};
+
+static Position const atalalarianPos = { -466.5134f, 95.19822f, -189.6463f, 0.03490658f };
+static uint8 const nStatues = 6;
+static Position const statuePositions[nStatues]
+{
+ { -515.553f, 95.25821f, -173.707f, 0.0f },
+ { -419.8487f, 94.48368f, -173.707f, 0.0f },
+ { -491.4003f, 135.9698f, -173.707f, 0.0f },
+ { -491.4909f, 53.48179f, -173.707f, 0.0f },
+ { -443.8549f, 136.1007f, -173.707f, 0.0f },
+ { -443.4171f, 53.83124f, -173.707f, 0.0f }
};
class instance_sunken_temple : public InstanceMapScript
@@ -77,7 +87,6 @@ public:
ObjectGuid GOAtalaiStatue4;
ObjectGuid GOAtalaiStatue5;
ObjectGuid GOAtalaiStatue6;
- ObjectGuid GOAtalaiIdol;
uint32 State;
@@ -98,7 +107,6 @@ public:
case GO_ATALAI_STATUE4: GOAtalaiStatue4 = go->GetGUID(); break;
case GO_ATALAI_STATUE5: GOAtalaiStatue5 = go->GetGUID(); break;
case GO_ATALAI_STATUE6: GOAtalaiStatue6 = go->GetGUID(); break;
- case GO_ATALAI_IDOL: GOAtalaiIdol = go->GetGUID(); break;
}
}
@@ -155,7 +163,10 @@ public:
if (s1 && s2 && s3 && s4 && s5 && !s6)
{
if (GameObject* pAtalaiStatue6 = instance->GetGameObject(GOAtalaiStatue6))
+ {
UseStatue(pAtalaiStatue6);
+ UseLastStatue(pAtalaiStatue6);
+ }
s6 = true;
State = 0;
}
@@ -169,18 +180,13 @@ public:
go->SetUInt32Value(GAMEOBJECT_FLAGS, 4);
}
- /*
- void UseLastStatue(GameObject* go)
- {
- AtalaiStatue1->SummonGameObject(GO_ATALAI_LIGHT2, AtalaiStatue1->GetPositionX(), AtalaiStatue1->GetPositionY(), AtalaiStatue1->GetPositionZ(), 0, 0, 0, 0, 0, 100);
- AtalaiStatue2->SummonGameObject(GO_ATALAI_LIGHT2, AtalaiStatue2->GetPositionX(), AtalaiStatue2->GetPositionY(), AtalaiStatue2->GetPositionZ(), 0, 0, 0, 0, 0, 100);
- AtalaiStatue3->SummonGameObject(GO_ATALAI_LIGHT2, AtalaiStatue3->GetPositionX(), AtalaiStatue3->GetPositionY(), AtalaiStatue3->GetPositionZ(), 0, 0, 0, 0, 0, 100);
- AtalaiStatue4->SummonGameObject(GO_ATALAI_LIGHT2, AtalaiStatue4->GetPositionX(), AtalaiStatue4->GetPositionY(), AtalaiStatue4->GetPositionZ(), 0, 0, 0, 0, 0, 100);
- AtalaiStatue5->SummonGameObject(GO_ATALAI_LIGHT2, AtalaiStatue5->GetPositionX(), AtalaiStatue5->GetPositionY(), AtalaiStatue5->GetPositionZ(), 0, 0, 0, 0, 0, 100);
- AtalaiStatue6->SummonGameObject(GO_ATALAI_LIGHT2, AtalaiStatue6->GetPositionX(), AtalaiStatue6->GetPositionY(), AtalaiStatue6->GetPositionZ(), 0, 0, 0, 0, 0, 100);
- go->SummonGameObject(148838, -488.997, 96.61, -189.019, -1.52, 0, 0, 0, 0, 100);
- }
- */
+ void UseLastStatue(GameObject* go)
+ {
+ for (uint8 i = 0; i < nStatues; ++i)
+ go->SummonGameObject(GO_ATALAI_LIGHT2, statuePositions[i].GetPositionX(), statuePositions[i].GetPositionY(), statuePositions[i].GetPositionZ(), statuePositions[i].GetOrientation(), 0, 0, 0, 0, 0);
+
+ go->SummonCreature(NPC_ATALALARION, atalalarianPos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 7200);
+ }
void SetData(uint32 type, uint32 data) override
{
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp
index cc55f758a22..5ec57fc44b6 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp
@@ -29,109 +29,104 @@ EndScriptData */
#include "SpellAuraEffects.h"
#include "zulaman.h"
-#define YELL_AGGRO "Da shadow gonna fall on you... "
-#define SOUND_YELL_AGGRO 12041
-#define YELL_SPIRIT_BOLTS "Your soul gonna bleed!"
-#define SOUND_YELL_SPIRIT_BOLTS 12047
-#define YELL_DRAIN_POWER "Darkness comin\' for you"
-#define SOUND_YELL_DRAIN_POWER 12046
-#define YELL_KILL_ONE "Dis a nightmare ya don\' wake up from!"
-#define SOUND_YELL_KILL_ONE 12043
-#define YELL_KILL_TWO "Azzaga choogo zinn!"
-#define SOUND_YELL_KILL_TWO 12044
-#define YELL_DEATH "Dis not... da end of me..."
-#define SOUND_YELL_DEATH 12051
-
+enum Yells
+{
+ YELL_AGGRO = 0,
+ YELL_KILL_ONE = 1,
+ YELL_KILL_TWO = 2,
+ YELL_DRAIN_POWER = 3,
+ YELL_SPIRIT_BOLTS = 4,
+ YELL_DEATH = 5
+};
enum Creatures
{
- NPC_TEMP_TRIGGER = 23920
+ NPC_TEMP_TRIGGER = 23920
};
enum Spells
{
- SPELL_SPIRIT_BOLTS = 43383,
- SPELL_DRAIN_POWER = 44131,
- SPELL_SIPHON_SOUL = 43501,
+ SPELL_SPIRIT_BOLTS = 43383,
+ SPELL_DRAIN_POWER = 44131,
+ SPELL_SIPHON_SOUL = 43501,
// Druid
- SPELL_DR_THORNS = 43420,
- SPELL_DR_LIFEBLOOM = 43421,
- SPELL_DR_MOONFIRE = 43545,
+ SPELL_DR_THORNS = 43420,
+ SPELL_DR_LIFEBLOOM = 43421,
+ SPELL_DR_MOONFIRE = 43545,
// Hunter
- SPELL_HU_EXPLOSIVE_TRAP = 43444,
- SPELL_HU_FREEZING_TRAP = 43447,
- SPELL_HU_SNAKE_TRAP = 43449,
+ SPELL_HU_EXPLOSIVE_TRAP = 43444,
+ SPELL_HU_FREEZING_TRAP = 43447,
+ SPELL_HU_SNAKE_TRAP = 43449,
// Mage
- SPELL_MG_FIREBALL = 41383,
- SPELL_MG_FROST_NOVA = 43426,
- SPELL_MG_ICE_LANCE = 43427,
- SPELL_MG_FROSTBOLT = 43428,
+ SPELL_MG_FIREBALL = 41383,
+ SPELL_MG_FROST_NOVA = 43426,
+ SPELL_MG_ICE_LANCE = 43427,
+ SPELL_MG_FROSTBOLT = 43428,
// Paladin
- SPELL_PA_CONSECRATION = 43429,
- SPELL_PA_AVENGING_WRATH = 43430,
- SPELL_PA_HOLY_LIGHT = 43451,
+ SPELL_PA_CONSECRATION = 43429,
+ SPELL_PA_AVENGING_WRATH = 43430,
+ SPELL_PA_HOLY_LIGHT = 43451,
// Priest
- SPELL_PR_HEAL = 41372,
- SPELL_PR_MIND_BLAST = 41374,
- SPELL_PR_SW_DEATH = 41375,
- SPELL_PR_PSYCHIC_SCREAM = 43432,
- SPELL_PR_MIND_CONTROL = 43550,
- SPELL_PR_PAIN_SUPP = 44416,
+ SPELL_PR_HEAL = 41372,
+ SPELL_PR_MIND_BLAST = 41374,
+ SPELL_PR_SW_DEATH = 41375,
+ SPELL_PR_PSYCHIC_SCREAM = 43432,
+ SPELL_PR_MIND_CONTROL = 43550,
+ SPELL_PR_PAIN_SUPP = 44416,
// Rogue
- SPELL_RO_BLIND = 43433,
- SPELL_RO_SLICE_DICE = 43457,
- SPELL_RO_WOUND_POISON = 43461,
+ SPELL_RO_BLIND = 43433,
+ SPELL_RO_SLICE_DICE = 43457,
+ SPELL_RO_WOUND_POISON = 43461,
// Shaman
- SPELL_SH_CHAIN_LIGHT = 43435,
- SPELL_SH_FIRE_NOVA = 43436,
- SPELL_SH_HEALING_WAVE = 43548,
+ SPELL_SH_CHAIN_LIGHT = 43435,
+ SPELL_SH_FIRE_NOVA = 43436,
+ SPELL_SH_HEALING_WAVE = 43548,
// Warlock
- SPELL_WL_CURSE_OF_DOOM = 43439,
- SPELL_WL_RAIN_OF_FIRE = 43440,
- SPELL_WL_UNSTABLE_AFFL = 43522,
- SPELL_WL_UNSTABLE_AFFL_DISPEL = 43523,
+ SPELL_WL_CURSE_OF_DOOM = 43439,
+ SPELL_WL_RAIN_OF_FIRE = 43440,
+ SPELL_WL_UNSTABLE_AFFL = 43522,
+ SPELL_WL_UNSTABLE_AFFL_DISPEL = 43523,
// Warrior
- SPELL_WR_MORTAL_STRIKE = 43441,
- SPELL_WR_WHIRLWIND = 43442,
- SPELL_WR_SPELL_REFLECT = 43443,
+ SPELL_WR_MORTAL_STRIKE = 43441,
+ SPELL_WR_WHIRLWIND = 43442,
+ SPELL_WR_SPELL_REFLECT = 43443,
// Thurg
- SPELL_BLOODLUST = 43578,
- SPELL_CLEAVE = 15496,
+ SPELL_BLOODLUST = 43578,
+ SPELL_CLEAVE = 15496,
// Gazakroth
- SPELL_FIREBOLT = 43584,
+ SPELL_FIREBOLT = 43584,
// Alyson Antille
- SPELL_FLASH_HEAL = 43575,
- SPELL_DISPEL_MAGIC = 43577,
+ SPELL_FLASH_HEAL = 43575,
+ SPELL_DISPEL_MAGIC = 43577,
// Lord Raadan
- SPELL_FLAME_BREATH = 43582,
- SPELL_THUNDERCLAP = 43583,
+ SPELL_FLAME_BREATH = 43582,
+ SPELL_THUNDERCLAP = 43583,
// Darkheart
- SPELL_PSYCHIC_WAIL = 43590,
+ SPELL_PSYCHIC_WAIL = 43590,
// Slither
- SPELL_VENOM_SPIT = 43579,
+ SPELL_VENOM_SPIT = 43579,
// Fenstalker
- SPELL_VOLATILE_INFECTION = 43586,
+ SPELL_VOLATILE_INFECTION = 43586,
// Koragg
- SPELL_COLD_STARE = 43593,
- SPELL_MIGHTY_BLOW = 43592
-
+ SPELL_COLD_STARE = 43593,
+ SPELL_MIGHTY_BLOW = 43592
};
#define ORIENT 1.5696f
@@ -306,8 +301,7 @@ class boss_hexlord_malacrass : public CreatureScript
instance->SetData(DATA_HEXLORDEVENT, IN_PROGRESS);
DoZoneInCombat();
- me->Yell(YELL_AGGRO, LANG_UNIVERSAL);
- DoPlaySoundToSet(me, SOUND_YELL_AGGRO);
+ Talk(YELL_AGGRO);
for (uint8 i = 0; i < 4; ++i)
{
@@ -327,12 +321,10 @@ class boss_hexlord_malacrass : public CreatureScript
switch (urand(0, 1))
{
case 0:
- me->Yell(YELL_KILL_ONE, LANG_UNIVERSAL);
- DoPlaySoundToSet(me, SOUND_YELL_KILL_ONE);
+ Talk(YELL_KILL_ONE);
break;
case 1:
- me->Yell(YELL_KILL_TWO, LANG_UNIVERSAL);
- DoPlaySoundToSet(me, SOUND_YELL_KILL_TWO);
+ Talk(YELL_KILL_TWO);
break;
}
}
@@ -341,8 +333,7 @@ class boss_hexlord_malacrass : public CreatureScript
{
instance->SetData(DATA_HEXLORDEVENT, DONE);
- me->Yell(YELL_DEATH, LANG_UNIVERSAL);
- DoPlaySoundToSet(me, SOUND_YELL_DEATH);
+ Talk(YELL_DEATH);
for (uint8 i = 0; i < 4; ++i)
{
@@ -415,8 +406,7 @@ class boss_hexlord_malacrass : public CreatureScript
if (DrainPower_Timer <= diff)
{
DoCast(me, SPELL_DRAIN_POWER, true);
- me->Yell(YELL_DRAIN_POWER, LANG_UNIVERSAL);
- DoPlaySoundToSet(me, SOUND_YELL_DRAIN_POWER);
+ Talk(YELL_DRAIN_POWER);
DrainPower_Timer = urand(40000, 55000); // must cast in 60 sec, or buff/debuff will disappear
} else DrainPower_Timer -= diff;
@@ -427,8 +417,7 @@ class boss_hexlord_malacrass : public CreatureScript
else
{
DoCast(me, SPELL_SPIRIT_BOLTS, false);
- me->Yell(YELL_SPIRIT_BOLTS, LANG_UNIVERSAL);
- DoPlaySoundToSet(me, SOUND_YELL_SPIRIT_BOLTS);
+ Talk(YELL_SPIRIT_BOLTS);
SpiritBolts_Timer = 40000;
SiphonSoul_Timer = 10000; // ready to drain
PlayerAbility_Timer = 99999;
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp
index 37505a8b74d..0407cb6cd7c 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp
@@ -30,21 +30,41 @@ EndScriptData */
#include "GridNotifiersImpl.h"
#include "CellImpl.h"
-enum Spells
+enum Yells
{
- SPELL_BERSERK = 45078,
+ YELL_NALORAKK_WAVE1 = 0,
+ YELL_NALORAKK_WAVE2 = 1,
+ YELL_NALORAKK_WAVE3 = 2,
+ YELL_NALORAKK_WAVE4 = 3,
+ YELL_AGGRO = 4,
+ YELL_SURGE = 5,
+ YELL_SHIFTEDTOBEAR = 6,
+ YELL_SHIFTEDTOTROLL = 7,
+ YELL_BERSERK = 8,
+ YELL_KILL_ONE = 9,
+ YELL_KILL_TWO = 10,
+ YELL_DEATH = 11
+
+// Not yet implemented
+// YELL_NALORAKK_EVENT1 = 12,
+// YELL_NALORAKK_EVENT2 = 13
+};
+enum Spells
+{
// Troll form
- SPELL_BRUTALSWIPE = 42384,
- SPELL_MANGLE = 42389,
- SPELL_MANGLEEFFECT = 44955,
- SPELL_SURGE = 42402,
- SPELL_BEARFORM = 42377,
+ SPELL_BRUTALSWIPE = 42384,
+ SPELL_MANGLE = 42389,
+ SPELL_MANGLEEFFECT = 44955,
+ SPELL_SURGE = 42402,
+ SPELL_BEARFORM = 42377,
// Bear form
- SPELL_LACERATINGSLASH = 42395,
- SPELL_RENDFLESH = 42397,
- SPELL_DEAFENINGROAR = 42398
+ SPELL_LACERATINGSLASH = 42395,
+ SPELL_RENDFLESH = 42397,
+ SPELL_DEAFENINGROAR = 42398,
+
+ SPELL_BERSERK = 45078
};
// Trash Waves
@@ -57,45 +77,9 @@ float NalorakkWay[8][3] =
{-79.929f, 1395.958f, 27.31f},
{-80.072f, 1374.555f, 40.87f}, // waypoint 3
{-80.072f, 1314.398f, 40.87f},
- {-80.072f, 1295.775f, 48.60f} // waypoint 4
+ {-80.072f, 1295.775f, 48.60f} // waypoint 4
};
-#define YELL_NALORAKK_WAVE1 "Get da move on, guards! It be killin' time!"
-#define SOUND_NALORAKK_WAVE1 12066
-#define YELL_NALORAKK_WAVE2 "Guards, go already! Who you more afraid of, dem... or me?"
-#define SOUND_NALORAKK_WAVE2 12067
-#define YELL_NALORAKK_WAVE3 "Ride now! Ride out dere and bring me back some heads!"
-#define SOUND_NALORAKK_WAVE3 12068
-#define YELL_NALORAKK_WAVE4 "I be losin' me patience! Go on: make dem wish dey was never born!"
-#define SOUND_NALORAKK_WAVE4 12069
-
-//Unimplemented SoundIDs
-/*
-#define SOUND_NALORAKK_EVENT1 12078
-#define SOUND_NALORAKK_EVENT2 12079
-*/
-
-//General defines
-#define YELL_AGGRO "You be dead soon enough!"
-#define SOUND_YELL_AGGRO 12070
-#define YELL_KILL_ONE "Mua-ha-ha! Now whatchoo got to say?"
-#define SOUND_YELL_KILL_ONE 12075
-#define YELL_KILL_TWO "Da Amani gonna rule again!"
-#define SOUND_YELL_KILL_TWO 12076
-#define YELL_DEATH "I... be waitin' on da udda side...."
-#define SOUND_YELL_DEATH 12077
-#define YELL_BERSERK "You had your chance, now it be too late!" //Never seen this being used, so just guessing from what I hear.
-#define SOUND_YELL_BERSERK 12074
-#define YELL_SURGE "I bring da pain!"
-#define SOUND_YELL_SURGE 12071
-
-#define YELL_SHIFTEDTOTROLL "Make way for Nalorakk!"
-#define SOUND_YELL_TOTROLL 12073
-
-
-#define YELL_SHIFTEDTOBEAR "You call on da beast, you gonna get more dan you bargain for!"
-#define SOUND_YELL_TOBEAR 12072
-
class boss_nalorakk : public CreatureScript
{
public:
@@ -227,8 +211,7 @@ class boss_nalorakk : public CreatureScript
case 0:
if (me->IsWithinDistInMap(who, 50))
{
- me->Yell(YELL_NALORAKK_WAVE1, LANG_UNIVERSAL);
- DoPlaySoundToSet(me, SOUND_NALORAKK_WAVE1);
+ Talk(YELL_NALORAKK_WAVE1);
(*me).GetMotionMaster()->MovePoint(1, NalorakkWay[1][0], NalorakkWay[1][1], NalorakkWay[1][2]);
MovePhase ++;
@@ -240,8 +223,7 @@ class boss_nalorakk : public CreatureScript
case 2:
if (me->IsWithinDistInMap(who, 40))
{
- me->Yell(YELL_NALORAKK_WAVE2, LANG_UNIVERSAL);
- DoPlaySoundToSet(me, SOUND_NALORAKK_WAVE2);
+ Talk(YELL_NALORAKK_WAVE2);
(*me).GetMotionMaster()->MovePoint(3, NalorakkWay[3][0], NalorakkWay[3][1], NalorakkWay[3][2]);
MovePhase ++;
@@ -253,8 +235,7 @@ class boss_nalorakk : public CreatureScript
case 5:
if (me->IsWithinDistInMap(who, 40))
{
- me->Yell(YELL_NALORAKK_WAVE3, LANG_UNIVERSAL);
- DoPlaySoundToSet(me, SOUND_NALORAKK_WAVE3);
+ Talk(YELL_NALORAKK_WAVE3);
(*me).GetMotionMaster()->MovePoint(6, NalorakkWay[6][0], NalorakkWay[6][1], NalorakkWay[6][2]);
MovePhase ++;
@@ -268,8 +249,7 @@ class boss_nalorakk : public CreatureScript
{
SendAttacker(who);
- me->Yell(YELL_NALORAKK_WAVE4, LANG_UNIVERSAL);
- DoPlaySoundToSet(me, SOUND_NALORAKK_WAVE4);
+ Talk(YELL_NALORAKK_WAVE4);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
@@ -287,8 +267,7 @@ class boss_nalorakk : public CreatureScript
{
instance->SetData(DATA_NALORAKKEVENT, IN_PROGRESS);
- me->Yell(YELL_AGGRO, LANG_UNIVERSAL);
- DoPlaySoundToSet(me, SOUND_YELL_AGGRO);
+ Talk(YELL_AGGRO);
DoZoneInCombat();
}
@@ -296,8 +275,7 @@ class boss_nalorakk : public CreatureScript
{
instance->SetData(DATA_NALORAKKEVENT, DONE);
- me->Yell(YELL_DEATH, LANG_UNIVERSAL);
- DoPlaySoundToSet(me, SOUND_YELL_DEATH);
+ Talk(YELL_DEATH);
}
void KilledUnit(Unit* /*victim*/) override
@@ -305,12 +283,10 @@ class boss_nalorakk : public CreatureScript
switch (urand(0, 1))
{
case 0:
- me->Yell(YELL_KILL_ONE, LANG_UNIVERSAL);
- DoPlaySoundToSet(me, SOUND_YELL_KILL_ONE);
+ Talk(YELL_KILL_ONE);
break;
case 1:
- me->Yell(YELL_KILL_TWO, LANG_UNIVERSAL);
- DoPlaySoundToSet(me, SOUND_YELL_KILL_TWO);
+ Talk(YELL_KILL_TWO);
break;
}
}
@@ -373,8 +349,7 @@ class boss_nalorakk : public CreatureScript
if (Berserk_Timer <= diff)
{
DoCast(me, SPELL_BERSERK, true);
- me->Yell(YELL_BERSERK, LANG_UNIVERSAL);
- DoPlaySoundToSet(me, SOUND_YELL_BERSERK);
+ Talk(YELL_BERSERK);
Berserk_Timer = 600000;
} else Berserk_Timer -= diff;
@@ -383,8 +358,7 @@ class boss_nalorakk : public CreatureScript
if (inBearForm)
{
// me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 5122);
- me->Yell(YELL_SHIFTEDTOTROLL, LANG_UNIVERSAL);
- DoPlaySoundToSet(me, SOUND_YELL_TOTROLL);
+ Talk(YELL_SHIFTEDTOTROLL);
me->RemoveAurasDueToSpell(SPELL_BEARFORM);
Surge_Timer = urand(15000, 20000);
BrutalSwipe_Timer = urand(7000, 12000);
@@ -395,8 +369,7 @@ class boss_nalorakk : public CreatureScript
else
{
// me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 0);
- me->Yell(YELL_SHIFTEDTOBEAR, LANG_UNIVERSAL);
- DoPlaySoundToSet(me, SOUND_YELL_TOBEAR);
+ Talk(YELL_SHIFTEDTOBEAR);
DoCast(me, SPELL_BEARFORM, true);
LaceratingSlash_Timer = 2000; // dur 18s
RendFlesh_Timer = 3000; // dur 5s
@@ -426,8 +399,7 @@ class boss_nalorakk : public CreatureScript
if (Surge_Timer <= diff)
{
- me->Yell(YELL_SURGE, LANG_UNIVERSAL);
- DoPlaySoundToSet(me, SOUND_YELL_SURGE);
+ Talk(YELL_SURGE);
Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 45, true);
if (target)
DoCast(target, SPELL_SURGE);
diff --git a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp
new file mode 100644
index 00000000000..8c781bb9001
--- /dev/null
+++ b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp
@@ -0,0 +1,372 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// This is where scripts' loading functions should be declared:
+void AddSC_alterac_valley(); //Alterac Valley
+void AddSC_boss_balinda();
+void AddSC_boss_drekthar();
+void AddSC_boss_galvangar();
+void AddSC_boss_vanndar();
+void AddSC_blackrock_depths(); //Blackrock Depths
+void AddSC_boss_ambassador_flamelash();
+void AddSC_boss_draganthaurissan();
+void AddSC_boss_general_angerforge();
+void AddSC_boss_high_interrogator_gerstahn();
+void AddSC_boss_magmus();
+void AddSC_boss_moira_bronzebeard();
+void AddSC_boss_tomb_of_seven();
+void AddSC_instance_blackrock_depths();
+void AddSC_boss_drakkisath(); //Blackrock Spire
+void AddSC_boss_halycon();
+void AddSC_boss_highlordomokk();
+void AddSC_boss_mothersmolderweb();
+void AddSC_boss_overlordwyrmthalak();
+void AddSC_boss_shadowvosh();
+void AddSC_boss_thebeast();
+void AddSC_boss_warmastervoone();
+void AddSC_boss_quatermasterzigris();
+void AddSC_boss_pyroguard_emberseer();
+void AddSC_boss_gyth();
+void AddSC_boss_rend_blackhand();
+void AddSC_boss_gizrul_the_slavener();
+void AddSC_boss_urok_doomhowl();
+void AddSC_boss_lord_valthalak();
+void AddSC_instance_blackrock_spire();
+void AddSC_boss_razorgore(); //Blackwing lair
+void AddSC_boss_vaelastrasz();
+void AddSC_boss_broodlord();
+void AddSC_boss_firemaw();
+void AddSC_boss_ebonroc();
+void AddSC_boss_flamegor();
+void AddSC_boss_chromaggus();
+void AddSC_boss_nefarian();
+void AddSC_instance_blackwing_lair();
+void AddSC_deadmines(); //Deadmines
+void AddSC_instance_deadmines();
+void AddSC_boss_mr_smite();
+void AddSC_gnomeregan(); //Gnomeregan
+void AddSC_instance_gnomeregan();
+void AddSC_boss_attumen(); //Karazhan
+void AddSC_boss_curator();
+void AddSC_boss_maiden_of_virtue();
+void AddSC_boss_shade_of_aran();
+void AddSC_boss_malchezaar();
+void AddSC_boss_terestian_illhoof();
+void AddSC_boss_moroes();
+void AddSC_bosses_opera();
+void AddSC_boss_netherspite();
+void AddSC_instance_karazhan();
+void AddSC_karazhan();
+void AddSC_boss_nightbane();
+void AddSC_boss_felblood_kaelthas(); // Magister's Terrace
+void AddSC_boss_selin_fireheart();
+void AddSC_boss_vexallus();
+void AddSC_boss_priestess_delrissa();
+void AddSC_instance_magisters_terrace();
+void AddSC_magisters_terrace();
+void AddSC_boss_lucifron(); //Molten core
+void AddSC_boss_magmadar();
+void AddSC_boss_gehennas();
+void AddSC_boss_garr();
+void AddSC_boss_baron_geddon();
+void AddSC_boss_shazzrah();
+void AddSC_boss_golemagg();
+void AddSC_boss_sulfuron();
+void AddSC_boss_majordomo();
+void AddSC_boss_ragnaros();
+void AddSC_instance_molten_core();
+void AddSC_instance_ragefire_chasm(); //Ragefire Chasm
+void AddSC_the_scarlet_enclave(); //Scarlet Enclave
+void AddSC_the_scarlet_enclave_c1();
+void AddSC_the_scarlet_enclave_c2();
+void AddSC_the_scarlet_enclave_c5();
+void AddSC_boss_arcanist_doan(); //Scarlet Monastery
+void AddSC_boss_azshir_the_sleepless();
+void AddSC_boss_bloodmage_thalnos();
+void AddSC_boss_headless_horseman();
+void AddSC_boss_herod();
+void AddSC_boss_high_inquisitor_fairbanks();
+void AddSC_boss_houndmaster_loksey();
+void AddSC_boss_interrogator_vishas();
+void AddSC_boss_scorn();
+void AddSC_instance_scarlet_monastery();
+void AddSC_boss_mograine_and_whitemane();
+void AddSC_boss_darkmaster_gandling(); //Scholomance
+void AddSC_boss_death_knight_darkreaver();
+void AddSC_boss_theolenkrastinov();
+void AddSC_boss_illuciabarov();
+void AddSC_boss_instructormalicia();
+void AddSC_boss_jandicebarov();
+void AddSC_boss_kormok();
+void AddSC_boss_lordalexeibarov();
+void AddSC_boss_lorekeeperpolkelt();
+void AddSC_boss_rasfrost();
+void AddSC_boss_theravenian();
+void AddSC_boss_vectus();
+void AddSC_boss_kirtonos_the_herald();
+void AddSC_instance_scholomance();
+void AddSC_shadowfang_keep(); //Shadowfang keep
+void AddSC_instance_shadowfang_keep();
+void AddSC_boss_magistrate_barthilas(); //Stratholme
+void AddSC_boss_maleki_the_pallid();
+void AddSC_boss_nerubenkan();
+void AddSC_boss_cannon_master_willey();
+void AddSC_boss_baroness_anastari();
+void AddSC_boss_ramstein_the_gorger();
+void AddSC_boss_timmy_the_cruel();
+void AddSC_boss_postmaster_malown();
+void AddSC_boss_baron_rivendare();
+void AddSC_boss_dathrohan_balnazzar();
+void AddSC_boss_order_of_silver_hand();
+void AddSC_instance_stratholme();
+void AddSC_stratholme();
+void AddSC_sunken_temple(); // Sunken Temple
+void AddSC_instance_sunken_temple();
+void AddSC_instance_sunwell_plateau(); //Sunwell Plateau
+void AddSC_boss_kalecgos();
+void AddSC_boss_brutallus();
+void AddSC_boss_felmyst();
+void AddSC_boss_eredar_twins();
+void AddSC_boss_muru();
+void AddSC_boss_kiljaeden();
+void AddSC_sunwell_plateau();
+void AddSC_boss_archaedas(); //Uldaman
+void AddSC_boss_ironaya();
+void AddSC_uldaman();
+void AddSC_instance_uldaman();
+void AddSC_instance_the_stockade(); //The Stockade
+void AddSC_boss_akilzon(); //Zul'Aman
+void AddSC_boss_halazzi();
+void AddSC_boss_hex_lord_malacrass();
+void AddSC_boss_janalai();
+void AddSC_boss_nalorakk();
+void AddSC_boss_zuljin();
+void AddSC_instance_zulaman();
+void AddSC_zulaman();
+void AddSC_boss_jeklik(); //Zul'Gurub
+void AddSC_boss_venoxis();
+void AddSC_boss_marli();
+void AddSC_boss_mandokir();
+void AddSC_boss_gahzranka();
+void AddSC_boss_thekal();
+void AddSC_boss_arlokk();
+void AddSC_boss_jindo();
+void AddSC_boss_hakkar();
+void AddSC_boss_grilek();
+void AddSC_boss_hazzarah();
+void AddSC_boss_renataki();
+void AddSC_boss_wushoolay();
+void AddSC_instance_zulgurub();
+//void AddSC_alterac_mountains();
+void AddSC_arathi_highlands();
+void AddSC_blasted_lands();
+void AddSC_burning_steppes();
+void AddSC_duskwood();
+void AddSC_eastern_plaguelands();
+void AddSC_ghostlands();
+void AddSC_hinterlands();
+void AddSC_isle_of_queldanas();
+void AddSC_loch_modan();
+void AddSC_redridge_mountains();
+void AddSC_silverpine_forest();
+void AddSC_stormwind_city();
+void AddSC_stranglethorn_vale();
+void AddSC_swamp_of_sorrows();
+void AddSC_tirisfal_glades();
+void AddSC_undercity();
+void AddSC_western_plaguelands();
+void AddSC_wetlands();
+
+// The name of this function should match:
+// void Add${NameOfDirectory}Scripts()
+void AddEasternKingdomsScripts()
+{
+ AddSC_alterac_valley(); //Alterac Valley
+ AddSC_boss_balinda();
+ AddSC_boss_drekthar();
+ AddSC_boss_galvangar();
+ AddSC_boss_vanndar();
+ AddSC_blackrock_depths(); //Blackrock Depths
+ AddSC_boss_ambassador_flamelash();
+ AddSC_boss_draganthaurissan();
+ AddSC_boss_general_angerforge();
+ AddSC_boss_high_interrogator_gerstahn();
+ AddSC_boss_magmus();
+ AddSC_boss_moira_bronzebeard();
+ AddSC_boss_tomb_of_seven();
+ AddSC_instance_blackrock_depths();
+ AddSC_boss_drakkisath(); //Blackrock Spire
+ AddSC_boss_halycon();
+ AddSC_boss_highlordomokk();
+ AddSC_boss_mothersmolderweb();
+ AddSC_boss_overlordwyrmthalak();
+ AddSC_boss_shadowvosh();
+ AddSC_boss_thebeast();
+ AddSC_boss_warmastervoone();
+ AddSC_boss_quatermasterzigris();
+ AddSC_boss_pyroguard_emberseer();
+ AddSC_boss_gyth();
+ AddSC_boss_rend_blackhand();
+ AddSC_boss_gizrul_the_slavener();
+ AddSC_boss_urok_doomhowl();
+ AddSC_boss_lord_valthalak();
+ AddSC_instance_blackrock_spire();
+ AddSC_boss_razorgore(); //Blackwing lair
+ AddSC_boss_vaelastrasz();
+ AddSC_boss_broodlord();
+ AddSC_boss_firemaw();
+ AddSC_boss_ebonroc();
+ AddSC_boss_flamegor();
+ AddSC_boss_chromaggus();
+ AddSC_boss_nefarian();
+ AddSC_instance_blackwing_lair();
+ AddSC_deadmines(); //Deadmines
+ AddSC_boss_mr_smite();
+ AddSC_instance_deadmines();
+ AddSC_gnomeregan(); //Gnomeregan
+ AddSC_instance_gnomeregan();
+ AddSC_boss_attumen(); //Karazhan
+ AddSC_boss_curator();
+ AddSC_boss_maiden_of_virtue();
+ AddSC_boss_shade_of_aran();
+ AddSC_boss_malchezaar();
+ AddSC_boss_terestian_illhoof();
+ AddSC_boss_moroes();
+ AddSC_bosses_opera();
+ AddSC_boss_netherspite();
+ AddSC_instance_karazhan();
+ AddSC_karazhan();
+ AddSC_boss_nightbane();
+ AddSC_boss_felblood_kaelthas(); // Magister's Terrace
+ AddSC_boss_selin_fireheart();
+ AddSC_boss_vexallus();
+ AddSC_boss_priestess_delrissa();
+ AddSC_instance_magisters_terrace();
+ AddSC_magisters_terrace();
+ AddSC_boss_lucifron(); //Molten core
+ AddSC_boss_magmadar();
+ AddSC_boss_gehennas();
+ AddSC_boss_garr();
+ AddSC_boss_baron_geddon();
+ AddSC_boss_shazzrah();
+ AddSC_boss_golemagg();
+ AddSC_boss_sulfuron();
+ AddSC_boss_majordomo();
+ AddSC_boss_ragnaros();
+ AddSC_instance_molten_core();
+ AddSC_instance_ragefire_chasm(); //Ragefire Chasm
+ AddSC_the_scarlet_enclave(); //Scarlet Enclave
+ AddSC_the_scarlet_enclave_c1();
+ AddSC_the_scarlet_enclave_c2();
+ AddSC_the_scarlet_enclave_c5();
+ AddSC_boss_arcanist_doan(); //Scarlet Monastery
+ AddSC_boss_azshir_the_sleepless();
+ AddSC_boss_bloodmage_thalnos();
+ AddSC_boss_headless_horseman();
+ AddSC_boss_herod();
+ AddSC_boss_high_inquisitor_fairbanks();
+ AddSC_boss_houndmaster_loksey();
+ AddSC_boss_interrogator_vishas();
+ AddSC_boss_scorn();
+ AddSC_instance_scarlet_monastery();
+ AddSC_boss_mograine_and_whitemane();
+ AddSC_boss_darkmaster_gandling(); //Scholomance
+ AddSC_boss_death_knight_darkreaver();
+ AddSC_boss_theolenkrastinov();
+ AddSC_boss_illuciabarov();
+ AddSC_boss_instructormalicia();
+ AddSC_boss_jandicebarov();
+ AddSC_boss_kormok();
+ AddSC_boss_lordalexeibarov();
+ AddSC_boss_lorekeeperpolkelt();
+ AddSC_boss_rasfrost();
+ AddSC_boss_theravenian();
+ AddSC_boss_vectus();
+ AddSC_boss_kirtonos_the_herald();
+ AddSC_instance_scholomance();
+ AddSC_shadowfang_keep(); //Shadowfang keep
+ AddSC_instance_shadowfang_keep();
+ AddSC_boss_magistrate_barthilas(); //Stratholme
+ AddSC_boss_maleki_the_pallid();
+ AddSC_boss_nerubenkan();
+ AddSC_boss_cannon_master_willey();
+ AddSC_boss_baroness_anastari();
+ AddSC_boss_ramstein_the_gorger();
+ AddSC_boss_timmy_the_cruel();
+ AddSC_boss_postmaster_malown();
+ AddSC_boss_baron_rivendare();
+ AddSC_boss_dathrohan_balnazzar();
+ AddSC_boss_order_of_silver_hand();
+ AddSC_instance_stratholme();
+ AddSC_stratholme();
+ AddSC_sunken_temple(); // Sunken Temple
+ AddSC_instance_sunken_temple();
+ AddSC_instance_sunwell_plateau(); //Sunwell Plateau
+ AddSC_boss_kalecgos();
+ AddSC_boss_brutallus();
+ AddSC_boss_felmyst();
+ AddSC_boss_eredar_twins();
+ AddSC_boss_muru();
+ AddSC_boss_kiljaeden();
+ AddSC_sunwell_plateau();
+ AddSC_instance_the_stockade(); //The Stockade
+ AddSC_boss_archaedas(); //Uldaman
+ AddSC_boss_ironaya();
+ AddSC_uldaman();
+ AddSC_instance_uldaman();
+ AddSC_boss_akilzon(); //Zul'Aman
+ AddSC_boss_halazzi();
+ AddSC_boss_hex_lord_malacrass();
+ AddSC_boss_janalai();
+ AddSC_boss_nalorakk();
+ AddSC_boss_zuljin();
+ AddSC_instance_zulaman();
+ AddSC_zulaman();
+ AddSC_boss_jeklik(); //Zul'Gurub
+ AddSC_boss_venoxis();
+ AddSC_boss_marli();
+ AddSC_boss_mandokir();
+ AddSC_boss_gahzranka();
+ AddSC_boss_thekal();
+ AddSC_boss_arlokk();
+ AddSC_boss_jindo();
+ AddSC_boss_hakkar();
+ AddSC_boss_grilek();
+ AddSC_boss_hazzarah();
+ AddSC_boss_renataki();
+ AddSC_boss_wushoolay();
+ AddSC_instance_zulgurub();
+ //AddSC_alterac_mountains();
+ AddSC_arathi_highlands();
+ AddSC_blasted_lands();
+ AddSC_burning_steppes();
+ AddSC_duskwood();
+ AddSC_eastern_plaguelands();
+ AddSC_ghostlands();
+ AddSC_hinterlands();
+ AddSC_isle_of_queldanas();
+ AddSC_loch_modan();
+ AddSC_redridge_mountains();
+ AddSC_silverpine_forest();
+ AddSC_stormwind_city();
+ AddSC_stranglethorn_vale();
+ AddSC_swamp_of_sorrows();
+ AddSC_tirisfal_glades();
+ AddSC_undercity();
+ AddSC_western_plaguelands();
+ AddSC_wetlands();
+}
diff --git a/src/server/scripts/EasternKingdoms/zone_burning_steppes.cpp b/src/server/scripts/EasternKingdoms/zone_burning_steppes.cpp
index df61a010f84..73b397553a5 100644
--- a/src/server/scripts/EasternKingdoms/zone_burning_steppes.cpp
+++ b/src/server/scripts/EasternKingdoms/zone_burning_steppes.cpp
@@ -19,7 +19,7 @@
/* ScriptData
SDName: Burning_Steppes
SD%Complete: 100
-SDComment: Quest support: 4224, 4866
+SDComment: Quest support: 4866
SDCategory: Burning Steppes
EndScriptData */
@@ -36,25 +36,11 @@ EndContentData */
## npc_ragged_john
######*/
-#define GOSSIP_HELLO "Official buisness, John. I need some information about Marsha Windsor. Tell me about the last time you saw him."
-#define GOSSIP_SELECT1 "So what did you do?"
-#define GOSSIP_SELECT2 "Start making sense, dwarf. I don't want to have anything to do with your cracker, your pappy, or any sort of 'discreditin'."
-#define GOSSIP_SELECT3 "Ironfoe?"
-#define GOSSIP_SELECT4 "Interesting... continue John."
-#define GOSSIP_SELECT5 "So that's how Windsor died..."
-#define GOSSIP_SELECT6 "So how did he die?"
-#define GOSSIP_SELECT7 "Ok so where the hell is he? Wait a minute! Are you drunk?"
-#define GOSSIP_SELECT8 "WHY is he in Blackrock Depths?"
-#define GOSSIP_SELECT9 "300? So the Dark Irons killed him and dragged him into the Depths?"
-#define GOSSIP_SELECT10 "Ahh... Ironfoe"
-#define GOSSIP_SELECT11 "Thanks, Ragged John. Your story was very uplifting and informative"
-
enum RaggedJohn
{
- QUEST_THE_TRUE_MASTERS = 4224,
- QUEST_MOTHERS_MILK = 4866,
- SPELL_MOTHERS_MILK = 16468,
- SPELL_WICKED_MILKING = 16472
+ QUEST_MOTHERS_MILK = 4866,
+ SPELL_MOTHERS_MILK = 16468,
+ SPELL_WICKED_MILKING = 16472
};
class npc_ragged_john : public CreatureScript
@@ -86,72 +72,13 @@ public:
void EnterCombat(Unit* /*who*/) override { }
};
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
- {
- player->PlayerTalkClass->ClearMenus();
- switch (action)
- {
- case GOSSIP_ACTION_INFO_DEF:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
- player->SEND_GOSSIP_MENU(2714, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+1:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
- player->SEND_GOSSIP_MENU(2715, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+2:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
- player->SEND_GOSSIP_MENU(2716, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+3:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
- player->SEND_GOSSIP_MENU(2717, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+4:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5);
- player->SEND_GOSSIP_MENU(2718, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+5:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6);
- player->SEND_GOSSIP_MENU(2719, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+6:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT7, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 7);
- player->SEND_GOSSIP_MENU(2720, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+7:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT8, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 8);
- player->SEND_GOSSIP_MENU(2721, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+8:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT9, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 9);
- player->SEND_GOSSIP_MENU(2722, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+9:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT10, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 10);
- player->SEND_GOSSIP_MENU(2723, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+10:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT11, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 11);
- player->SEND_GOSSIP_MENU(2725, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+11:
- player->CLOSE_GOSSIP_MENU();
- player->AreaExploredOrEventHappens(QUEST_THE_TRUE_MASTERS);
- break;
- }
- return true;
- }
-
bool OnGossipHello(Player* player, Creature* creature) override
{
if (creature->IsQuestGiver())
+ {
player->PrepareQuestMenu(creature->GetGUID());
-
- if (player->GetQuestStatus(QUEST_THE_TRUE_MASTERS) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
-
- player->SEND_GOSSIP_MENU(2713, creature->GetGUID());
+ player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
+ }
return true;
}
diff --git a/src/server/scripts/EasternKingdoms/zone_eastern_plaguelands.cpp b/src/server/scripts/EasternKingdoms/zone_eastern_plaguelands.cpp
index ce0ebf4d129..4cc72715868 100644
--- a/src/server/scripts/EasternKingdoms/zone_eastern_plaguelands.cpp
+++ b/src/server/scripts/EasternKingdoms/zone_eastern_plaguelands.cpp
@@ -19,7 +19,7 @@
/* ScriptData
SDName: Eastern_Plaguelands
SD%Complete: 100
-SDComment: Quest support: 5211, 5742. Special vendor Augustus the Touched
+SDComment: Quest support: 5211. Special vendor Augustus the Touched
SDCategory: Eastern Plaguelands
EndScriptData */
@@ -27,7 +27,6 @@ EndScriptData */
npc_ghoul_flayer
npc_augustus_the_touched
npc_darrowshire_spirit
-npc_tirion_fordring
EndContentData */
#include "ScriptMgr.h"
@@ -133,63 +132,9 @@ public:
};
};
-/*######
-## npc_tirion_fordring
-######*/
-
-#define GOSSIP_HELLO "I am ready to hear your tale, Tirion."
-#define GOSSIP_SELECT1 "Thank you, Tirion. What of your identity?"
-#define GOSSIP_SELECT2 "That is terrible."
-#define GOSSIP_SELECT3 "I will, Tirion."
-
-class npc_tirion_fordring : public CreatureScript
-{
-public:
- npc_tirion_fordring() : CreatureScript("npc_tirion_fordring") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
- {
- player->PlayerTalkClass->ClearMenus();
- switch (action)
- {
- case GOSSIP_ACTION_INFO_DEF+1:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
- player->SEND_GOSSIP_MENU(4493, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+2:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
- player->SEND_GOSSIP_MENU(4494, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+3:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
- player->SEND_GOSSIP_MENU(4495, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+4:
- player->CLOSE_GOSSIP_MENU();
- player->AreaExploredOrEventHappens(5742);
- break;
- }
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) override
- {
- if (creature->IsQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (player->GetQuestStatus(5742) == QUEST_STATUS_INCOMPLETE && player->getStandState() == UNIT_STAND_STATE_SIT)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
-
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
-
- return true;
- }
-};
-
void AddSC_eastern_plaguelands()
{
new npc_ghoul_flayer();
new npc_augustus_the_touched();
new npc_darrowshire_spirit();
- new npc_tirion_fordring();
}
diff --git a/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp b/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp
index 2d6d4da5aef..4a585bcb267 100644
--- a/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp
+++ b/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp
@@ -19,14 +19,12 @@
/* ScriptData
SDName: Stormwind_City
SD%Complete: 100
-SDComment: Quest support: 1640, 1447, 4185, 11223, 434.
+SDComment: Quest support: 1640, 1447, 434.
SDCategory: Stormwind City
EndScriptData */
/* ContentData
-npc_archmage_malin
npc_bartleby
-npc_lady_katrana_prestor
npc_tyrion
npc_tyrion_spybot
npc_marzon_silent_blade
@@ -40,50 +38,13 @@ EndContentData */
#include "Player.h"
/*######
-## npc_archmage_malin
-######*/
-
-#define GOSSIP_ITEM_MALIN "Can you send me to Theramore? I have an urgent message for Lady Jaina from Highlord Bolvar."
-
-class npc_archmage_malin : public CreatureScript
-{
-public:
- npc_archmage_malin() : CreatureScript("npc_archmage_malin") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
- {
- player->PlayerTalkClass->ClearMenus();
- if (action == GOSSIP_ACTION_INFO_DEF)
- {
- player->CLOSE_GOSSIP_MENU();
- creature->CastSpell(player, 42711, true);
- }
-
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) override
- {
- if (creature->IsQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (player->GetQuestStatus(11223) == QUEST_STATUS_COMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_MALIN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
-
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
-
- return true;
- }
-};
-
-/*######
## npc_bartleby
######*/
enum Bartleby
{
- FACTION_ENEMY = 168,
- QUEST_BEAT = 1640
+ FACTION_ENEMY = 168,
+ QUEST_BEAT = 1640
};
class npc_bartleby : public CreatureScript
@@ -148,71 +109,18 @@ public:
};
/*######
-## npc_lady_katrana_prestor
-######*/
-
-#define GOSSIP_ITEM_KAT_1 "Pardon the intrusion, Lady Prestor, but Highlord Bolvar suggested that I seek your advice."
-#define GOSSIP_ITEM_KAT_2 "My apologies, Lady Prestor."
-#define GOSSIP_ITEM_KAT_3 "Begging your pardon, Lady Prestor. That was not my intent."
-#define GOSSIP_ITEM_KAT_4 "Thank you for your time, Lady Prestor."
-
-class npc_lady_katrana_prestor : public CreatureScript
-{
-public:
- npc_lady_katrana_prestor() : CreatureScript("npc_lady_katrana_prestor") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
- {
- player->PlayerTalkClass->ClearMenus();
- switch (action)
- {
- case GOSSIP_ACTION_INFO_DEF:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KAT_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
- player->SEND_GOSSIP_MENU(2694, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+1:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KAT_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
- player->SEND_GOSSIP_MENU(2695, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+2:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KAT_4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
- player->SEND_GOSSIP_MENU(2696, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+3:
- player->CLOSE_GOSSIP_MENU();
- player->AreaExploredOrEventHappens(4185);
- break;
- }
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) override
- {
- if (creature->IsQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (player->GetQuestStatus(4185) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KAT_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
-
- player->SEND_GOSSIP_MENU(2693, creature->GetGUID());
-
- return true;
- }
-};
-
-/*######
## npc_lord_gregor_lescovar
######*/
enum LordGregorLescovar
{
- SAY_GUARD_2 = 0,
- SAY_LESCOVAR_2 = 0,
- SAY_LESCOVAR_3 = 1,
- SAY_LESCOVAR_4 = 2,
- SAY_MARZON_1 = 0,
- SAY_MARZON_2 = 1,
- SAY_TYRION_2 = 1,
+ SAY_GUARD_2 = 0,
+ SAY_LESCOVAR_2 = 0,
+ SAY_LESCOVAR_3 = 1,
+ SAY_LESCOVAR_4 = 2,
+ SAY_MARZON_1 = 0,
+ SAY_MARZON_2 = 1,
+ SAY_TYRION_2 = 1,
NPC_STORMWIND_ROYAL = 1756,
NPC_MARZON_BLADE = 1755,
@@ -650,9 +558,7 @@ public:
void AddSC_stormwind_city()
{
- new npc_archmage_malin();
new npc_bartleby();
- new npc_lady_katrana_prestor();
new npc_tyrion();
new npc_tyrion_spybot();
new npc_lord_gregor_lescovar();
diff --git a/src/server/scripts/Events/CMakeLists.txt b/src/server/scripts/Events/CMakeLists.txt
deleted file mode 100644
index 1c9e5cfe8e1..00000000000
--- a/src/server/scripts/Events/CMakeLists.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
-#
-# This file is free software; as a special exception the author gives
-# unlimited permission to copy and/or distribute it, with or without
-# modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-file(GLOB_RECURSE sources_Events Events/*.cpp Events/*.h)
-
-set(scripts_STAT_SRCS
- ${scripts_STAT_SRCS}
- ${sources_Events}
-)
-
-message(" -> Prepared: Events")
diff --git a/src/server/scripts/Events/events_script_loader.cpp b/src/server/scripts/Events/events_script_loader.cpp
new file mode 100644
index 00000000000..625c08f5389
--- /dev/null
+++ b/src/server/scripts/Events/events_script_loader.cpp
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// This is where scripts' loading functions should be declared:
+void AddSC_event_childrens_week();
+
+// The name of this function should match:
+// void Add${NameOfDirectory}Scripts()
+void AddEventsScripts()
+{
+ AddSC_event_childrens_week();
+}
diff --git a/src/server/scripts/Kalimdor/CMakeLists.txt b/src/server/scripts/Kalimdor/CMakeLists.txt
deleted file mode 100644
index 2d1b4b49649..00000000000
--- a/src/server/scripts/Kalimdor/CMakeLists.txt
+++ /dev/null
@@ -1,121 +0,0 @@
-# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
-#
-# This file is free software; as a special exception the author gives
-# unlimited permission to copy and/or distribute it, with or without
-# modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-set(scripts_STAT_SRCS
- ${scripts_STAT_SRCS}
- Kalimdor/zone_stonetalon_mountains.cpp
- Kalimdor/zone_silithus.cpp
- Kalimdor/zone_moonglade.cpp
- Kalimdor/RazorfenDowns/razorfen_downs.cpp
- Kalimdor/RazorfenDowns/instance_razorfen_downs.cpp
- Kalimdor/RazorfenDowns/boss_tuten_kash.cpp
- Kalimdor/RazorfenDowns/boss_mordresh_fire_eye.cpp
- Kalimdor/RazorfenDowns/boss_glutton.cpp
- Kalimdor/RazorfenDowns/boss_amnennar_the_coldbringer.cpp
- Kalimdor/RazorfenDowns/razorfen_downs.h
- Kalimdor/ZulFarrak/zulfarrak.cpp
- Kalimdor/ZulFarrak/instance_zulfarrak.cpp
- Kalimdor/ZulFarrak/boss_zum_rah.cpp
- Kalimdor/ZulFarrak/zulfarrak.h
- Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_epoch_hunter.cpp
- Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.h
- Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_leutenant_drake.cpp
- Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp
- Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/instance_old_hillsbrad.cpp
- Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_captain_skarloc.cpp
- Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp
- Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h
- Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h
- Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp
- Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp
- Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp
- Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp
- Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp
- Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp
- Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h
- Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp
- Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp
- Kalimdor/CavernsOfTime/CullingOfStratholme/boss_infinite_corruptor.cpp
- Kalimdor/CavernsOfTime/CullingOfStratholme/boss_salramm_the_fleshcrafter.cpp
- Kalimdor/CavernsOfTime/CullingOfStratholme/boss_meathook.cpp
- Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp
- Kalimdor/CavernsOfTime/CullingOfStratholme/boss_chrono_lord_epoch.cpp
- Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp
- Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp
- Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.h
- Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.h
- Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp
- Kalimdor/CavernsOfTime/TheBlackMorass/boss_chrono_lord_deja.cpp
- Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp
- Kalimdor/CavernsOfTime/TheBlackMorass/boss_aeonus.cpp
- Kalimdor/CavernsOfTime/TheBlackMorass/boss_temporus.cpp
- Kalimdor/BlackfathomDeeps/boss_kelris.cpp
- Kalimdor/BlackfathomDeeps/instance_blackfathom_deeps.cpp
- Kalimdor/BlackfathomDeeps/boss_gelihast.cpp
- Kalimdor/BlackfathomDeeps/blackfathom_deeps.cpp
- Kalimdor/BlackfathomDeeps/boss_aku_mai.cpp
- Kalimdor/BlackfathomDeeps/blackfathom_deeps.h
- Kalimdor/zone_azuremyst_isle.cpp
- Kalimdor/zone_orgrimmar.cpp
- Kalimdor/zone_desolace.cpp
- Kalimdor/zone_feralas.cpp
- Kalimdor/Maraudon/boss_princess_theradras.cpp
- Kalimdor/Maraudon/boss_landslide.cpp
- Kalimdor/Maraudon/boss_celebras_the_cursed.cpp
- Kalimdor/Maraudon/boss_noxxion.cpp
- Kalimdor/Maraudon/instance_maraudon.cpp
- Kalimdor/TempleOfAhnQiraj/boss_fankriss.cpp
- Kalimdor/TempleOfAhnQiraj/boss_huhuran.cpp
- Kalimdor/TempleOfAhnQiraj/instance_temple_of_ahnqiraj.cpp
- Kalimdor/TempleOfAhnQiraj/mob_anubisath_sentinel.cpp
- Kalimdor/TempleOfAhnQiraj/boss_viscidus.cpp
- Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp
- Kalimdor/TempleOfAhnQiraj/boss_sartura.cpp
- Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp
- Kalimdor/TempleOfAhnQiraj/temple_of_ahnqiraj.h
- Kalimdor/TempleOfAhnQiraj/boss_skeram.cpp
- Kalimdor/TempleOfAhnQiraj/boss_ouro.cpp
- Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp
- Kalimdor/zone_darkshore.cpp
- Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp
- Kalimdor/RuinsOfAhnQiraj/instance_ruins_of_ahnqiraj.cpp
- Kalimdor/RuinsOfAhnQiraj/boss_rajaxx.cpp
- Kalimdor/RuinsOfAhnQiraj/boss_ossirian.cpp
- Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp
- Kalimdor/RuinsOfAhnQiraj/boss_moam.cpp
- Kalimdor/RuinsOfAhnQiraj/ruins_of_ahnqiraj.h
- Kalimdor/RuinsOfAhnQiraj/boss_kurinnaxx.cpp
- Kalimdor/zone_bloodmyst_isle.cpp
- Kalimdor/zone_thunder_bluff.cpp
- Kalimdor/zone_azshara.cpp
- Kalimdor/RazorfenKraul/razorfen_kraul.h
- Kalimdor/RazorfenKraul/instance_razorfen_kraul.cpp
- Kalimdor/RazorfenKraul/razorfen_kraul.cpp
- Kalimdor/zone_the_barrens.cpp
- Kalimdor/zone_ungoro_crater.cpp
- Kalimdor/WailingCaverns/wailing_caverns.h
- Kalimdor/WailingCaverns/instance_wailing_caverns.cpp
- Kalimdor/WailingCaverns/wailing_caverns.cpp
- Kalimdor/zone_durotar.cpp
- Kalimdor/zone_felwood.cpp
- Kalimdor/boss_azuregos.cpp
- Kalimdor/zone_tanaris.cpp
- Kalimdor/zone_dustwallow_marsh.cpp
- Kalimdor/zone_winterspring.cpp
- Kalimdor/zone_thousand_needles.cpp
- Kalimdor/zone_ashenvale.cpp
- Kalimdor/OnyxiasLair/boss_onyxia.cpp
- Kalimdor/OnyxiasLair/onyxias_lair.h
- Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp
- Kalimdor/RagefireChasm/instance_ragefire_chasm.cpp
- Kalimdor/DireMaul/instance_dire_maul.cpp
-)
-
-message(" -> Prepared: Kalimdor")
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h
index 55b85801652..54d3c53039e 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h
@@ -121,15 +121,15 @@ struct hyjalAI : public npc_escortAI
void Initialize();
- void Reset(); // Generically used to reset our variables. Do *not* call in EnterEvadeMode as this may make problems if the raid is still in combat
+ void Reset() override; // Generically used to reset our variables. Do *not* call in EnterEvadeMode as this may make problems if the raid is still in combat
- void EnterEvadeMode(EvadeReason /*why*/ = EVADE_REASON_OTHER); // Send creature back to spawn location and evade.
+ void EnterEvadeMode(EvadeReason /*why*/ = EVADE_REASON_OTHER) override; // Send creature back to spawn location and evade.
- void EnterCombat(Unit* /*who*/); // Used to reset cooldowns for our spells and to inform the raid that we're under attack
+ void EnterCombat(Unit* /*who*/) override; // Used to reset cooldowns for our spells and to inform the raid that we're under attack
- void UpdateAI(uint32 diff); // Called to summon waves, check for boss deaths and to cast our spells.
+ void UpdateAI(uint32 diff) override; // Called to summon waves, check for boss deaths and to cast our spells.
- void JustDied(Unit* /*killer*/); // Called on death, informs the raid that they have failed.
+ void JustDied(Unit* /*killer*/) override; // Called on death, informs the raid that they have failed.
void SetFaction(uint32 _faction) // Set the faction to either Alliance or Horde in Hyjal
{
@@ -140,13 +140,13 @@ struct hyjalAI : public npc_escortAI
void SpawnVeins();
void DeSpawnVeins();
- void JustSummoned(Creature* summoned);
- void SummonedCreatureDespawn(Creature* summoned);
+ void JustSummoned(Creature* summoned) override;
+ void SummonedCreatureDespawn(Creature* summoned) override;
void HideNearPos(float x, float y);
void RespawnNearPos(float x, float y);
- void WaypointReached(uint32 waypointId);
+ void WaypointReached(uint32 waypointId) override;
void DoOverrun(uint32 faction, const uint32 diff);
- void MoveInLineOfSight(Unit* who);
+ void MoveInLineOfSight(Unit* who) override;
void SummonCreature(uint32 entry, float Base[4][3]); // Summons a creature for that wave in that base
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h
index 5275c07f63a..f29851e7cea 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h
@@ -25,11 +25,11 @@ struct hyjal_trashAI : public npc_escortAI
{
hyjal_trashAI(Creature* creature);
- void UpdateAI(uint32 diff);
+ void UpdateAI(uint32 diff) override;
- void JustDied(Unit* /*killer*/);
+ void JustDied(Unit* /*killer*/) override;
- void DamageTaken(Unit* done_by, uint32 &damage);
+ void DamageTaken(Unit* done_by, uint32 &damage) override;
public:
InstanceScript* instance;
diff --git a/src/server/scripts/Kalimdor/kalimdor_script_loader.cpp b/src/server/scripts/Kalimdor/kalimdor_script_loader.cpp
new file mode 100644
index 00000000000..f1969a063d6
--- /dev/null
+++ b/src/server/scripts/Kalimdor/kalimdor_script_loader.cpp
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// This is where scripts' loading functions should be declared:
+void AddSC_blackfathom_deeps(); //Blackfathom Depths
+void AddSC_boss_gelihast();
+void AddSC_boss_kelris();
+void AddSC_boss_aku_mai();
+void AddSC_instance_blackfathom_deeps();
+void AddSC_hyjal(); //CoT Battle for Mt. Hyjal
+void AddSC_boss_archimonde();
+void AddSC_instance_mount_hyjal();
+void AddSC_hyjal_trash();
+void AddSC_boss_rage_winterchill();
+void AddSC_boss_anetheron();
+void AddSC_boss_kazrogal();
+void AddSC_boss_azgalor();
+void AddSC_boss_captain_skarloc(); //CoT Old Hillsbrad
+void AddSC_boss_epoch_hunter();
+void AddSC_boss_lieutenant_drake();
+void AddSC_instance_old_hillsbrad();
+void AddSC_old_hillsbrad();
+void AddSC_boss_aeonus(); //CoT The Black Morass
+void AddSC_boss_chrono_lord_deja();
+void AddSC_boss_temporus();
+void AddSC_the_black_morass();
+void AddSC_instance_the_black_morass();
+void AddSC_boss_epoch(); //CoT Culling Of Stratholme
+void AddSC_boss_infinite_corruptor();
+void AddSC_boss_salramm();
+void AddSC_boss_mal_ganis();
+void AddSC_boss_meathook();
+void AddSC_culling_of_stratholme();
+void AddSC_instance_culling_of_stratholme();
+void AddSC_instance_dire_maul(); //Dire Maul
+void AddSC_boss_celebras_the_cursed(); //Maraudon
+void AddSC_boss_landslide();
+void AddSC_boss_noxxion();
+void AddSC_boss_ptheradras();
+void AddSC_instance_maraudon();
+void AddSC_boss_onyxia(); //Onyxia's Lair
+void AddSC_instance_onyxias_lair();
+void AddSC_boss_tuten_kash(); //Razorfen Downs
+void AddSC_boss_mordresh_fire_eye();
+void AddSC_boss_glutton();
+void AddSC_boss_amnennar_the_coldbringer();
+void AddSC_razorfen_downs();
+void AddSC_instance_razorfen_downs();
+void AddSC_razorfen_kraul(); //Razorfen Kraul
+void AddSC_instance_razorfen_kraul();
+void AddSC_boss_kurinnaxx(); //Ruins of ahn'qiraj
+void AddSC_boss_rajaxx();
+void AddSC_boss_moam();
+void AddSC_boss_buru();
+void AddSC_boss_ayamiss();
+void AddSC_boss_ossirian();
+void AddSC_instance_ruins_of_ahnqiraj();
+void AddSC_boss_cthun(); //Temple of ahn'qiraj
+void AddSC_boss_viscidus();
+void AddSC_boss_fankriss();
+void AddSC_boss_huhuran();
+void AddSC_bug_trio();
+void AddSC_boss_sartura();
+void AddSC_boss_skeram();
+void AddSC_boss_twinemperors();
+void AddSC_boss_ouro();
+void AddSC_npc_anubisath_sentinel();
+void AddSC_instance_temple_of_ahnqiraj();
+void AddSC_wailing_caverns(); //Wailing caverns
+void AddSC_instance_wailing_caverns();
+void AddSC_boss_zum_rah(); //Zul'Farrak
+void AddSC_zulfarrak();
+void AddSC_instance_zulfarrak();
+
+void AddSC_ashenvale();
+void AddSC_azshara();
+void AddSC_azuremyst_isle();
+void AddSC_bloodmyst_isle();
+void AddSC_boss_azuregos();
+void AddSC_darkshore();
+void AddSC_desolace();
+void AddSC_durotar();
+void AddSC_dustwallow_marsh();
+void AddSC_felwood();
+void AddSC_feralas();
+void AddSC_moonglade();
+void AddSC_orgrimmar();
+void AddSC_silithus();
+void AddSC_stonetalon_mountains();
+void AddSC_tanaris();
+void AddSC_the_barrens();
+void AddSC_thousand_needles();
+void AddSC_thunder_bluff();
+void AddSC_ungoro_crater();
+void AddSC_winterspring();
+
+// The name of this function should match:
+// void Add${NameOfDirectory}Scripts()
+void AddKalimdorScripts()
+{
+ AddSC_blackfathom_deeps(); //Blackfathom Depths
+ AddSC_boss_gelihast();
+ AddSC_boss_kelris();
+ AddSC_boss_aku_mai();
+ AddSC_instance_blackfathom_deeps();
+ AddSC_hyjal(); //CoT Battle for Mt. Hyjal
+ AddSC_boss_archimonde();
+ AddSC_instance_mount_hyjal();
+ AddSC_hyjal_trash();
+ AddSC_boss_rage_winterchill();
+ AddSC_boss_anetheron();
+ AddSC_boss_kazrogal();
+ AddSC_boss_azgalor();
+ AddSC_boss_captain_skarloc(); //CoT Old Hillsbrad
+ AddSC_boss_epoch_hunter();
+ AddSC_boss_lieutenant_drake();
+ AddSC_instance_old_hillsbrad();
+ AddSC_old_hillsbrad();
+ AddSC_boss_aeonus(); //CoT The Black Morass
+ AddSC_boss_chrono_lord_deja();
+ AddSC_boss_temporus();
+ AddSC_the_black_morass();
+ AddSC_instance_the_black_morass();
+ AddSC_boss_epoch(); //CoT Culling Of Stratholme
+ AddSC_boss_infinite_corruptor();
+ AddSC_boss_salramm();
+ AddSC_boss_mal_ganis();
+ AddSC_boss_meathook();
+ AddSC_culling_of_stratholme();
+ AddSC_instance_culling_of_stratholme();
+ AddSC_instance_dire_maul(); //Dire Maul
+ AddSC_boss_celebras_the_cursed(); //Maraudon
+ AddSC_boss_landslide();
+ AddSC_boss_noxxion();
+ AddSC_boss_ptheradras();
+ AddSC_instance_maraudon();
+ AddSC_boss_onyxia(); //Onyxia's Lair
+ AddSC_instance_onyxias_lair();
+ AddSC_boss_tuten_kash(); //Razorfen Downs
+ AddSC_boss_mordresh_fire_eye();
+ AddSC_boss_glutton();
+ AddSC_boss_amnennar_the_coldbringer();
+ AddSC_razorfen_downs();
+ AddSC_instance_razorfen_downs();
+ AddSC_razorfen_kraul(); //Razorfen Kraul
+ AddSC_instance_razorfen_kraul();
+ AddSC_boss_kurinnaxx(); //Ruins of ahn'qiraj
+ AddSC_boss_rajaxx();
+ AddSC_boss_moam();
+ AddSC_boss_buru();
+ AddSC_boss_ayamiss();
+ AddSC_boss_ossirian();
+ AddSC_instance_ruins_of_ahnqiraj();
+ AddSC_boss_cthun(); //Temple of ahn'qiraj
+ AddSC_boss_viscidus();
+ AddSC_boss_fankriss();
+ AddSC_boss_huhuran();
+ AddSC_bug_trio();
+ AddSC_boss_sartura();
+ AddSC_boss_skeram();
+ AddSC_boss_twinemperors();
+ AddSC_boss_ouro();
+ AddSC_npc_anubisath_sentinel();
+ AddSC_instance_temple_of_ahnqiraj();
+ AddSC_wailing_caverns(); //Wailing caverns
+ AddSC_instance_wailing_caverns();
+ AddSC_boss_zum_rah(); //Zul'Farrak
+ AddSC_zulfarrak();
+ AddSC_instance_zulfarrak();
+
+ AddSC_ashenvale();
+ AddSC_azshara();
+ AddSC_azuremyst_isle();
+ AddSC_bloodmyst_isle();
+ AddSC_boss_azuregos();
+ AddSC_darkshore();
+ AddSC_desolace();
+ AddSC_durotar();
+ AddSC_dustwallow_marsh();
+ AddSC_felwood();
+ AddSC_feralas();
+ AddSC_moonglade();
+ AddSC_orgrimmar();
+ AddSC_silithus();
+ AddSC_stonetalon_mountains();
+ AddSC_tanaris();
+ AddSC_the_barrens();
+ AddSC_thousand_needles();
+ AddSC_thunder_bluff();
+ AddSC_ungoro_crater();
+ AddSC_winterspring();
+}
diff --git a/src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp b/src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp
index 273e81d83c0..6063b9fe5c6 100644
--- a/src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp
+++ b/src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp
@@ -240,11 +240,6 @@ class npc_sironas : public CreatureScript
public:
npc_sironas() : CreatureScript("npc_sironas") { }
- CreatureAI* GetAI(Creature* creature) const
- {
- return new npc_sironasAI(creature);
- }
-
struct npc_sironasAI : public ScriptedAI
{
npc_sironasAI(Creature* creature) : ScriptedAI(creature) { }
@@ -343,6 +338,11 @@ public:
GuidList _beamGuidList;
EventMap _events;
};
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new npc_sironasAI(creature);
+ }
};
/*######
@@ -354,11 +354,6 @@ class npc_demolitionist_legoso : public CreatureScript
public:
npc_demolitionist_legoso() : CreatureScript("npc_demolitionist_legoso") { }
- CreatureAI* GetAI(Creature* creature) const
- {
- return new npc_demolitionist_legosoAI(creature);
- }
-
struct npc_demolitionist_legosoAI : public npc_escortAI
{
npc_demolitionist_legosoAI(Creature* creature) : npc_escortAI(creature)
@@ -812,6 +807,11 @@ public:
GuidList _explosivesGuids;
EventMap _events;
};
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new npc_demolitionist_legosoAI(creature);
+ }
};
void AddSC_bloodmyst_isle()
diff --git a/src/server/scripts/Kalimdor/zone_desolace.cpp b/src/server/scripts/Kalimdor/zone_desolace.cpp
index 621e0b0a585..6880d8ee38f 100644
--- a/src/server/scripts/Kalimdor/zone_desolace.cpp
+++ b/src/server/scripts/Kalimdor/zone_desolace.cpp
@@ -66,7 +66,6 @@ public:
npc_aged_dying_ancient_kodoAI(Creature* creature) : ScriptedAI(creature) { }
void MoveInLineOfSight(Unit* who) override
-
{
if (who->GetEntry() == NPC_SMEED && me->IsWithinDistInMap(who, 10.0f) && !me->HasAura(SPELL_KODO_KOMBO_GOSSIP))
{
@@ -226,37 +225,9 @@ public:
}
};
-/*######
-## go_demon_portal
-######*/
-
-enum DemonPortal
-{
- NPC_DEMON_GUARDIAN = 11937,
- QUEST_PORTAL_OF_THE_LEGION = 5581
-};
-
-class go_demon_portal : public GameObjectScript
-{
- public:
- go_demon_portal() : GameObjectScript("go_demon_portal") { }
-
- bool OnGossipHello(Player* player, GameObject* go) override
- {
- if (player->GetQuestStatus(QUEST_PORTAL_OF_THE_LEGION) == QUEST_STATUS_INCOMPLETE && !go->FindNearestCreature(NPC_DEMON_GUARDIAN, 5.0f, true))
- {
- if (Creature* guardian = player->SummonCreature(NPC_DEMON_GUARDIAN, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ(), 0.0f, TEMPSUMMON_DEAD_DESPAWN, 0))
- guardian->AI()->AttackStart(player);
- }
-
- return true;
- }
-};
-
void AddSC_desolace()
{
new npc_aged_dying_ancient_kodo();
new go_iruxos();
new npc_dalinda();
- new go_demon_portal();
}
diff --git a/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp b/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp
index 9df9f0b604a..be49778ee4a 100644
--- a/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp
+++ b/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp
@@ -24,7 +24,6 @@ SDCategory: Dustwallow Marsh
EndScriptData */
/* ContentData
-npc_lady_jaina_proudmoore
npc_nat_pagle
npc_private_hendel
npc_cassa_crimsonwing - handled by npc_taxi
@@ -39,49 +38,6 @@ EndContentData */
#include "WorldSession.h"
/*######
-## npc_lady_jaina_proudmoore
-######*/
-
-enum LadyJaina
-{
- QUEST_JAINAS_AUTOGRAPH = 558,
- SPELL_JAINAS_AUTOGRAPH = 23122
-};
-
-#define GOSSIP_ITEM_JAINA "I know this is rather silly but i have a young ward who is a bit shy and would like your autograph."
-
-class npc_lady_jaina_proudmoore : public CreatureScript
-{
-public:
- npc_lady_jaina_proudmoore() : CreatureScript("npc_lady_jaina_proudmoore") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
- {
- player->PlayerTalkClass->ClearMenus();
- if (action == GOSSIP_SENDER_INFO)
- {
- player->SEND_GOSSIP_MENU(7012, creature->GetGUID());
- player->CastSpell(player, SPELL_JAINAS_AUTOGRAPH, false);
- }
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) override
- {
- if (creature->IsQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (player->GetQuestStatus(QUEST_JAINAS_AUTOGRAPH) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_JAINA, GOSSIP_SENDER_MAIN, GOSSIP_SENDER_INFO);
-
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
-
- return true;
- }
-
-};
-
-/*######
## npc_nat_pagle
######*/
@@ -417,7 +373,6 @@ class spell_energize_aoe : public SpellScriptLoader
void AddSC_dustwallow_marsh()
{
- new npc_lady_jaina_proudmoore();
new npc_nat_pagle();
new npc_private_hendel();
new npc_zelfrax();
diff --git a/src/server/scripts/Kalimdor/zone_orgrimmar.cpp b/src/server/scripts/Kalimdor/zone_orgrimmar.cpp
index ac26aa1f811..adb6439272a 100644
--- a/src/server/scripts/Kalimdor/zone_orgrimmar.cpp
+++ b/src/server/scripts/Kalimdor/zone_orgrimmar.cpp
@@ -143,20 +143,30 @@ public:
enum ThrallWarchief
{
- QUEST_6566 = 6566,
-
- SPELL_CHAIN_LIGHTNING = 16033,
- SPELL_SHOCK = 16034
+ GOSSIP_MENU_OPTION_ID_ALL = 0,
+
+ OPTION_PLEASE_SHARE_YOUR = 3664,
+ OPTION_WHAT_DISCOVERIES = 3665,
+ OPTION_USURPER = 3666,
+ OPTION_WITH_ALL_DUE_RESPECT = 3667,
+ OPTION_I_I_DID_NOT_THINK_OF = 3668,
+ OPTION_I_LIVE_ONLY_TO_SERVE = 3669,
+ OPTION_OF_COURSE_WARCHIEF = 3670,
+
+ GOSSIP_MEMBERS_OF_THE_HORDE = 4477,
+ GOSSIP_THE_SHATTERED_HAND = 5733,
+ GOSSIP_IT_WOULD_APPEAR_AS = 5734,
+ GOSSIP_THE_BROOD_MOTHER = 5735,
+ GOSSIP_SO_MUCH_TO_LEARN = 5736,
+ GOSSIP_I_DO_NOT_FAULT_YOU = 5737,
+ GOSSIP_NOW_PAY_ATTENTION = 5738,
+
+ QUEST_WHAT_THE_WIND_CARRIES = 6566,
+
+ SPELL_CHAIN_LIGHTNING = 16033,
+ SPELL_SHOCK = 16034
};
-#define GOSSIP_HTW "Please share your wisdom with me, Warchief."
-#define GOSSIP_STW1 "What discoveries?"
-#define GOSSIP_STW2 "Usurper?"
-#define GOSSIP_STW3 "With all due respect, Warchief - why not allow them to be destroyed? Does this not strengthen our position?"
-#define GOSSIP_STW4 "I... I did not think of it that way, Warchief."
-#define GOSSIP_STW5 "I live only to serve, Warchief! My life is empty and meaningless without your guidance."
-#define GOSSIP_STW6 "Of course, Warchief!"
-
/// @todo verify abilities/timers
class npc_thrall_warchief : public CreatureScript
{
@@ -169,32 +179,32 @@ public:
switch (action)
{
case GOSSIP_ACTION_INFO_DEF+1:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
- player->SEND_GOSSIP_MENU(5733, creature->GetGUID());
+ player->ADD_GOSSIP_ITEM_DB(OPTION_WHAT_DISCOVERIES, GOSSIP_MENU_OPTION_ID_ALL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+ player->SEND_GOSSIP_MENU(GOSSIP_THE_SHATTERED_HAND, creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+2:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
- player->SEND_GOSSIP_MENU(5734, creature->GetGUID());
+ player->ADD_GOSSIP_ITEM_DB(OPTION_USURPER, GOSSIP_MENU_OPTION_ID_ALL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
+ player->SEND_GOSSIP_MENU(GOSSIP_IT_WOULD_APPEAR_AS, creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+3:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4);
- player->SEND_GOSSIP_MENU(5735, creature->GetGUID());
+ player->ADD_GOSSIP_ITEM_DB(OPTION_WITH_ALL_DUE_RESPECT, GOSSIP_MENU_OPTION_ID_ALL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4);
+ player->SEND_GOSSIP_MENU(GOSSIP_THE_BROOD_MOTHER, creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+4:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5);
- player->SEND_GOSSIP_MENU(5736, creature->GetGUID());
+ player->ADD_GOSSIP_ITEM_DB(OPTION_I_I_DID_NOT_THINK_OF, GOSSIP_MENU_OPTION_ID_ALL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5);
+ player->SEND_GOSSIP_MENU(GOSSIP_SO_MUCH_TO_LEARN, creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+5:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6);
- player->SEND_GOSSIP_MENU(5737, creature->GetGUID());
+ player->ADD_GOSSIP_ITEM_DB(OPTION_I_LIVE_ONLY_TO_SERVE, GOSSIP_MENU_OPTION_ID_ALL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6);
+ player->SEND_GOSSIP_MENU(GOSSIP_I_DO_NOT_FAULT_YOU, creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+6:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+7);
- player->SEND_GOSSIP_MENU(5738, creature->GetGUID());
+ player->ADD_GOSSIP_ITEM_DB(OPTION_OF_COURSE_WARCHIEF, GOSSIP_MENU_OPTION_ID_ALL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+7);
+ player->SEND_GOSSIP_MENU(GOSSIP_NOW_PAY_ATTENTION, creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+7:
player->CLOSE_GOSSIP_MENU();
- player->AreaExploredOrEventHappens(QUEST_6566);
+ player->AreaExploredOrEventHappens(QUEST_WHAT_THE_WIND_CARRIES);
break;
}
return true;
@@ -205,10 +215,10 @@ public:
if (creature->IsQuestGiver())
player->PrepareQuestMenu(creature->GetGUID());
- if (player->GetQuestStatus(QUEST_6566) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HTW, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ if (player->GetQuestStatus(QUEST_WHAT_THE_WIND_CARRIES) == QUEST_STATUS_INCOMPLETE)
+ player->ADD_GOSSIP_ITEM_DB(OPTION_PLEASE_SHARE_YOUR, GOSSIP_MENU_OPTION_ID_ALL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
+ player->SEND_GOSSIP_MENU(GOSSIP_MEMBERS_OF_THE_HORDE, creature->GetGUID());
return true;
}
diff --git a/src/server/scripts/Northrend/CMakeLists.txt b/src/server/scripts/Northrend/CMakeLists.txt
deleted file mode 100644
index 1dc453ad416..00000000000
--- a/src/server/scripts/Northrend/CMakeLists.txt
+++ /dev/null
@@ -1,199 +0,0 @@
-# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
-#
-# This file is free software; as a special exception the author gives
-# unlimited permission to copy and/or distribute it, with or without
-# modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-set(scripts_STAT_SRCS
- ${scripts_STAT_SRCS}
- Northrend/zone_wintergrasp.cpp
- Northrend/isle_of_conquest.cpp
- Northrend/zone_storm_peaks.cpp
- Northrend/Ulduar/HallsOfLightning/instance_halls_of_lightning.cpp
- Northrend/Ulduar/HallsOfLightning/boss_bjarngrim.cpp
- Northrend/Ulduar/HallsOfLightning/halls_of_lightning.h
- Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp
- Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp
- Northrend/Ulduar/HallsOfLightning/boss_loken.cpp
- Northrend/Ulduar/Ulduar/boss_general_vezax.cpp
- Northrend/Ulduar/Ulduar/boss_thorim.cpp
- Northrend/Ulduar/Ulduar/boss_ignis.cpp
- Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp
- Northrend/Ulduar/Ulduar/instance_ulduar.cpp
- Northrend/Ulduar/Ulduar/boss_auriaya.cpp
- Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp
- Northrend/Ulduar/Ulduar/boss_hodir.cpp
- Northrend/Ulduar/Ulduar/boss_assembly_of_iron.cpp
- Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
- Northrend/Ulduar/Ulduar/boss_xt002.cpp
- Northrend/Ulduar/Ulduar/boss_mimiron.cpp
- Northrend/Ulduar/Ulduar/ulduar.h
- Northrend/Ulduar/Ulduar/boss_freya.cpp
- Northrend/Ulduar/Ulduar/boss_razorscale.cpp
- Northrend/Ulduar/Ulduar/boss_kologarn.cpp
- Northrend/Ulduar/HallsOfStone/boss_krystallus.cpp
- Northrend/Ulduar/HallsOfStone/halls_of_stone.h
- Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp
- Northrend/Ulduar/HallsOfStone/boss_maiden_of_grief.cpp
- Northrend/Ulduar/HallsOfStone/boss_sjonnir.cpp
- Northrend/Ulduar/HallsOfStone/halls_of_stone.cpp
- Northrend/ChamberOfAspects/ObsidianSanctum/instance_obsidian_sanctum.cpp
- Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.h
- Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp
- Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp
- Northrend/ChamberOfAspects/RubySanctum/instance_ruby_sanctum.cpp
- Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.h
- Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.cpp
- Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp
- Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp
- Northrend/ChamberOfAspects/RubySanctum/boss_general_zarithrian.cpp
- Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
- Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h
- Northrend/FrozenHalls/HallsOfReflection/boss_falric.cpp
- Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp
- Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
- Northrend/FrozenHalls/HallsOfReflection/boss_marwyn.cpp
- Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp
- Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp
- Northrend/FrozenHalls/PitOfSaron/pit_of_saron.cpp
- Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp
- Northrend/FrozenHalls/PitOfSaron/pit_of_saron.h
- Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp
- Northrend/FrozenHalls/ForgeOfSouls/forge_of_souls.cpp
- Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp
- Northrend/FrozenHalls/ForgeOfSouls/instance_forge_of_souls.cpp
- Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp
- Northrend/FrozenHalls/ForgeOfSouls/forge_of_souls.h
- Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
- Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp
- Northrend/Nexus/EyeOfEternity/eye_of_eternity.h
- Northrend/Nexus/Oculus/boss_eregos.cpp
- Northrend/Nexus/Oculus/boss_drakos.cpp
- Northrend/Nexus/Oculus/oculus.h
- Northrend/Nexus/Oculus/boss_varos.cpp
- Northrend/Nexus/Oculus/boss_urom.cpp
- Northrend/Nexus/Oculus/oculus.cpp
- Northrend/Nexus/Oculus/instance_oculus.cpp
- Northrend/Nexus/Nexus/boss_nexus_commanders.cpp
- Northrend/Nexus/Nexus/boss_ormorok.cpp
- Northrend/Nexus/Nexus/boss_magus_telestra.cpp
- Northrend/Nexus/Nexus/instance_nexus.cpp
- Northrend/Nexus/Nexus/boss_keristrasza.cpp
- Northrend/Nexus/Nexus/boss_anomalus.cpp
- Northrend/Nexus/Nexus/nexus.h
- Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
- Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp
- Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp
- Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h
- Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp
- Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp
- Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp
- Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp
- Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.h
- Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp
- Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp
- Northrend/CrusadersColiseum/TrialOfTheChampion/boss_black_knight.cpp
- Northrend/CrusadersColiseum/TrialOfTheChampion/instance_trial_of_the_champion.cpp
- Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp
- Northrend/Naxxramas/boss_loatheb.cpp
- Northrend/Naxxramas/boss_anubrekhan.cpp
- Northrend/Naxxramas/boss_maexxna.cpp
- Northrend/Naxxramas/boss_patchwerk.cpp
- Northrend/Naxxramas/boss_gothik.cpp
- Northrend/Naxxramas/boss_faerlina.cpp
- Northrend/Naxxramas/boss_gluth.cpp
- Northrend/Naxxramas/boss_four_horsemen.cpp
- Northrend/Naxxramas/naxxramas.h
- Northrend/Naxxramas/boss_kelthuzad.cpp
- Northrend/Naxxramas/boss_heigan.cpp
- Northrend/Naxxramas/boss_thaddius.cpp
- Northrend/Naxxramas/boss_razuvious.cpp
- Northrend/Naxxramas/boss_sapphiron.cpp
- Northrend/Naxxramas/instance_naxxramas.cpp
- Northrend/Naxxramas/boss_grobbulus.cpp
- Northrend/Naxxramas/boss_noth.cpp
- Northrend/zone_crystalsong_forest.cpp
- Northrend/VaultOfArchavon/boss_archavon.cpp
- Northrend/VaultOfArchavon/boss_koralon.cpp
- Northrend/VaultOfArchavon/vault_of_archavon.h
- Northrend/VaultOfArchavon/instance_vault_of_archavon.cpp
- Northrend/VaultOfArchavon/boss_emalon.cpp
- Northrend/VaultOfArchavon/boss_toravon.cpp
- Northrend/zone_sholazar_basin.cpp
- Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp
- Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp
- Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp
- Northrend/UtgardeKeep/UtgardePinnacle/boss_ymiron.cpp
- Northrend/UtgardeKeep/UtgardePinnacle/instance_utgarde_pinnacle.cpp
- Northrend/UtgardeKeep/UtgardePinnacle/utgarde_pinnacle.h
- Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp
- Northrend/UtgardeKeep/UtgardeKeep/boss_skarvald_dalronn.cpp
- Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.h
- Northrend/UtgardeKeep/UtgardeKeep/instance_utgarde_keep.cpp
- Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp
- Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp
- Northrend/zone_dragonblight.cpp
- Northrend/zone_grizzly_hills.cpp
- Northrend/AzjolNerub/AzjolNerub/azjol_nerub.h
- Northrend/AzjolNerub/AzjolNerub/instance_azjol_nerub.cpp
- Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp
- Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp
- Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp
- Northrend/AzjolNerub/Ahnkahet/boss_herald_volazj.cpp
- Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp
- Northrend/AzjolNerub/Ahnkahet/instance_ahnkahet.cpp
- Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp
- Northrend/AzjolNerub/Ahnkahet/boss_elder_nadox.cpp
- Northrend/AzjolNerub/Ahnkahet/boss_amanitar.cpp
- Northrend/AzjolNerub/Ahnkahet/ahnkahet.h
- Northrend/VioletHold/boss_zuramat.cpp
- Northrend/VioletHold/instance_violet_hold.cpp
- Northrend/VioletHold/boss_lavanthor.cpp
- Northrend/VioletHold/boss_cyanigosa.cpp
- Northrend/VioletHold/violet_hold.h
- Northrend/VioletHold/boss_ichoron.cpp
- Northrend/VioletHold/boss_moragg.cpp
- Northrend/VioletHold/boss_xevozz.cpp
- Northrend/VioletHold/boss_erekem.cpp
- Northrend/VioletHold/violet_hold.cpp
- Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
- Northrend/IcecrownCitadel/icecrown_citadel.cpp
- Northrend/IcecrownCitadel/icecrown_citadel.h
- Northrend/IcecrownCitadel/icecrown_citadel_teleport.cpp
- Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp
- Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
- Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp
- Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
- Northrend/IcecrownCitadel/boss_festergut.cpp
- Northrend/IcecrownCitadel/boss_rotface.cpp
- Northrend/IcecrownCitadel/boss_professor_putricide.cpp
- Northrend/IcecrownCitadel/boss_blood_prince_council.cpp
- Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
- Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
- Northrend/IcecrownCitadel/boss_sindragosa.cpp
- Northrend/IcecrownCitadel/boss_the_lich_king.cpp
- Northrend/zone_zuldrak.cpp
- Northrend/zone_icecrown.cpp
- Northrend/Gundrak/boss_slad_ran.cpp
- Northrend/Gundrak/instance_gundrak.cpp
- Northrend/Gundrak/boss_drakkari_colossus.cpp
- Northrend/Gundrak/gundrak.h
- Northrend/Gundrak/boss_gal_darah.cpp
- Northrend/Gundrak/boss_moorabi.cpp
- Northrend/Gundrak/boss_eck.cpp
- Northrend/zone_borean_tundra.cpp
- Northrend/zone_howling_fjord.cpp
- Northrend/zone_dalaran.cpp
- Northrend/DraktharonKeep/boss_trollgore.cpp
- Northrend/DraktharonKeep/instance_drak_tharon_keep.cpp
- Northrend/DraktharonKeep/boss_novos.cpp
- Northrend/DraktharonKeep/drak_tharon_keep.h
- Northrend/DraktharonKeep/boss_tharon_ja.cpp
- Northrend/DraktharonKeep/boss_king_dred.cpp
-)
-
-message(" -> Prepared: Northrend")
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/instance_ruby_sanctum.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/instance_ruby_sanctum.cpp
index a6cd8362db3..739c3602f44 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/instance_ruby_sanctum.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/instance_ruby_sanctum.cpp
@@ -23,7 +23,7 @@
#include "WorldPacket.h"
#include "ruby_sanctum.h"
-BossBoundaryData const boundaries =
+BossBoundaryData const boundaries =
{
{ DATA_GENERAL_ZARITHRIAN, new EllipseBoundary(Position(3013.409f, 529.492f), 45.0, 100.0) },
{ DATA_HALION, new CircleBoundary(Position(3156.037f, 533.2656f), 48.5) }
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.cpp
index ae4a5e2a69a..9235b75d53e 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.cpp
@@ -18,6 +18,7 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
+#include "SpellScript.h"
#include "ruby_sanctum.h"
#include "Player.h"
@@ -45,6 +46,11 @@ enum Events
EVENT_XERESTRASZA_EVENT_7 = 7,
};
+enum Spells
+{
+ SPELL_RALLY = 75416
+};
+
Position const xerestraszaMovePos = {3151.236f, 379.8733f, 86.31996f, 0.0f};
class npc_xerestrasza : public CreatureScript
@@ -165,8 +171,53 @@ class at_baltharus_plateau : public AreaTriggerScript
}
};
+// 75415 - Rallying Shout
+class spell_ruby_sanctum_rallying_shout : public SpellScriptLoader
+{
+ public:
+ spell_ruby_sanctum_rallying_shout() : SpellScriptLoader("spell_ruby_sanctum_rallying_shout") { }
+
+ class spell_ruby_sanctum_rallying_shout_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_ruby_sanctum_rallying_shout_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_RALLY))
+ return false;
+ return true;
+ }
+
+ void CountTargets(std::list<WorldObject*>& targets)
+ {
+ _targetCount = targets.size();
+ }
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ if (_targetCount && !GetCaster()->HasAura(SPELL_RALLY))
+ GetCaster()->CastCustomSpell(SPELL_RALLY, SPELLVALUE_AURA_STACK, _targetCount, GetCaster(), TRIGGERED_FULL_MASK);
+ }
+
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_ruby_sanctum_rallying_shout_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
+ OnEffectHit += SpellEffectFn(spell_ruby_sanctum_rallying_shout_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+
+ private:
+ uint32 _targetCount = 0;
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_ruby_sanctum_rallying_shout_SpellScript();
+ }
+};
+
void AddSC_ruby_sanctum()
{
new npc_xerestrasza();
new at_baltharus_plateau();
+ new spell_ruby_sanctum_rallying_shout();
}
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp
index eb1e769c07e..278f6a7ab4f 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp
@@ -132,7 +132,7 @@ class OrbsDespawner : public BasicEvent
{
}
- bool Execute(uint64 /*currTime*/, uint32 /*diff*/)
+ bool Execute(uint64 /*currTime*/, uint32 /*diff*/) override
{
Trinity::CreatureWorker<OrbsDespawner> worker(_creature, *this);
_creature->VisitNearbyGridObject(5000.0f, worker);
diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp
index 96bd0aaa35e..5410f403ab9 100644
--- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp
@@ -22,6 +22,7 @@
#include "pit_of_saron.h"
#include "Vehicle.h"
#include "Player.h"
+#include "PlayerAI.h"
enum Yells
{
@@ -438,9 +439,10 @@ class spell_tyrannus_overlord_brand : public SpellScriptLoader
if (GetTarget()->GetTypeId() != TYPEID_PLAYER)
return;
- oldAI = GetTarget()->GetAI();
- oldAIState = GetTarget()->IsAIEnabled;
- GetTarget()->SetAI(new player_overlord_brandAI(GetTarget()->ToPlayer(), GetCasterGUID()));
+ Player* pTarget = GetTarget()->ToPlayer();
+ oldAI = pTarget->AI();
+ oldAIState = pTarget->IsAIEnabled;
+ GetTarget()->SetAI(new player_overlord_brandAI(pTarget, GetCasterGUID()));
GetTarget()->IsAIEnabled = true;
}
@@ -450,7 +452,7 @@ class spell_tyrannus_overlord_brand : public SpellScriptLoader
return;
GetTarget()->IsAIEnabled = oldAIState;
- UnitAI* thisAI = GetTarget()->GetAI();
+ PlayerAI* thisAI = GetTarget()->ToPlayer()->AI();
GetTarget()->SetAI(oldAI);
delete thisAI;
}
@@ -461,7 +463,7 @@ class spell_tyrannus_overlord_brand : public SpellScriptLoader
AfterEffectRemove += AuraEffectRemoveFn(spell_tyrannus_overlord_brand_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
- UnitAI* oldAI;
+ PlayerAI* oldAI;
bool oldAIState;
};
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp
index f59701b9c25..166e9739a95 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp
@@ -160,7 +160,7 @@ class StandUpEvent : public BasicEvent
public:
StandUpEvent(Creature& owner) : BasicEvent(), _owner(owner) { }
- bool Execute(uint64 /*eventTime*/, uint32 /*diff*/)
+ bool Execute(uint64 /*eventTime*/, uint32 /*diff*/) override
{
_owner.HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
_owner.SetReactState(REACT_AGGRESSIVE);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
index d3cf6495aa7..b3a11b8eb31 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
@@ -203,7 +203,7 @@ class DaranavanMoveEvent : public BasicEvent
public:
DaranavanMoveEvent(Creature& darnavan) : _darnavan(darnavan) { }
- bool Execute(uint64 /*time*/, uint32 /*diff*/)
+ bool Execute(uint64 /*time*/, uint32 /*diff*/) override
{
_darnavan.GetMotionMaster()->MovePoint(POINT_DESPAWN, SummonPositions[6]);
return true;
@@ -421,7 +421,7 @@ class boss_lady_deathwhisper : public CreatureScript
void UpdateAI(uint32 diff) override
{
- if ((!UpdateVictim() && !events.IsInPhase(PHASE_INTRO)))
+ if (!UpdateVictim() && !events.IsInPhase(PHASE_INTRO))
return;
events.Update(diff);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
index 2db9d206a00..f4e9d4673f2 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
@@ -562,7 +562,7 @@ class boss_professor_putricide : public CreatureScript
void UpdateAI(uint32 diff) override
{
- if ((!(events.IsInPhase(PHASE_ROTFACE) || events.IsInPhase(PHASE_FESTERGUT)) && !UpdateVictim()))
+ if (!(events.IsInPhase(PHASE_ROTFACE) || events.IsInPhase(PHASE_FESTERGUT)) && !UpdateVictim())
return;
events.Update(diff);
@@ -776,7 +776,7 @@ class npc_volatile_ooze : public CreatureScript
{
}
- void CastMainSpell()
+ void CastMainSpell() override
{
me->CastSpell(me, SPELL_VOLATILE_OOZE_ADHESIVE, false);
}
@@ -800,7 +800,7 @@ class npc_gas_cloud : public CreatureScript
_newTargetSelectTimer = 0;
}
- void CastMainSpell()
+ void CastMainSpell() override
{
me->CastCustomSpell(SPELL_GASEOUS_BLOAT, SPELLVALUE_AURA_STACK, 10, me, false);
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp
index 683dd976b7a..bf69a49055c 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp
@@ -856,14 +856,14 @@ class spell_rotface_vile_gas_trigger : public SpellScriptLoader
GetCaster()->CastSpell(GetHitUnit(), SPELL_VILE_GAS_TRIGGER_SUMMON);
}
- void Register()
+ void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_rotface_vile_gas_trigger_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_rotface_vile_gas_trigger_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
- SpellScript* GetSpellScript() const
+ SpellScript* GetSpellScript() const override
{
return new spell_rotface_vile_gas_trigger_SpellScript();
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
index ac094588d35..0b129f3aa89 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
@@ -134,6 +134,7 @@ enum FrostwingData
DATA_WHELP_MARKER = 2,
DATA_LINKED_GAMEOBJECT = 3,
DATA_TRAPPED_PLAYER = 4,
+ DATA_IS_THIRD_PHASE = 5
};
enum MovementPoints
@@ -168,7 +169,7 @@ class FrostwyrmLandEvent : public BasicEvent
public:
FrostwyrmLandEvent(Creature& owner, Position const& dest) : _owner(owner), _dest(dest) { }
- bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/)
+ bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/) override
{
_owner.GetMotionMaster()->MoveLand(POINT_FROSTWYRM_LAND, _dest);
return true;
@@ -184,7 +185,7 @@ class FrostBombExplosion : public BasicEvent
public:
FrostBombExplosion(Creature* owner, ObjectGuid sindragosaGUID) : _owner(owner), _sindragosaGUID(sindragosaGUID) { }
- bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/)
+ bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/) override
{
_owner->CastSpell((Unit*)NULL, SPELL_FROST_BOMB, false, NULL, NULL, _sindragosaGUID);
_owner->RemoveAurasDueToSpell(SPELL_FROST_BOMB_VISUAL);
@@ -196,20 +197,19 @@ class FrostBombExplosion : public BasicEvent
ObjectGuid _sindragosaGUID;
};
-class FrostBeaconSelector
+class FrostBeaconSelector : NonTankTargetSelector
{
public:
- FrostBeaconSelector(Unit* source) : _source(source) { }
+ FrostBeaconSelector(Unit* source) : NonTankTargetSelector(source, true) { }
- bool operator()(Unit* target) const
+ bool operator()(WorldObject* target) const
{
- return target->GetTypeId() == TYPEID_PLAYER &&
- target != _source->GetVictim() &&
- !target->HasAura(SPELL_ICE_TOMB_UNTARGETABLE);
- }
+ if (Unit* unitTarget = target->ToUnit())
+ return !NonTankTargetSelector::operator()(unitTarget) ||
+ unitTarget->HasAura(SPELL_ICE_TOMB_UNTARGETABLE);
- private:
- Unit* _source;
+ return false;
+ }
};
class boss_sindragosa : public CreatureScript
@@ -326,9 +326,15 @@ class boss_sindragosa : public CreatureScript
uint32 GetData(uint32 type) const override
{
- if (type == DATA_MYSTIC_BUFFET_STACK)
- return _mysticBuffetStack;
- return 0xFFFFFFFF;
+ switch (type)
+ {
+ case DATA_MYSTIC_BUFFET_STACK:
+ return _mysticBuffetStack;
+ case DATA_IS_THIRD_PHASE:
+ return _isThirdPhase;
+ default:
+ return 0xFFFFFFFF;
+ }
}
void MovementInform(uint32 type, uint32 point) override
@@ -419,7 +425,6 @@ class boss_sindragosa : public CreatureScript
if (spellId == spell->Id)
if (Aura const* mysticBuffet = target->GetAura(spell->Id))
_mysticBuffetStack = std::max<uint8>(_mysticBuffetStack, mysticBuffet->GetStackAmount());
-
}
void UpdateAI(uint32 diff) override
@@ -494,11 +499,7 @@ class boss_sindragosa : public CreatureScript
me->GetMotionMaster()->MovePoint(POINT_AIR_PHASE_FAR, SindragosaAirPosFar);
break;
case EVENT_ICE_TOMB:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, FrostBeaconSelector(me)))
- {
- Talk(EMOTE_WARN_FROZEN_ORB, target);
- me->CastCustomSpell(SPELL_ICE_TOMB_TARGET, SPELLVALUE_MAX_TARGETS, 1, nullptr, TRIGGERED_FULL_MASK);
- }
+ me->CastCustomSpell(SPELL_ICE_TOMB_TARGET, SPELLVALUE_MAX_TARGETS, 1, nullptr, TRIGGERED_FULL_MASK);
events.ScheduleEvent(EVENT_ICE_TOMB, urand(16000, 23000));
break;
case EVENT_FROST_BOMB:
@@ -1576,6 +1577,41 @@ class spell_frostwarden_handler_focus_fire : public SpellScriptLoader
}
};
+class spell_sindragosa_ice_tomb_target : public SpellScriptLoader
+{
+public:
+ spell_sindragosa_ice_tomb_target() : SpellScriptLoader("spell_sindragosa_ice_tomb_target") { }
+
+ class spell_sindragosa_ice_tomb_target_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_sindragosa_ice_tomb_target_SpellScript);
+
+ void FilterTargets(std::list<WorldObject*>& unitList)
+ {
+ Unit* caster = GetCaster();
+ unitList.remove_if(FrostBeaconSelector(caster));
+ }
+
+ void HandleSindragosaTalk(SpellEffIndex /*effIndex*/)
+ {
+ if (Creature* creatureCaster = GetCaster()->ToCreature())
+ if (creatureCaster->GetAI()->GetData(DATA_IS_THIRD_PHASE))
+ creatureCaster->AI()->Talk(EMOTE_WARN_FROZEN_ORB, GetHitUnit());
+ }
+
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sindragosa_ice_tomb_target_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnEffectLaunchTarget += SpellEffectFn(spell_sindragosa_ice_tomb_target_SpellScript::HandleSindragosaTalk, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_sindragosa_ice_tomb_target_SpellScript();
+ }
+};
+
class at_sindragosa_lair : public AreaTriggerScript
{
public:
@@ -1641,6 +1677,7 @@ void AddSC_boss_sindragosa()
new spell_frostwarden_handler_focus_fire();
new spell_trigger_spell_from_caster("spell_sindragosa_ice_tomb", SPELL_ICE_TOMB_DUMMY, TRIGGERED_IGNORE_SET_FACING);
new spell_trigger_spell_from_caster("spell_sindragosa_ice_tomb_dummy", SPELL_FROST_BEACON);
+ new spell_sindragosa_ice_tomb_target();
new at_sindragosa_lair();
new achievement_all_you_can_eat();
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
index 9fa624aaad3..4675989228a 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
@@ -437,7 +437,7 @@ class StartMovementEvent : public BasicEvent
{
}
- bool Execute(uint64 /*time*/, uint32 /*diff*/)
+ bool Execute(uint64 /*time*/, uint32 /*diff*/) override
{
_owner->SetReactState(REACT_AGGRESSIVE);
if (Creature* _summoner = ObjectAccessor::GetCreature(*_owner, _summonerGuid))
@@ -459,7 +459,7 @@ class VileSpiritActivateEvent : public BasicEvent
{
}
- bool Execute(uint64 /*time*/, uint32 /*diff*/)
+ bool Execute(uint64 /*time*/, uint32 /*diff*/) override
{
_owner->SetReactState(REACT_AGGRESSIVE);
_owner->CastSpell(_owner, SPELL_VILE_SPIRIT_MOVE_SEARCH, true);
@@ -479,7 +479,7 @@ class TriggerWickedSpirit : public BasicEvent
{
}
- bool Execute(uint64 /*time*/, uint32 /*diff*/)
+ bool Execute(uint64 /*time*/, uint32 /*diff*/) override
{
_owner->CastCustomSpell(SPELL_TRIGGER_VILE_SPIRIT_HEROIC, SPELLVALUE_MAX_TARGETS, 1, NULL, true);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
index 4f35f848927..b07de3457bd 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
@@ -179,7 +179,7 @@ class DelayedCastEvent : public BasicEvent
{
}
- bool Execute(uint64 /*time*/, uint32 /*diff*/)
+ bool Execute(uint64 /*time*/, uint32 /*diff*/) override
{
_trigger->CastSpell(_trigger, _spellId, false, NULL, NULL, _originalCaster);
if (_despawnTime)
@@ -201,7 +201,7 @@ class AuraRemoveEvent : public BasicEvent
{
}
- bool Execute(uint64 /*time*/, uint32 /*diff*/)
+ bool Execute(uint64 /*time*/, uint32 /*diff*/) override
{
_trigger->RemoveAurasDueToSpell(_spellId);
return true;
@@ -219,7 +219,7 @@ class ValithriaDespawner : public BasicEvent
{
}
- bool Execute(uint64 /*currTime*/, uint32 /*diff*/)
+ bool Execute(uint64 /*currTime*/, uint32 /*diff*/) override
{
Trinity::CreatureWorker<ValithriaDespawner> worker(_creature, *this);
_creature->VisitNearbyGridObject(333.0f, worker);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
index 25ca99f6a20..abb9c025771 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
@@ -365,7 +365,7 @@ class CaptainSurviveTalk : public BasicEvent
public:
explicit CaptainSurviveTalk(Creature const& owner) : _owner(owner) { }
- bool Execute(uint64 /*currTime*/, uint32 /*diff*/)
+ bool Execute(uint64 /*currTime*/, uint32 /*diff*/) override
{
_owner.AI()->Talk(SAY_CAPTAIN_SURVIVE_TALK);
return true;
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp b/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp
index e8c4216b00e..60c60640c04 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp
@@ -162,13 +162,13 @@ public:
summons.DoZoneInCombat();
events.SetPhase(PHASE_NORMAL);
- events.ScheduleEvent(EVENT_IMPALE, urand(10 * IN_MILLISECONDS, 20 * IN_MILLISECONDS), 0, PHASE_NORMAL);
- events.ScheduleEvent(EVENT_SCARABS, urand(20 * IN_MILLISECONDS, 30 * IN_MILLISECONDS), 0, PHASE_NORMAL);
- events.ScheduleEvent(EVENT_LOCUST, urand(80,120) * IN_MILLISECONDS, 0, PHASE_NORMAL);
- events.ScheduleEvent(EVENT_BERSERK, 10 * MINUTE * IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_IMPALE, randtime(Seconds(10), Seconds(20)), 0, PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_SCARABS, randtime(Seconds(20), Seconds(30)), 0, PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_LOCUST, Minutes(1)+randtime(Seconds(40), Seconds(60)), 0, PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_BERSERK, Minutes(10));
if (!Is25ManRaid())
- events.ScheduleEvent(EVENT_SPAWN_GUARD, urand(15, 20) * IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_SPAWN_GUARD, randtime(Seconds(15), Seconds(20)));
}
void UpdateAI(uint32 diff) override
@@ -189,11 +189,9 @@ public:
else
EnterEvadeMode();
- events.ScheduleEvent(EVENT_IMPALE, urand(10 * IN_MILLISECONDS, 20 * IN_MILLISECONDS), 0, PHASE_NORMAL);
+ events.Repeat(randtime(Seconds(10), Seconds(20)));
break;
case EVENT_SCARABS:
- events.ScheduleEvent(EVENT_SCARABS, urand(40 * IN_MILLISECONDS, 60 * IN_MILLISECONDS), 0, PHASE_NORMAL);
-
if (!guardCorpses.empty())
{
if (ObjectGuid target = Trinity::Containers::SelectRandomContainerElement(guardCorpses))
@@ -204,27 +202,28 @@ public:
creatureTarget->DespawnOrUnsummon();
}
}
+ events.Repeat(randtime(Seconds(40), Seconds(60)));
break;
case EVENT_LOCUST:
Talk(EMOTE_LOCUST);
+ events.SetPhase(PHASE_SWARM);
DoCast(me, SPELL_LOCUST_SWARM);
- events.ScheduleEvent(EVENT_SPAWN_GUARD, 3 * IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_LOCUST_ENDS, RAID_MODE(19, 23) * IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_LOCUST, 90000);
- events.SetPhase(PHASE_SWARM);
+ events.ScheduleEvent(EVENT_SPAWN_GUARD, Seconds(3));
+ events.ScheduleEvent(EVENT_LOCUST_ENDS, RAID_MODE(Seconds(19), Seconds(23)));
+ events.Repeat(Minutes(1)+Seconds(30));
break;
case EVENT_LOCUST_ENDS:
- events.ScheduleEvent(EVENT_IMPALE, urand(10 * IN_MILLISECONDS, 20 * IN_MILLISECONDS), 0, PHASE_NORMAL);
- events.ScheduleEvent(EVENT_SCARABS, urand(20 * IN_MILLISECONDS, 30 * IN_MILLISECONDS), 0, PHASE_NORMAL);
events.SetPhase(PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_IMPALE, randtime(Seconds(10), Seconds(20)), 0, PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_SCARABS, randtime(Seconds(20), Seconds(30)), 0, PHASE_NORMAL);
break;
case EVENT_SPAWN_GUARD:
me->SummonCreatureGroup(GROUP_SINGLE_SPAWN);
break;
case EVENT_BERSERK:
DoCast(me, SPELL_BERSERK, true);
- events.ScheduleEvent(EVENT_BERSERK, 600000);
+ events.ScheduleEvent(EVENT_BERSERK, Minutes(10));
break;
}
}
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp b/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp
index 39c41c935bf..8a7bdd293ba 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp
@@ -100,9 +100,9 @@ class boss_faerlina : public CreatureScript
_EnterCombat();
Talk(SAY_AGGRO);
summons.DoZoneInCombat();
- events.ScheduleEvent(EVENT_POISON, urand(10 * IN_MILLISECONDS, 15 * IN_MILLISECONDS));
- events.ScheduleEvent(EVENT_FIRE, urand(6 * IN_MILLISECONDS, 18 * IN_MILLISECONDS));
- events.ScheduleEvent(EVENT_FRENZY, urand(60 * IN_MILLISECONDS, 80 * IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_POISON, randtime(Seconds(10), Seconds(15)));
+ events.ScheduleEvent(EVENT_FIRE, randtime(Seconds(6), Seconds(18)));
+ events.ScheduleEvent(EVENT_FRENZY, Minutes(1)+randtime(Seconds(0), Seconds(20)));
}
void Reset() override
@@ -111,9 +111,9 @@ class boss_faerlina : public CreatureScript
_frenzyDispels = 0;
}
- void KilledUnit(Unit* /*victim*/) override
+ void KilledUnit(Unit* victim) override
{
- if (!urand(0, 2))
+ if (victim->GetTypeId() == TYPEID_PLAYER)
Talk(SAY_SLAY);
}
@@ -158,21 +158,21 @@ class boss_faerlina : public CreatureScript
case EVENT_POISON:
if (!me->HasAura(SPELL_WIDOWS_EMBRACE_HELPER))
DoCastAOE(SPELL_POISON_BOLT_VOLLEY);
- events.ScheduleEvent(EVENT_POISON, urand(8000, 15000));
+ events.Repeat(randtime(Seconds(8), Seconds(15)));
break;
case EVENT_FIRE:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
DoCast(target, SPELL_RAIN_OF_FIRE);
- events.ScheduleEvent(EVENT_FIRE, urand(6000, 18000));
+ events.Repeat(randtime(Seconds(6), Seconds(18)));
break;
case EVENT_FRENZY:
if (Aura* widowsEmbrace = me->GetAura(SPELL_WIDOWS_EMBRACE_HELPER))
- events.ScheduleEvent(EVENT_FRENZY, widowsEmbrace->GetDuration()+1 * IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_FRENZY, Milliseconds(widowsEmbrace->GetDuration()+1));
else
{
DoCast(SPELL_FRENZY);
Talk(EMOTE_FRENZY);
- events.ScheduleEvent(EVENT_FRENZY, urand(60 * IN_MILLISECONDS, 80 * IN_MILLISECONDS));
+ events.Repeat(Minutes(1) + randtime(Seconds(0), Seconds(20)));
}
break;
}
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp b/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp
index a7a89f44d81..0de1c4785b8 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp
@@ -285,7 +285,7 @@ struct boss_four_horsemen_baseAI : public BossAI
void EnterCombat(Unit* /*who*/) override
{
- if (instance->GetBossState(BOSS_HORSEMEN) != NOT_STARTED) // another horseman already did it
+ if (instance->GetBossState(BOSS_HORSEMEN) == IN_PROGRESS || instance->GetBossState(BOSS_HORSEMEN) == DONE) // another horseman already did it
return;
Talk(SAY_AGGRO);
BeginEncounter();
@@ -411,9 +411,9 @@ class boss_four_horsemen_baron : public CreatureScript
else
AttackStart(threat.getHostilTarget());
- events.ScheduleEvent(EVENT_BERSERK, 10 * MINUTE * IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_MARK, 24 * IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_UNHOLYSHADOW, urandms(3,7));
+ events.ScheduleEvent(EVENT_BERSERK, Minutes(10));
+ events.ScheduleEvent(EVENT_MARK, Seconds(24));
+ events.ScheduleEvent(EVENT_UNHOLYSHADOW, randtime(Seconds(3), Seconds(7)));
}
void _UpdateAI(uint32 diff) override
@@ -431,11 +431,11 @@ class boss_four_horsemen_baron : public CreatureScript
break;
case EVENT_MARK:
DoCastAOE(SPELL_BARON_MARK, true);
- events.ScheduleEvent(EVENT_MARK, 12 * IN_MILLISECONDS);
+ events.Repeat(Seconds(12));
break;
case EVENT_UNHOLYSHADOW:
DoCastVictim(SPELL_UNHOLY_SHADOW);
- events.ScheduleEvent(EVENT_UNHOLYSHADOW, urandms(10,30));
+ events.Repeat(randtime(Seconds(10), Seconds(30)));
break;
}
}
@@ -484,9 +484,9 @@ class boss_four_horsemen_thane : public CreatureScript
else
AttackStart(threat.getHostilTarget());
- events.ScheduleEvent(EVENT_BERSERK, 10 * MINUTE * IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_MARK, 24 * IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_METEOR, urandms(10,15));
+ events.ScheduleEvent(EVENT_BERSERK, Minutes(10));
+ events.ScheduleEvent(EVENT_MARK, Seconds(24));
+ events.ScheduleEvent(EVENT_METEOR, randtime(Seconds(10), Seconds(25)));
}
void _UpdateAI(uint32 diff) override
{
@@ -503,7 +503,7 @@ class boss_four_horsemen_thane : public CreatureScript
break;
case EVENT_MARK:
DoCastAOE(SPELL_THANE_MARK, true);
- events.ScheduleEvent(EVENT_MARK, 12 * IN_MILLISECONDS);
+ events.Repeat(Seconds(12));
break;
case EVENT_METEOR:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 20.0f, true))
@@ -511,7 +511,7 @@ class boss_four_horsemen_thane : public CreatureScript
DoCast(target, SPELL_METEOR);
_shouldSay = true;
}
- events.ScheduleEvent(EVENT_METEOR, urandms(13,17));
+ events.Repeat(randtime(Seconds(13), Seconds(17)));
break;
}
}
@@ -550,9 +550,9 @@ class boss_four_horsemen_lady : public CreatureScript
boss_four_horsemen_ladyAI(Creature* creature) : boss_four_horsemen_baseAI(creature, LADY, ladyPath) { }
void BeginFighting() override
{
- events.ScheduleEvent(EVENT_BERSERK, 10 * MINUTE * IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_MARK, 24 * IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_VOIDZONE, urandms(5,10));
+ events.ScheduleEvent(EVENT_BERSERK, Minutes(10));
+ events.ScheduleEvent(EVENT_MARK, Seconds(24));
+ events.ScheduleEvent(EVENT_VOIDZONE, randtime(Seconds(5), Seconds(10)));
}
void _UpdateAI(uint32 diff) override
@@ -578,7 +578,7 @@ class boss_four_horsemen_lady : public CreatureScript
break;
case EVENT_MARK:
DoCastAOE(SPELL_LADY_MARK, true);
- events.ScheduleEvent(EVENT_MARK, 15 * IN_MILLISECONDS);
+ events.Repeat(Seconds(15));
break;
case EVENT_VOIDZONE:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45.0f, true))
@@ -586,7 +586,7 @@ class boss_four_horsemen_lady : public CreatureScript
DoCast(target, SPELL_VOID_ZONE, true);
Talk(SAY_SPECIAL);
}
- events.ScheduleEvent(EVENT_VOIDZONE, urandms(12, 18));
+ events.Repeat(randtime(Seconds(12), Seconds(18)));
break;
}
}
@@ -620,9 +620,9 @@ class boss_four_horsemen_sir : public CreatureScript
boss_four_horsemen_sirAI(Creature* creature) : boss_four_horsemen_baseAI(creature, SIR, sirPath), _shouldSay(true) { }
void BeginFighting() override
{
- events.ScheduleEvent(EVENT_BERSERK, 10 * MINUTE * IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_MARK, 24 * IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_HOLYWRATH, urandms(13,18));
+ events.ScheduleEvent(EVENT_BERSERK, Minutes(10));
+ events.ScheduleEvent(EVENT_MARK, Seconds(24));
+ events.ScheduleEvent(EVENT_HOLYWRATH, randtime(Seconds(13), Seconds(18)));
}
void _UpdateAI(uint32 diff) override
@@ -648,7 +648,7 @@ class boss_four_horsemen_sir : public CreatureScript
break;
case EVENT_MARK:
DoCastAOE(SPELL_SIR_MARK, true);
- events.ScheduleEvent(EVENT_MARK, 15 * IN_MILLISECONDS);
+ events.Repeat(Seconds(15));
break;
case EVENT_HOLYWRATH:
if (Unit* target = SelectTarget(SELECT_TARGET_NEAREST, 0, 45.0f, true))
@@ -656,7 +656,7 @@ class boss_four_horsemen_sir : public CreatureScript
DoCast(target, SPELL_HOLY_WRATH, true);
_shouldSay = true;
}
- events.ScheduleEvent(EVENT_HOLYWRATH, urandms(10,18));
+ events.Repeat(randtime(Seconds(10), Seconds(18)));
break;
}
}
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp
index be12894ebea..30c05c9dca9 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp
@@ -65,7 +65,7 @@ enum Spells
/* gothik phase two spells */
SPELL_HARVEST_SOUL = 28679,
SPELL_SHADOW_BOLT = 29317,
-
+
/* visual spells */
SPELL_ANCHOR_1_TRAINEE = 27892,
SPELL_ANCHOR_1_DK = 27928,
@@ -324,13 +324,13 @@ class boss_gothik : public CreatureScript
{
_EnterCombat();
events.SetPhase(PHASE_ONE);
- events.ScheduleEvent(EVENT_SUMMON, 25 * IN_MILLISECONDS, 0, PHASE_ONE);
- events.ScheduleEvent(EVENT_DOORS_UNLOCK, 205 * IN_MILLISECONDS, 0, PHASE_ONE);
- events.ScheduleEvent(EVENT_PHASE_TWO, 270 * IN_MILLISECONDS, 0, PHASE_ONE);
+ events.ScheduleEvent(EVENT_SUMMON, Seconds(25), 0, PHASE_ONE);
+ events.ScheduleEvent(EVENT_DOORS_UNLOCK, Minutes(3) + Seconds(25), 0, PHASE_ONE);
+ events.ScheduleEvent(EVENT_PHASE_TWO, Minutes(4) + Seconds(30), 0, PHASE_ONE);
Talk(SAY_INTRO_1);
- events.ScheduleEvent(EVENT_INTRO_2, 4 * IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_INTRO_3, 9 * IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_INTRO_4, 14 * IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_INTRO_2, Seconds(4));
+ events.ScheduleEvent(EVENT_INTRO_3, Seconds(9));
+ events.ScheduleEvent(EVENT_INTRO_4, Seconds(14));
instance->SetData(DATA_GOTHIK_GATE, GO_STATE_READY);
_gateIsOpen = false;
}
@@ -373,7 +373,7 @@ class boss_gothik : public CreatureScript
instance->SetData(DATA_GOTHIK_GATE, GO_STATE_ACTIVE);
Talk(EMOTE_GATE_OPENED);
_gateIsOpen = true;
-
+
for (ObjectGuid summonGuid : summons)
{
if (Creature* summon = ObjectAccessor::GetCreature(*me, summonGuid))
@@ -444,7 +444,7 @@ class boss_gothik : public CreatureScript
TC_LOG_INFO("scripts", "GothikAI: Wave count %d is out of range for difficulty %d.", _waveCount, GetDifficulty());
break;
}
-
+
std::list<Creature*> triggers;
me->GetCreatureListWithEntryInGrid(triggers, NPC_TRIGGER, 150.0f);
for (GothikWaveEntry entry : RAID_MODE(waves10, waves25)[_waveCount].first)
@@ -470,7 +470,7 @@ class boss_gothik : public CreatureScript
default:
targetDBGuid = 0;
}
-
+
for (Creature* trigger : triggers)
if (trigger && trigger->GetSpawnId() == targetDBGuid)
{
@@ -480,7 +480,7 @@ class boss_gothik : public CreatureScript
}
if (uint8 timeToNext = RAID_MODE(waves10, waves25)[_waveCount].second)
- events.ScheduleEvent(EVENT_SUMMON, timeToNext * IN_MILLISECONDS, 0, PHASE_ONE);
+ events.Repeat(Seconds(timeToNext));
++_waveCount;
break;
@@ -497,9 +497,9 @@ class boss_gothik : public CreatureScript
break;
case EVENT_PHASE_TWO:
events.SetPhase(PHASE_TWO);
- events.ScheduleEvent(EVENT_TELEPORT, 20 * IN_MILLISECONDS, 0, PHASE_TWO);
- events.ScheduleEvent(EVENT_HARVEST, 15 * IN_MILLISECONDS, 0, PHASE_TWO);
- events.ScheduleEvent(EVENT_RESUME_ATTACK, 2 * IN_MILLISECONDS, 0, PHASE_TWO);
+ events.ScheduleEvent(EVENT_TELEPORT, Seconds(20), 0, PHASE_TWO);
+ events.ScheduleEvent(EVENT_HARVEST, Seconds(15), 0, PHASE_TWO);
+ events.ScheduleEvent(EVENT_RESUME_ATTACK, Seconds(2), 0, PHASE_TWO);
Talk(SAY_PHASE_TWO);
Talk(EMOTE_PHASE_TWO);
me->SetReactState(REACT_PASSIVE);
@@ -518,23 +518,23 @@ class boss_gothik : public CreatureScript
_lastTeleportDead = !_lastTeleportDead;
events.CancelEvent(EVENT_BOLT);
- events.ScheduleEvent(EVENT_TELEPORT, 20 * IN_MILLISECONDS, 0, PHASE_TWO);
events.ScheduleEvent(EVENT_RESUME_ATTACK, 2 * IN_MILLISECONDS, 0, PHASE_TWO);
+ events.Repeat(Seconds(20));
}
break;
case EVENT_HARVEST:
DoCastAOE(SPELL_HARVEST_SOUL, true); // triggered allows this to go "through" shadow bolt
- events.ScheduleEvent(EVENT_HARVEST, 15 * IN_MILLISECONDS, 0, PHASE_TWO);
+ events.Repeat(Seconds(15));
break;
case EVENT_RESUME_ATTACK:
me->SetReactState(REACT_AGGRESSIVE);
- events.ScheduleEvent(EVENT_BOLT, 0, 0, PHASE_TWO);
+ events.ScheduleEvent(EVENT_BOLT, Seconds(0), 0, PHASE_TWO);
// return to the start of this method so victim side etc is re-evaluated
return UpdateAI(0u); // tail recursion for efficiency
case EVENT_BOLT:
DoCastVictim(SPELL_SHADOW_BOLT);
- events.ScheduleEvent(EVENT_BOLT, 1 * IN_MILLISECONDS, 0, PHASE_TWO);
+ events.Repeat(Seconds(2));
break;
case EVENT_INTRO_2:
Talk(SAY_INTRO_2);
@@ -548,7 +548,7 @@ class boss_gothik : public CreatureScript
}
}
}
-
+
private:
uint32 _waveCount;
bool _gateCanOpen;
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp b/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp
index a1d8f6e5e02..cf38d659d40 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp
@@ -57,10 +57,10 @@ class boss_grobbulus : public CreatureScript
void EnterCombat(Unit* /*who*/) override
{
_EnterCombat();
- events.ScheduleEvent(EVENT_CLOUD, 15000);
- events.ScheduleEvent(EVENT_INJECT, 20000);
- events.ScheduleEvent(EVENT_SPRAY, urand(15000, 30000)); // not sure
- events.ScheduleEvent(EVENT_BERSERK, 12 * 60000);
+ events.ScheduleEvent(EVENT_CLOUD, Seconds(15));
+ events.ScheduleEvent(EVENT_INJECT, Seconds(20));
+ events.ScheduleEvent(EVENT_SPRAY, randtime(Seconds(15), Seconds(30))); // not sure
+ events.ScheduleEvent(EVENT_BERSERK, Minutes(12));
}
void SpellHitTarget(Unit* target, SpellInfo const* spell) override
@@ -82,19 +82,19 @@ class boss_grobbulus : public CreatureScript
{
case EVENT_CLOUD:
DoCastAOE(SPELL_POISON_CLOUD);
- events.ScheduleEvent(EVENT_CLOUD, 15000);
+ events.Repeat(Seconds(15));
return;
case EVENT_BERSERK:
DoCastAOE(SPELL_BERSERK, true);
return;
case EVENT_SPRAY:
DoCastAOE(SPELL_SLIME_SPRAY);
- events.ScheduleEvent(EVENT_SPRAY, urand(15000, 30000));
+ events.Repeat(randtime(Seconds(15), Seconds(30)));
return;
case EVENT_INJECT:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, -SPELL_MUTATING_INJECTION))
DoCast(target, SPELL_MUTATING_INJECTION);
- events.ScheduleEvent(EVENT_INJECT, 8000 + uint32(120 * me->GetHealthPct()));
+ events.Repeat(Seconds(8) + Milliseconds(uint32(std::round(120 * me->GetHealthPct()))));
return;
default:
break;
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp b/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp
index 9b9619fe5b9..41d718d188d 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp
@@ -27,6 +27,7 @@ enum Spells
SPELL_SPELL_DISRUPTION = 29310,
SPELL_PLAGUE_CLOUD = 29350,
SPELL_TELEPORT_SELF = 30211,
+ SPELL_ERUPTION = 29371
};
enum Yells
@@ -60,6 +61,15 @@ enum Misc
DATA_SAFETY_DANCE = 19962139
};
+static const uint32 firstEruptionDBGUID = 84980;
+static const uint8 numSections = 4;
+static const uint8 numEruptions[numSections] = { // count of sequential GO DBGUIDs in the respective section of the room
+ 15,
+ 25,
+ 23,
+ 13
+};
+
class boss_heigan : public CreatureScript
{
public:
@@ -72,7 +82,7 @@ public:
struct boss_heiganAI : public BossAI
{
- boss_heiganAI(Creature* creature) : BossAI(creature, BOSS_HEIGAN), eruptSection(0), eruptDirection(false), safetyDance(false) { }
+ boss_heiganAI(Creature* creature) : BossAI(creature, BOSS_HEIGAN), _safeSection(0), _danceDirection(false), _safetyDance(false) { }
void Reset() override
{
@@ -82,15 +92,16 @@ public:
void KilledUnit(Unit* who) override
{
- Talk(SAY_SLAY);
-
if (who->GetTypeId() == TYPEID_PLAYER)
- safetyDance = false;
+ {
+ Talk(SAY_SLAY);
+ _safetyDance = false;
+ }
}
uint32 GetData(uint32 type) const override
{
- return (type == DATA_SAFETY_DANCE && safetyDance) ? 1u : 0u;
+ return (type == DATA_SAFETY_DANCE && _safetyDance) ? 1u : 0u;
}
void JustDied(Unit* /*killer*/) override
@@ -104,13 +115,27 @@ public:
_EnterCombat();
Talk(SAY_AGGRO);
- eruptSection = 3;
- events.ScheduleEvent(EVENT_DISRUPT, urand(15 * IN_MILLISECONDS, 20 * IN_MILLISECONDS), 0, PHASE_FIGHT);
- events.ScheduleEvent(EVENT_FEVER, urand(10 * IN_MILLISECONDS, 20 * IN_MILLISECONDS), 0, PHASE_FIGHT);
- events.ScheduleEvent(EVENT_DANCE, 90 * IN_MILLISECONDS, 0, PHASE_FIGHT);
- events.ScheduleEvent(EVENT_ERUPT, 15 * IN_MILLISECONDS, 0, PHASE_FIGHT);
+ _safeSection = 0;
+ events.ScheduleEvent(EVENT_DISRUPT, randtime(Seconds(15), Seconds(20)), 0, PHASE_FIGHT);
+ events.ScheduleEvent(EVENT_FEVER, randtime(Seconds(10), Seconds(20)), 0, PHASE_FIGHT);
+ events.ScheduleEvent(EVENT_DANCE, Minutes(1) + Seconds(30), 0, PHASE_FIGHT);
+ events.ScheduleEvent(EVENT_ERUPT, Seconds(15), 0, PHASE_FIGHT);
+
+ _safetyDance = true;
- safetyDance = true;
+ // figure out the current GUIDs of our eruption tiles and which segment they belong in
+ std::unordered_multimap<uint32, GameObject*> const& mapGOs = me->GetMap()->GetGameObjectBySpawnIdStore();
+ uint32 spawnId = firstEruptionDBGUID;
+ for (uint8 section = 0; section < numSections; ++section)
+ {
+ _eruptTiles[section].clear();
+ for (uint8 i = 0; i < numEruptions[section]; ++i)
+ {
+ std::pair<std::unordered_multimap<uint32, GameObject*>::const_iterator, std::unordered_multimap<uint32, GameObject*>::const_iterator> tileIt = mapGOs.equal_range(spawnId++);
+ for (std::unordered_multimap<uint32, GameObject*>::const_iterator it = tileIt.first; it != tileIt.second; ++it)
+ _eruptTiles[section].push_back(it->second->GetGUID());
+ }
+ }
}
void UpdateAI(uint32 diff) override
@@ -126,52 +151,56 @@ public:
{
case EVENT_DISRUPT:
DoCastAOE(SPELL_SPELL_DISRUPTION);
- events.ScheduleEvent(EVENT_DISRUPT, 11 * IN_MILLISECONDS);
+ events.Repeat(Seconds(11));
break;
case EVENT_FEVER:
DoCastAOE(SPELL_DECREPIT_FEVER);
- events.ScheduleEvent(EVENT_FEVER, urand(20 * IN_MILLISECONDS, 25 * IN_MILLISECONDS));
+ events.Repeat(randtime(Seconds(20), Seconds(25)));
break;
case EVENT_DANCE:
events.SetPhase(PHASE_DANCE);
Talk(SAY_TAUNT);
Talk(EMOTE_DANCE);
- eruptSection = 3;
+ _safeSection = 0;
me->SetReactState(REACT_PASSIVE);
me->AttackStop();
me->StopMoving();
DoCast(SPELL_TELEPORT_SELF);
DoCastAOE(SPELL_PLAGUE_CLOUD);
- events.ScheduleEvent(EVENT_DANCE_END, 45 * IN_MILLISECONDS, 0, PHASE_DANCE);
- events.ScheduleEvent(EVENT_ERUPT, 10 * IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_DANCE_END, Seconds(45), 0, PHASE_DANCE);
+ events.ScheduleEvent(EVENT_ERUPT, Seconds(10));
break;
case EVENT_DANCE_END:
events.SetPhase(PHASE_FIGHT);
Talk(EMOTE_DANCE_END);
- eruptSection = 3;
- events.ScheduleEvent(EVENT_DISRUPT, urand(10, 25) * IN_MILLISECONDS, 0, PHASE_FIGHT);
- events.ScheduleEvent(EVENT_FEVER, urand(15, 20) * IN_MILLISECONDS, 0, PHASE_FIGHT);
- events.ScheduleEvent(EVENT_DANCE, 90 * IN_MILLISECONDS, 0, PHASE_FIGHT);
- events.ScheduleEvent(EVENT_ERUPT, 15 * IN_MILLISECONDS, 0, PHASE_FIGHT);
+ _safeSection = 0;
+ events.ScheduleEvent(EVENT_DISRUPT, randtime(Seconds(10), Seconds(25)), 0, PHASE_FIGHT);
+ events.ScheduleEvent(EVENT_FEVER, randtime(Seconds(15), Seconds(20)), 0, PHASE_FIGHT);
+ events.ScheduleEvent(EVENT_DANCE, Minutes(1) + Seconds(30), 0, PHASE_FIGHT);
+ events.ScheduleEvent(EVENT_ERUPT, Seconds(15), 0, PHASE_FIGHT);
me->CastStop();
me->SetReactState(REACT_AGGRESSIVE);
DoZoneInCombat();
break;
case EVENT_ERUPT:
- instance->SetData(DATA_HEIGAN_ERUPT, eruptSection);
TeleportCheaters();
-
- if (eruptSection == 0)
- eruptDirection = true;
- else if (eruptSection == 3)
- eruptDirection = false;
-
- eruptDirection ? ++eruptSection : --eruptSection;
-
- if (events.IsInPhase(PHASE_DANCE))
- events.ScheduleEvent(EVENT_ERUPT, 3 * IN_MILLISECONDS, 0, PHASE_DANCE);
- else
- events.ScheduleEvent(EVENT_ERUPT, 10 * IN_MILLISECONDS, 0, PHASE_FIGHT);
+ for (uint8 section = 0; section < numSections; ++section)
+ if (section != _safeSection)
+ for (ObjectGuid tileGUID : _eruptTiles[section])
+ if (GameObject* tile = ObjectAccessor::GetGameObject(*me, tileGUID))
+ {
+ tile->SendCustomAnim(0);
+ tile->CastSpell(nullptr, SPELL_ERUPTION);
+ }
+
+ if (_safeSection == 0)
+ _danceDirection = true;
+ else if (_safeSection == numSections-1)
+ _danceDirection = false;
+
+ _danceDirection ? ++_safeSection : --_safeSection;
+
+ events.Repeat(events.IsInPhase(PHASE_DANCE) ? Seconds(3) : Seconds(10));
break;
}
}
@@ -180,10 +209,11 @@ public:
}
private:
- uint32 eruptSection;
- bool eruptDirection;
+ std::vector<ObjectGuid> _eruptTiles[numSections]; // populated on encounter start
- bool safetyDance; // is achievement still possible? (= no player deaths yet)
+ uint32 _safeSection; // 0 is next to the entrance
+ bool _danceDirection; // true is counter-clockwise, false is clock-wise
+ bool _safetyDance; // is achievement still possible? (= no player deaths yet)
};
};
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_loatheb.cpp b/src/server/scripts/Northrend/Naxxramas/boss_loatheb.cpp
index 086d21120e8..c6c9c76bed4 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_loatheb.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_loatheb.cpp
@@ -24,7 +24,6 @@
enum Spells
{
SPELL_NECROTIC_AURA = 55593,
- SPELL_WARN_NECROTIC_AURA = 59481,
SPELL_SUMMON_SPORE = 29234,
SPELL_DEATHBLOOM = 29865,
SPELL_INEVITABLE_DOOM = 29204,
@@ -42,11 +41,12 @@ enum Texts
enum Events
{
- EVENT_NECROTIC_AURA = 1,
- EVENT_DEATHBLOOM = 2,
- EVENT_INEVITABLE_DOOM = 3,
- EVENT_SPORE = 4,
- EVENT_NECROTIC_AURA_FADING = 5,
+ EVENT_NECROTIC_AURA = 1,
+ EVENT_DEATHBLOOM,
+ EVENT_INEVITABLE_DOOM,
+ EVENT_SPORE,
+ EVENT_NECROTIC_AURA_FADING,
+ EVENT_NECROTIC_AURA_FADED
};
enum Achievement
@@ -82,10 +82,10 @@ class boss_loatheb : public CreatureScript
void EnterCombat(Unit* /*who*/) override
{
_EnterCombat();
- events.ScheduleEvent(EVENT_NECROTIC_AURA, 17 * IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_DEATHBLOOM, 5 * IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_SPORE, RAID_MODE(36,18) * IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_INEVITABLE_DOOM, 2 * MINUTE * IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_NECROTIC_AURA, Seconds(17));
+ events.ScheduleEvent(EVENT_DEATHBLOOM, Seconds(5));
+ events.ScheduleEvent(EVENT_SPORE, Seconds(18));
+ events.ScheduleEvent(EVENT_INEVITABLE_DOOM, Minutes(2));
}
void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
@@ -94,13 +94,6 @@ class boss_loatheb : public CreatureScript
summon->CastSpell(summon,SPELL_FUNGAL_CREEP,true);
}
- void SummonedCreatureDespawn(Creature* summon) override
- {
- summons.Despawn(summon);
- if (summon->IsAlive())
- summon->CastSpell(summon,SPELL_FUNGAL_CREEP,true);
- }
-
uint32 GetData(uint32 id) const override
{
return (_sporeLoserData && id == DATA_ACHIEVEMENT_SPORE_LOSER) ? 1u : 0u;
@@ -119,34 +112,33 @@ class boss_loatheb : public CreatureScript
{
case EVENT_NECROTIC_AURA:
DoCastAOE(SPELL_NECROTIC_AURA);
- DoCast(me, SPELL_WARN_NECROTIC_AURA);
- events.ScheduleEvent(EVENT_NECROTIC_AURA, 20 * IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_NECROTIC_AURA_FADING, 14 * IN_MILLISECONDS);
+ Talk(SAY_NECROTIC_AURA_APPLIED);
+ events.ScheduleEvent(EVENT_NECROTIC_AURA_FADING, Seconds(14));
+ events.ScheduleEvent(EVENT_NECROTIC_AURA_FADED, Seconds(17));
+ events.Repeat(Seconds(20));
break;
case EVENT_DEATHBLOOM:
DoCastAOE(SPELL_DEATHBLOOM);
- events.ScheduleEvent(EVENT_DEATHBLOOM, 30 * IN_MILLISECONDS);
+ events.Repeat(Seconds(30));
break;
case EVENT_INEVITABLE_DOOM:
_doomCounter++;
DoCastAOE(SPELL_INEVITABLE_DOOM);
if (_doomCounter > 6)
- {
- if (_doomCounter & 1) // odd
- events.ScheduleEvent(EVENT_INEVITABLE_DOOM, 14 * IN_MILLISECONDS);
- else
- events.ScheduleEvent(EVENT_INEVITABLE_DOOM, 17 * IN_MILLISECONDS);
- }
+ events.Repeat((_doomCounter & 1) ? Seconds(14) : Seconds(17));
else
- events.ScheduleEvent(EVENT_INEVITABLE_DOOM, 30 * IN_MILLISECONDS);
+ events.Repeat(30);
break;
case EVENT_SPORE:
DoCast(me, SPELL_SUMMON_SPORE, false);
- events.ScheduleEvent(EVENT_SPORE, RAID_MODE(36,18) * IN_MILLISECONDS);
+ events.Repeat(RAID_MODE(Seconds(36), Seconds(15)));
break;
case EVENT_NECROTIC_AURA_FADING:
Talk(SAY_NECROTIC_AURA_FADING);
break;
+ case EVENT_NECROTIC_AURA_FADED:
+ Talk(SAY_NECROTIC_AURA_REMOVED);
+ break;
default:
break;
}
@@ -177,49 +169,6 @@ class achievement_spore_loser : public AchievementCriteriaScript
}
};
-typedef boss_loatheb::boss_loathebAI LoathebAI;
-
-class spell_loatheb_necrotic_aura_warning : public SpellScriptLoader
-{
- public:
- spell_loatheb_necrotic_aura_warning() : SpellScriptLoader("spell_loatheb_necrotic_aura_warning") { }
-
- class spell_loatheb_necrotic_aura_warning_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_loatheb_necrotic_aura_warning_AuraScript);
-
- bool Validate(SpellInfo const* /*spell*/) override
- {
- if (!sSpellStore.LookupEntry(SPELL_WARN_NECROTIC_AURA))
- return false;
- return true;
- }
-
- void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
- {
- if (GetTarget()->IsAIEnabled)
- ENSURE_AI(LoathebAI, GetTarget()->GetAI())->Talk(SAY_NECROTIC_AURA_APPLIED);
- }
-
- void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
- {
- if (GetTarget()->IsAIEnabled)
- ENSURE_AI(LoathebAI, GetTarget()->GetAI())->Talk(SAY_NECROTIC_AURA_REMOVED);
- }
-
- void Register() override
- {
- AfterEffectApply += AuraEffectApplyFn(spell_loatheb_necrotic_aura_warning_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
- AfterEffectRemove += AuraEffectRemoveFn(spell_loatheb_necrotic_aura_warning_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
- }
- };
-
- AuraScript* GetAuraScript() const override
- {
- return new spell_loatheb_necrotic_aura_warning_AuraScript();
- }
-};
-
class spell_loatheb_deathbloom : public SpellScriptLoader
{
public:
@@ -260,6 +209,5 @@ void AddSC_boss_loatheb()
{
new boss_loatheb();
new achievement_spore_loser();
- new spell_loatheb_necrotic_aura_warning();
new spell_loatheb_deathbloom();
}
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp b/src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp
index 9d8f1365afb..9502193884a 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp
@@ -73,6 +73,8 @@ struct WebTargetSelector : public std::unary_function<Unit*, bool>
WebTargetSelector(Unit* maexxna) : _maexxna(maexxna) {}
bool operator()(Unit const* target) const
{
+ if (target->GetTypeId() != TYPEID_PLAYER) // never web nonplayers (pets, guardians, etc.)
+ return false;
if (_maexxna->GetVictim() == target) // never target tank
return false;
if (target->HasAura(SPELL_WEB_WRAP)) // never target targets that are already webbed
@@ -101,11 +103,11 @@ public:
void EnterCombat(Unit* /*who*/) override
{
_EnterCombat();
- events.ScheduleEvent(EVENT_WRAP, 20 * IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_SPRAY, 40 * IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_SHOCK, urandms(5, 10));
- events.ScheduleEvent(EVENT_POISON, urandms(10, 15));
- events.ScheduleEvent(EVENT_SUMMON, 30 * IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_WRAP, Seconds(20));
+ events.ScheduleEvent(EVENT_SPRAY, Seconds(40));
+ events.ScheduleEvent(EVENT_SHOCK, randtime(Seconds(5), Seconds(10)));
+ events.ScheduleEvent(EVENT_POISON, randtime(Seconds(10), Seconds(15)));
+ events.ScheduleEvent(EVENT_SUMMON, Seconds(30));
}
void Reset() override
@@ -153,28 +155,28 @@ public:
}
}
}
- events.ScheduleEvent(EVENT_WRAP, 40000);
+ events.Repeat(Seconds(40));
break;
}
case EVENT_SPRAY:
Talk(EMOTE_WEB_SPRAY);
DoCastAOE(SPELL_WEB_SPRAY);
- events.ScheduleEvent(EVENT_SPRAY, 40000);
+ events.Repeat(Seconds(40));
break;
case EVENT_SHOCK:
DoCastAOE(SPELL_POISON_SHOCK);
- events.ScheduleEvent(EVENT_SHOCK, urandms(10, 20));
+ events.Repeat(randtime(Seconds(10), Seconds(20)));
break;
case EVENT_POISON:
DoCastVictim(SPELL_NECROTIC_POISON);
- events.ScheduleEvent(EVENT_POISON, urandms(10, 20));
+ events.Repeat(randtime(Seconds(10), Seconds(20)));
break;
case EVENT_SUMMON:
Talk(EMOTE_SPIDERS);
uint8 amount = urand(8, 10);
for (uint8 i = 0; i < amount; ++i)
DoSummon(NPC_SPIDERLING, me, 4.0f, 5 * IN_MILLISECONDS, TEMPSUMMON_CORPSE_TIMED_DESPAWN);
- events.ScheduleEvent(EVENT_SUMMON, 40000);
+ events.Repeat(Seconds(40));
break;
}
}
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp b/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp
index 8ee3936dee3..2108b4ce102 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp
@@ -131,25 +131,25 @@ public:
Reset();
else
{
- uint8 secondsGround;
+ uint8 timeGround;
switch (balconyCount)
{
case 0:
- secondsGround = 90;
+ timeGround = 90;
break;
case 1:
- secondsGround = 110;
+ timeGround = 110;
break;
case 2:
default:
- secondsGround = 180;
+ timeGround = 180;
}
- events.ScheduleEvent(EVENT_GROUND_ATTACKABLE, 2 * IN_MILLISECONDS, 0, PHASE_GROUND);
- events.ScheduleEvent(EVENT_BALCONY, secondsGround * IN_MILLISECONDS, 0, PHASE_GROUND);
- events.ScheduleEvent(EVENT_CURSE, urand(10,25) * IN_MILLISECONDS, 0, PHASE_GROUND);
- events.ScheduleEvent(EVENT_WARRIOR, urand(20,30) * IN_MILLISECONDS, 0, PHASE_GROUND);
+ events.ScheduleEvent(EVENT_GROUND_ATTACKABLE, Seconds(2), 0, PHASE_GROUND);
+ events.ScheduleEvent(EVENT_BALCONY, Seconds(timeGround), 0, PHASE_GROUND);
+ events.ScheduleEvent(EVENT_CURSE, randtime(Seconds(10), Seconds(25)), 0, PHASE_GROUND);
+ events.ScheduleEvent(EVENT_WARRIOR, randtime(Seconds(20), Seconds(30)), 0, PHASE_GROUND);
if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)
- events.ScheduleEvent(EVENT_BLINK, urand(20,30) * IN_MILLISECONDS, 0, PHASE_GROUND);
+ events.ScheduleEvent(EVENT_BLINK, randtime(Seconds(20), Seconds(30)), 0, PHASE_GROUND);
}
}
@@ -220,7 +220,7 @@ public:
case EVENT_CURSE:
{
DoCastAOE(SPELL_CURSE);
- events.ScheduleEvent(EVENT_CURSE, urand(50, 70) * IN_MILLISECONDS, 0, PHASE_GROUND);
+ events.Repeat(randtime(Seconds(50), Seconds(70)));
break;
}
case EVENT_WARRIOR:
@@ -229,7 +229,7 @@ public:
CastSummon(RAID_MODE(2, 3), 0, 0);
- events.ScheduleEvent(EVENT_WARRIOR, 40 * IN_MILLISECONDS, 0, PHASE_GROUND);
+ events.Repeat(Seconds(40));
break;
case EVENT_BLINK:
DoCastAOE(SPELL_CRIPPLE, true);
@@ -237,7 +237,7 @@ public:
DoResetThreat();
justBlinked = true;
- events.ScheduleEvent(EVENT_BLINK, 40000, 0, PHASE_GROUND);
+ events.Repeat(Seconds(40));
break;
case EVENT_BALCONY:
events.SetPhase(PHASE_BALCONY);
@@ -247,24 +247,24 @@ public:
me->StopMoving();
me->RemoveAllAuras();
- events.ScheduleEvent(EVENT_BALCONY_TELEPORT, 3 * IN_MILLISECONDS, 0, PHASE_BALCONY);
- events.ScheduleEvent(EVENT_WAVE, urand(5 * IN_MILLISECONDS, 8 * IN_MILLISECONDS), 0, PHASE_BALCONY);
+ events.ScheduleEvent(EVENT_BALCONY_TELEPORT, Seconds(3), 0, PHASE_BALCONY);
+ events.ScheduleEvent(EVENT_WAVE, randtime(Seconds(5), Seconds(8)), 0, PHASE_BALCONY);
- uint8 secondsBalcony;
+ uint8 timeBalcony;
switch (balconyCount)
{
case 0:
- secondsBalcony = 70;
+ timeBalcony = 70;
break;
case 1:
- secondsBalcony = 97;
+ timeBalcony = 97;
break;
case 2:
default:
- secondsBalcony = 120;
+ timeBalcony = 120;
break;
}
- events.ScheduleEvent(EVENT_GROUND, secondsBalcony * IN_MILLISECONDS, 0, PHASE_BALCONY);
+ events.ScheduleEvent(EVENT_GROUND, Seconds(timeBalcony), 0, PHASE_BALCONY);
break;
case EVENT_BALCONY_TELEPORT:
Talk(EMOTE_TELEPORT_1);
@@ -287,7 +287,7 @@ public:
CastSummon(0, RAID_MODE(5, 10), RAID_MODE(5, 10));
break;
}
- events.ScheduleEvent(EVENT_WAVE, urand(30, 45) * IN_MILLISECONDS, 0, PHASE_BALCONY);
+ events.Repeat(randtime(Seconds(30), Seconds(45)));
break;
case EVENT_GROUND:
++balconyCount;
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_patchwerk.cpp b/src/server/scripts/Northrend/Naxxramas/boss_patchwerk.cpp
index b8ce402a939..cfa6e2e9f30 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_patchwerk.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_patchwerk.cpp
@@ -97,8 +97,8 @@ public:
_EnterCombat();
Enraged = false;
Talk(SAY_AGGRO);
- events.ScheduleEvent(EVENT_HATEFUL, 1 * IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_BERSERK, 6 * MINUTE * IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_HATEFUL, Seconds(1));
+ events.ScheduleEvent(EVENT_BERSERK, Minutes(6));
instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_MAKE_QUICK_WERK_OF_HIM_STARTING_EVENT);
}
@@ -167,17 +167,17 @@ public:
if (thirdThreatTarget)
me->getThreatManager().addThreat(thirdThreatTarget, HATEFUL_THREAT_AMT); // this will only ever be used in 25m
- events.ScheduleEvent(EVENT_HATEFUL, 1 * IN_MILLISECONDS);
+ events.Repeat(Seconds(1));
break;
}
case EVENT_BERSERK:
DoCast(me, SPELL_BERSERK, true);
Talk(EMOTE_BERSERK);
- events.ScheduleEvent(EVENT_SLIME, 2 * IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_SLIME, Seconds(2));
break;
case EVENT_SLIME:
- DoCastVictim(SPELL_SLIME_BOLT, true);
- events.ScheduleEvent(EVENT_SLIME, 2 * IN_MILLISECONDS);
+ DoCastAOE(SPELL_SLIME_BOLT, true);
+ events.Repeat(Seconds(2));
break;
}
}
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_razuvious.cpp b/src/server/scripts/Northrend/Naxxramas/boss_razuvious.cpp
index 1d12f64a949..548f8086eb8 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_razuvious.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_razuvious.cpp
@@ -104,6 +104,9 @@ public:
void JustDied(Unit* /*killer*/) override
{
+ for (ObjectGuid summonGuid : summons)
+ if (Creature* summon = ObjectAccessor::GetCreature(*me, summonGuid))
+ summon->RemoveCharmAuras();
Talk(SAY_DEATH);
DoCastAOE(SPELL_HOPELESS, true);
@@ -117,10 +120,10 @@ public:
me->StopMoving();
summons.DoZoneInCombat();
Talk(SAY_AGGRO);
- events.ScheduleEvent(EVENT_ATTACK, 7 * IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_STRIKE, 21 * IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_SHOUT, 16 * IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_KNIFE, 10 * IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_ATTACK, Seconds(7));
+ events.ScheduleEvent(EVENT_STRIKE, Seconds(21));
+ events.ScheduleEvent(EVENT_SHOUT, Seconds(16));
+ events.ScheduleEvent(EVENT_KNIFE, Seconds(10));
}
void UpdateAI(uint32 diff) override
@@ -141,16 +144,16 @@ public:
break;
case EVENT_STRIKE:
DoCastVictim(SPELL_UNBALANCING_STRIKE);
- events.ScheduleEvent(EVENT_STRIKE, 6 * IN_MILLISECONDS);
+ events.Repeat(Seconds(6));
return;
case EVENT_SHOUT:
DoCastAOE(SPELL_DISRUPTING_SHOUT);
- events.ScheduleEvent(EVENT_SHOUT, 16 * IN_MILLISECONDS);
+ events.Repeat(Seconds(16));
return;
case EVENT_KNIFE:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45.0f))
DoCast(target, SPELL_JAGGED_KNIFE);
- events.ScheduleEvent(EVENT_KNIFE, urandms(10,15));
+ events.Repeat(randtime(Seconds(10), Seconds(15)));
return;
}
}
@@ -174,7 +177,10 @@ class npc_dk_understudy : public CreatureScript
struct npc_dk_understudyAI : public ScriptedAI
{
- npc_dk_understudyAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), bloodStrikeTimer(0) { }
+ npc_dk_understudyAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), bloodStrikeTimer(0)
+ {
+ creature->LoadEquipment(1);
+ }
void EnterCombat(Unit* /*who*/) override
{
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp b/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp
index 68b9e252150..4596b17bc23 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp
@@ -16,7 +16,9 @@
*/
#include "ScriptMgr.h"
+#include "GameObjectAI.h"
#include "ScriptedCreature.h"
+#include "SpellScript.h"
#include "Player.h"
#include "SpellInfo.h"
#include "naxxramas.h"
@@ -31,25 +33,24 @@ enum Yells
enum Spells
{
- SPELL_FROST_AURA = 28531,
- SPELL_CLEAVE = 19983,
- SPELL_TAIL_SWEEP = 55697,
- SPELL_SUMMON_BLIZZARD = 28560,
- SPELL_LIFE_DRAIN = 28542,
- SPELL_ICEBOLT = 28522,
- SPELL_FROST_BREATH = 29318,
- SPELL_FROST_EXPLOSION = 28524,
- SPELL_FROST_MISSILE = 30101,
- SPELL_BERSERK = 26662,
- SPELL_DIES = 29357,
- SPELL_CHILL = 28547,
- SPELL_CHECK_RESISTS = 60539,
+ SPELL_FROST_AURA = 28531,
+ SPELL_CLEAVE = 19983,
+ SPELL_TAIL_SWEEP = 55697,
+ SPELL_SUMMON_BLIZZARD = 28560,
+ SPELL_LIFE_DRAIN = 28542,
+ SPELL_ICEBOLT = 28522,
+ SPELL_FROST_BREATH_ANTICHEAT = 29318, // damage effect ignoring LoS on the entrance platform to prevent cheese
+ SPELL_FROST_BREATH = 28524, // damage effect below sapphiron
+ SPELL_FROST_MISSILE = 30101, // visual only
+ SPELL_BERSERK = 26662,
+ SPELL_DIES = 29357,
+ SPELL_CHECK_RESISTS = 60539,
+ SPELL_SAPPHIRON_WING_BUFFET = 29328
};
enum Phases
{
- PHASE_NULL = 0,
- PHASE_BIRTH,
+ PHASE_BIRTH = 1,
PHASE_GROUND,
PHASE_FLIGHT
};
@@ -72,9 +73,15 @@ enum Events
EVENT_CHECK_RESISTS
};
+enum Actions
+{
+ ACTION_BIRTH = 1
+};
+
enum Misc
{
NPC_BLIZZARD = 16474,
+ NPC_WING_BUFFET = 17025,
GO_ICEBLOCK = 181247,
// The Hundred Club
@@ -92,77 +99,74 @@ class boss_sapphiron : public CreatureScript
struct boss_sapphironAI : public BossAI
{
boss_sapphironAI(Creature* creature) :
- BossAI(creature, BOSS_SAPPHIRON), _iceboltCount(0), _map(me->GetMap())
+ BossAI(creature, BOSS_SAPPHIRON)
{
Initialize();
}
void Initialize()
{
- _phase = PHASE_NULL;
-
+ _delayedDrain = false;
_canTheHundredClub = true;
}
void InitializeAI() override
{
+ if (instance->GetBossState(BOSS_SAPPHIRON) == DONE)
+ return;
+
_canTheHundredClub = true;
- float x, y, z;
- me->GetPosition(x, y, z);
- me->SummonGameObject(GO_BIRTH, x, y, z, 0, 0, 0, 0, 0, 0);
- me->SetVisible(false);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- me->SetReactState(REACT_PASSIVE);
+ if (!instance->GetData(DATA_HAD_SAPPHIRON_BIRTH))
+ {
+ me->SetVisible(false);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ me->SetReactState(REACT_PASSIVE);
+ }
BossAI::InitializeAI();
}
void Reset() override
{
- _Reset();
-
- if (_phase == PHASE_FLIGHT)
+ if (events.IsInPhase(PHASE_FLIGHT))
{
- ClearIceBlock();
+ instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_ICEBOLT);
me->SetReactState(REACT_AGGRESSIVE);
if (me->IsHovering())
{
me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
me->SetHover(false);
}
- me->SetDisableGravity(false);
}
+ _Reset();
Initialize();
}
+ void DamageTaken(Unit* /*who*/, uint32& damage) override
+ {
+ if (damage < me->GetHealth() || !events.IsInPhase(PHASE_FLIGHT))
+ return;
+ damage = me->GetHealth()-1; // don't die during air phase
+ }
+
void EnterCombat(Unit* /*who*/) override
{
_EnterCombat();
me->CastSpell(me, SPELL_FROST_AURA, true);
- DoCast(me, SPELL_CHECK_RESISTS);
- events.ScheduleEvent(EVENT_CHECK_RESISTS, 30 * IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_BERSERK, 15 * MINUTE * IN_MILLISECONDS);
- EnterPhaseGround();
+ events.SetPhase(PHASE_GROUND);
+ events.ScheduleEvent(EVENT_CHECK_RESISTS, Seconds(0));
+ events.ScheduleEvent(EVENT_BERSERK, Minutes(15));
+ EnterPhaseGround(true);
}
void SpellHitTarget(Unit* target, SpellInfo const* spell) override
{
switch(spell->Id)
{
- case SPELL_ICEBOLT:
- {
- IceBlockMap::iterator itr = _iceblocks.find(target->GetGUID());
- if (itr != _iceblocks.end() && !itr->second)
- {
- if (GameObject* iceblock = me->SummonGameObject(GO_ICEBLOCK, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, 0, 0, 0, 0, 25))
- itr->second = iceblock->GetGUID();
- }
- break;
- }
case SPELL_CHECK_RESISTS:
if (target && target->GetResistance(SPELL_SCHOOL_FROST) > MAX_FROST_RESISTANCE)
_canTheHundredClub = false;
@@ -179,41 +183,37 @@ class boss_sapphiron : public CreatureScript
void MovementInform(uint32 /*type*/, uint32 id) override
{
if (id == 1)
- events.ScheduleEvent(EVENT_LIFTOFF, 0);
+ events.ScheduleEvent(EVENT_LIFTOFF, Seconds(0), 0, PHASE_FLIGHT);
}
void DoAction(int32 param) override
{
- if (param == DATA_SAPPHIRON_BIRTH)
+ if (param == ACTION_BIRTH)
{
- _phase = PHASE_BIRTH;
- events.ScheduleEvent(EVENT_BIRTH, 23 * IN_MILLISECONDS);
+ events.SetPhase(PHASE_BIRTH);
+ events.ScheduleEvent(EVENT_BIRTH, Seconds(23));
}
}
- void EnterPhaseGround()
+ void EnterPhaseGround(bool initial)
{
- _phase = PHASE_GROUND;
me->SetReactState(REACT_AGGRESSIVE);
- events.SetPhase(PHASE_GROUND);
- events.ScheduleEvent(EVENT_CLEAVE, urand(5, 15) * IN_MILLISECONDS, 0, PHASE_GROUND);
- events.ScheduleEvent(EVENT_TAIL, urand(5, 15) * IN_MILLISECONDS, 0, PHASE_GROUND);
- events.ScheduleEvent(EVENT_DRAIN, 24 * IN_MILLISECONDS, 0, PHASE_GROUND);
- events.ScheduleEvent(EVENT_BLIZZARD, urand(5, 10) * IN_MILLISECONDS, 0, PHASE_GROUND);
- events.ScheduleEvent(EVENT_FLIGHT, 45 * IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_CLEAVE, randtime(Seconds(5), Seconds(15)), 0, PHASE_GROUND);
+ events.ScheduleEvent(EVENT_TAIL, randtime(Seconds(7), Seconds(10)), 0, PHASE_GROUND);
+ events.ScheduleEvent(EVENT_BLIZZARD, randtime(Seconds(5), Seconds(10)), 0, PHASE_GROUND);
+ if (initial)
+ {
+ events.ScheduleEvent(EVENT_DRAIN, randtime(Seconds(22), Seconds(28)));
+ events.ScheduleEvent(EVENT_FLIGHT, Seconds(48) + Milliseconds(500), 0, PHASE_GROUND);
+ }
+ else
+ events.ScheduleEvent(EVENT_FLIGHT, Minutes(1), 0, PHASE_GROUND);
}
- void ClearIceBlock()
+ inline void CastDrain()
{
- for (IceBlockMap::const_iterator itr = _iceblocks.begin(); itr != _iceblocks.end(); ++itr)
- {
- if (Player* player = ObjectAccessor::GetPlayer(*me, itr->first))
- player->RemoveAura(SPELL_ICEBOLT);
-
- if (GameObject* go = ObjectAccessor::GetGameObject(*me, itr->second))
- go->Delete();
- }
- _iceblocks.clear();
+ DoCastAOE(SPELL_LIFE_DRAIN);
+ events.ScheduleEvent(EVENT_DRAIN, randtime(Seconds(22), Seconds(28)));
}
uint32 GetData(uint32 data) const override
@@ -226,15 +226,12 @@ class boss_sapphiron : public CreatureScript
void UpdateAI(uint32 diff) override
{
- if (!_phase)
- return;
-
events.Update(diff);
- if (_phase != PHASE_BIRTH && !UpdateVictim())
+ if (!events.IsInPhase(PHASE_BIRTH) && !UpdateVictim())
return;
- if (_phase == PHASE_GROUND)
+ if (events.IsInPhase(PHASE_GROUND))
{
while (uint32 eventId = events.ExecuteEvent())
{
@@ -242,7 +239,10 @@ class boss_sapphiron : public CreatureScript
{
case EVENT_CHECK_RESISTS:
DoCast(me, SPELL_CHECK_RESISTS);
- events.ScheduleEvent(EVENT_CHECK_RESISTS, 30 * IN_MILLISECONDS);
+ events.Repeat(Seconds(30));
+ return;
+ case EVENT_GROUND:
+ EnterPhaseGround(false);
return;
case EVENT_BERSERK:
Talk(EMOTE_ENRAGE);
@@ -250,27 +250,26 @@ class boss_sapphiron : public CreatureScript
return;
case EVENT_CLEAVE:
DoCastVictim(SPELL_CLEAVE);
- events.ScheduleEvent(EVENT_CLEAVE, urand(5, 15) * IN_MILLISECONDS, 0, PHASE_GROUND);
+ events.ScheduleEvent(EVENT_CLEAVE, randtime(Seconds(5), Seconds(15)), 0, PHASE_GROUND);
return;
case EVENT_TAIL:
DoCastAOE(SPELL_TAIL_SWEEP);
- events.ScheduleEvent(EVENT_TAIL, urand(5, 15) * IN_MILLISECONDS, 0, PHASE_GROUND);
+ events.ScheduleEvent(EVENT_TAIL, randtime(Seconds(7), Seconds(10)), 0, PHASE_GROUND);
return;
case EVENT_DRAIN:
- DoCastAOE(SPELL_LIFE_DRAIN);
- events.ScheduleEvent(EVENT_DRAIN, 24 * IN_MILLISECONDS, 0, PHASE_GROUND);
+ if (events.IsInPhase(PHASE_FLIGHT))
+ _delayedDrain = true;
+ else
+ CastDrain();
return;
case EVENT_BLIZZARD:
- {
- if (Creature* summon = DoSummon(NPC_BLIZZARD, me, 0.0f, urand(25, 30) * IN_MILLISECONDS, TEMPSUMMON_TIMED_DESPAWN))
- summon->GetMotionMaster()->MoveRandom(40);
- events.ScheduleEvent(EVENT_BLIZZARD, RAID_MODE(20, 7) * IN_MILLISECONDS, 0, PHASE_GROUND);
+ DoCastAOE(SPELL_SUMMON_BLIZZARD);
+ events.ScheduleEvent(EVENT_BLIZZARD, RAID_MODE(Seconds(20), Seconds(7)), 0, PHASE_GROUND);
break;
- }
case EVENT_FLIGHT:
if (HealthAbovePct(10))
{
- _phase = PHASE_FLIGHT;
+ _delayedDrain = false;
events.SetPhase(PHASE_FLIGHT);
me->SetReactState(REACT_PASSIVE);
me->AttackStop();
@@ -293,61 +292,69 @@ class boss_sapphiron : public CreatureScript
{
case EVENT_CHECK_RESISTS:
DoCast(me, SPELL_CHECK_RESISTS);
- events.ScheduleEvent(EVENT_CHECK_RESISTS, 30 * IN_MILLISECONDS);
+ events.Repeat(Seconds(30));
return;
case EVENT_LIFTOFF:
+ {
Talk(EMOTE_AIR_PHASE);
- me->SetDisableGravity(true);
+ if (Creature* buffet = DoSummon(NPC_WING_BUFFET, me, 0.0f, 0, TEMPSUMMON_MANUAL_DESPAWN))
+ _buffet = buffet->GetGUID();
+ me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
me->SetHover(true);
- events.ScheduleEvent(EVENT_ICEBOLT, 1500);
- _iceboltCount = RAID_MODE(2, 3);
+ events.ScheduleEvent(EVENT_ICEBOLT, Seconds(7), 0, PHASE_FLIGHT);
+
+ _iceboltTargets.clear();
+ std::list<Unit*> targets;
+ SelectTargetList(targets, RAID_MODE(2, 3), SELECT_TARGET_RANDOM, 200.0f, true);
+ for (Unit* target : targets)
+ if (target)
+ _iceboltTargets.push_back(target->GetGUID());
return;
+ }
case EVENT_ICEBOLT:
{
- std::vector<Unit*> targets;
- std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin();
- for (; i != me->getThreatManager().getThreatList().end(); ++i)
- if ((*i)->getTarget()->GetTypeId() == TYPEID_PLAYER && !(*i)->getTarget()->HasAura(SPELL_ICEBOLT))
- targets.push_back((*i)->getTarget());
-
- if (targets.empty())
- _iceboltCount = 0;
- else
+ if (_iceboltTargets.empty())
{
- std::vector<Unit*>::const_iterator itr = targets.begin();
- advance(itr, rand32() % targets.size());
- _iceblocks.insert(std::make_pair((*itr)->GetGUID(), ObjectGuid::Empty));
- DoCast(*itr, SPELL_ICEBOLT);
- --_iceboltCount;
+ events.ScheduleEvent(EVENT_BREATH, Seconds(2), 0, PHASE_FLIGHT);
+ return;
}
-
- if (_iceboltCount)
- events.ScheduleEvent(EVENT_ICEBOLT, 1 * IN_MILLISECONDS);
+ ObjectGuid target = _iceboltTargets.back();
+ if (Player* pTarget = ObjectAccessor::GetPlayer(*me, target))
+ if (pTarget->IsAlive())
+ DoCast(pTarget, SPELL_ICEBOLT);
+ _iceboltTargets.pop_back();
+
+ if (_iceboltTargets.empty())
+ events.ScheduleEvent(EVENT_BREATH, Seconds(2), 0, PHASE_FLIGHT);
else
- events.ScheduleEvent(EVENT_BREATH, 1 * IN_MILLISECONDS);
+ events.Repeat(Seconds(3));
return;
}
case EVENT_BREATH:
{
Talk(EMOTE_BREATH);
DoCastAOE(SPELL_FROST_MISSILE);
- events.ScheduleEvent(EVENT_EXPLOSION, 8 * IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_EXPLOSION, Seconds(8), 0, PHASE_FLIGHT);
return;
}
case EVENT_EXPLOSION:
- CastExplosion();
- ClearIceBlock();
- events.ScheduleEvent(EVENT_LAND, 3 * IN_MILLISECONDS);
+ DoCastAOE(SPELL_FROST_BREATH);
+ DoCastAOE(SPELL_FROST_BREATH_ANTICHEAT);
+ events.ScheduleEvent(EVENT_LAND, Seconds(3) + Milliseconds(500), 0, PHASE_FLIGHT);
return;
case EVENT_LAND:
+ if (_delayedDrain)
+ CastDrain();
+ if (Creature* cBuffet = ObjectAccessor::GetCreature(*me, _buffet))
+ {
+ cBuffet->DespawnOrUnsummon(1 * IN_MILLISECONDS);
+ _buffet.Clear();
+ }
me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
Talk(EMOTE_GROUND_PHASE);
me->SetHover(false);
- me->SetDisableGravity(false);
- events.ScheduleEvent(EVENT_GROUND, 1500);
- return;
- case EVENT_GROUND:
- EnterPhaseGround();
+ events.SetPhase(PHASE_GROUND);
+ events.ScheduleEvent(EVENT_GROUND, Seconds(3) + Milliseconds(500), 0, PHASE_GROUND);
return;
case EVENT_BIRTH:
me->SetVisible(true);
@@ -359,56 +366,261 @@ class boss_sapphiron : public CreatureScript
}
}
- void CastExplosion()
+ private:
+ std::vector<ObjectGuid> _iceboltTargets;
+ ObjectGuid _buffet;
+ bool _delayedDrain;
+ bool _canTheHundredClub;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new boss_sapphironAI(creature);
+ }
+};
+
+class go_sapphiron_birth : public GameObjectScript
+{
+ public:
+ go_sapphiron_birth() : GameObjectScript("go_sapphiron_birth") { }
+
+ struct go_sapphiron_birthAI : public GameObjectAI
+ {
+ go_sapphiron_birthAI(GameObject* go) : GameObjectAI(go), instance(go->GetInstanceScript()) { }
+
+ void OnStateChanged(uint32 state, Unit* who) override
+ {
+ if (state == GO_ACTIVATED)
+ {
+ if (who)
+ {
+ if (Creature* sapphiron = ObjectAccessor::GetCreature(*go, instance->GetGuidData(DATA_SAPPHIRON)))
+ sapphiron->AI()->DoAction(ACTION_BIRTH);
+ instance->SetData(DATA_HAD_SAPPHIRON_BIRTH, 1u);
+ }
+ }
+ else if (state == GO_JUST_DEACTIVATED)
+ { // prevent ourselves from going back to _READY and resetting the client anim
+ go->SetRespawnTime(0);
+ go->Delete();
+ }
+ }
+
+ InstanceScript* instance;
+ };
+
+ GameObjectAI* GetAI(GameObject* go) const override
+ {
+ return GetInstanceAI<go_sapphiron_birthAI>(go);
+ }
+};
+
+
+class spell_sapphiron_change_blizzard_target : public SpellScriptLoader
+{
+ public:
+ spell_sapphiron_change_blizzard_target() : SpellScriptLoader("spell_sapphiron_change_blizzard_target") { }
+
+ class spell_sapphiron_change_blizzard_target_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_sapphiron_change_blizzard_target_AuraScript);
+
+ void HandlePeriodic(AuraEffect const* /*eff*/)
+ {
+ TempSummon* me = GetTarget()->ToTempSummon();
+ if (Creature* owner = me ? me->GetSummonerCreatureBase() : nullptr)
+ {
+ Unit* newTarget = owner->AI()->SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true);
+ if (!newTarget)
+ newTarget = owner->getAttackerForHelper();
+ if (newTarget)
+ me->GetMotionMaster()->MoveFollow(newTarget, 0.1f, 0.0f);
+ else
+ {
+ me->StopMoving();
+ me->GetMotionMaster()->Clear();
+ }
+ }
+ }
+
+ void Register() override
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_sapphiron_change_blizzard_target_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_sapphiron_change_blizzard_target_AuraScript();
+ }
+};
+
+class spell_sapphiron_icebolt : public SpellScriptLoader
+{
+ public:
+ spell_sapphiron_icebolt() : SpellScriptLoader("spell_sapphiron_icebolt") { }
+
+ class spell_sapphiron_icebolt_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_sapphiron_icebolt_AuraScript);
+
+ void HandleApply(AuraEffect const* /*eff*/, AuraEffectHandleModes /*mode*/)
+ {
+ GetTarget()->ApplySpellImmune(SPELL_ICEBOLT, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_FROST, true);
+ }
+
+ void HandleRemove(AuraEffect const* /*eff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (_block)
+ if (GameObject* oBlock = ObjectAccessor::GetGameObject(*GetTarget(), _block))
+ oBlock->Delete();
+ GetTarget()->ApplySpellImmune(SPELL_ICEBOLT, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_FROST, false);
+ }
+
+ void HandlePeriodic(AuraEffect const* /*eff*/)
+ {
+ if (_block)
+ return;
+ if (GetTarget()->isMoving())
+ return;
+ float x, y, z;
+ GetTarget()->GetPosition(x, y, z);
+ if (GameObject* block = GetTarget()->SummonGameObject(GO_ICEBLOCK, x, y, z, 0, 0, 0, 0, 0, 25))
+ _block = block->GetGUID();
+ }
+
+ void Register() override
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_sapphiron_icebolt_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_sapphiron_icebolt_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL);
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_sapphiron_icebolt_AuraScript::HandlePeriodic, EFFECT_2, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
+ }
+
+ ObjectGuid _block;
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_sapphiron_icebolt_AuraScript();
+ }
+};
+
+// @hack Hello, developer from the future! How has your day been?
+// Anyway, this is, as you can undoubtedly see, a hack to emulate line of sight checks on a spell that abides line of sight anyway.
+// In the current core, line of sight is not properly checked for people standing behind an ice block. This is not a good thing and kills people.
+// Thus, we have this hack to check for ice block LoS in a "safe" way. Kind of. It's inaccurate, but in a good way (tends to save people when it shouldn't in edge cases).
+// If LoS handling is better in whatever the current revision is when you read this, please get rid of the hack. Thanks!
+class spell_sapphiron_frost_breath : public SpellScriptLoader
+{
+ public:
+ spell_sapphiron_frost_breath() : SpellScriptLoader("spell_sapphiron_frost_breath") { }
+
+ class spell_sapphiron_frost_breath_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_sapphiron_frost_breath_SpellScript);
+
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ return !!sSpellMgr->GetSpellInfo(SPELL_FROST_BREATH);
+ }
+
+ void HandleTargets(std::list<WorldObject*>& targetList)
{
- DoZoneInCombat(); // make sure everyone is in threatlist
- std::vector<Unit*> targets;
- std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin();
- for (; i != me->getThreatManager().getThreatList().end(); ++i)
+ std::list<GameObject*> blocks;
+ if (GetCaster())
+ GetCaster()->GetGameObjectListWithEntryInGrid(blocks, GO_ICEBLOCK, 200.0f);
+
+ std::vector<Unit*> toRemove;
+ toRemove.reserve(3);
+ std::list<WorldObject*>::iterator it = targetList.begin();
+ while (it != targetList.end())
{
- Unit* target = (*i)->getTarget();
- if (target->GetTypeId() != TYPEID_PLAYER)
+ Unit* target = (*it)->ToUnit();
+ if (!target)
+ {
+ it = targetList.erase(it);
continue;
+ }
if (target->HasAura(SPELL_ICEBOLT))
{
- target->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, true);
- targets.push_back(target);
+ it = targetList.erase(it);
+ toRemove.push_back(target);
+ continue;
+ }
+
+ bool found = false;
+ for (GameObject* block : blocks)
+ if (block->IsInBetween(GetCaster(), target, 2.0f) && GetCaster()->GetExactDist2d(block) + 5 >= GetCaster()->GetExactDist2d(target))
+ {
+ found = true;
+ break;
+ }
+ if (found)
+ {
+ it = targetList.erase(it);
continue;
}
+ ++it;
+ }
+
+ for (Unit* block : toRemove)
+ block->RemoveAura(SPELL_ICEBOLT);
+ }
+
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sapphiron_frost_breath_SpellScript::HandleTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
+ }
+ };
- for (IceBlockMap::const_iterator itr = _iceblocks.begin(); itr != _iceblocks.end(); ++itr)
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_sapphiron_frost_breath_SpellScript();
+ }
+};
+
+class spell_sapphiron_summon_blizzard : public SpellScriptLoader
+{
+ public:
+ spell_sapphiron_summon_blizzard() : SpellScriptLoader("spell_sapphiron_summon_blizzard") { }
+
+ class spell_sapphiron_summon_blizzard_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_sapphiron_summon_blizzard_SpellScript);
+
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ return !!sSpellMgr->GetSpellInfo(SPELL_SUMMON_BLIZZARD);
+ }
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* target = GetHitUnit())
+ if (Creature* blizzard = GetCaster()->SummonCreature(NPC_BLIZZARD, *target, TEMPSUMMON_TIMED_DESPAWN, urandms(25, 30)))
{
- if (GameObject* go = ObjectAccessor::GetGameObject(*me, itr->second))
+ blizzard->CastSpell(nullptr, blizzard->m_spells[0], TRIGGERED_NONE);
+ if (Creature* creatureCaster = GetCaster()->ToCreature())
{
- if (go->IsInBetween(me, target, 2.0f)
- && me->GetExactDist2d(target->GetPositionX(), target->GetPositionY()) - me->GetExactDist2d(go->GetPositionX(), go->GetPositionY()) < 5.0f)
+ if (Unit* newTarget = creatureCaster->AI()->SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true))
{
- target->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, true);
- targets.push_back(target);
- break;
+ blizzard->GetMotionMaster()->MoveFollow(newTarget, 0.1f, 0.0f);
+ return;
}
}
+ blizzard->GetMotionMaster()->MoveFollow(target, 0.1f, 0.0f);
}
- }
-
- me->CastSpell(me, SPELL_FROST_EXPLOSION, true);
-
- for (std::vector<Unit*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr)
- (*itr)->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, false);
}
- private:
- Phases _phase;
- uint32 _iceboltCount;
- IceBlockMap _iceblocks;
- bool _canTheHundredClub;
- Map* _map;
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_sapphiron_summon_blizzard_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
};
- CreatureAI* GetAI(Creature* creature) const override
+ SpellScript* GetSpellScript() const override
{
- return new boss_sapphironAI(creature);
+ return new spell_sapphiron_summon_blizzard_SpellScript();
}
};
@@ -426,5 +638,10 @@ class achievement_the_hundred_club : public AchievementCriteriaScript
void AddSC_boss_sapphiron()
{
new boss_sapphiron();
+ new go_sapphiron_birth();
+ new spell_sapphiron_change_blizzard_target();
+ new spell_sapphiron_icebolt();
+ new spell_sapphiron_frost_breath();
+ new spell_sapphiron_summon_blizzard();
new achievement_the_hundred_club();
}
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp b/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp
index 7330f90e585..2cf3a4664dd 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp
@@ -109,6 +109,10 @@ enum PetSpells
SPELL_MAGNETIC_PULL = 54517,
SPELL_MAGNETIC_PULL_EFFECT = 28337,
+ // @hack feugen/stalagg use this in P1 after gripping tanks to prevent mmaps from pathing them off the platform once they approach the ramp
+ // developer from the future, if you read this and mmaps in the room has been fixed, then get rid of the hackfix, please
+ SPELL_ROOT_SELF = 75215,
+
SPELL_TESLA_SHOCK = 28099
};
@@ -166,10 +170,12 @@ public:
struct boss_thaddiusAI : public BossAI
{
public:
- boss_thaddiusAI(Creature* creature) : BossAI(creature, BOSS_THADDIUS), stalaggAlive(true), feugenAlive(true), ballLightningEnabled(false), shockingEligibility(true)
+ boss_thaddiusAI(Creature* creature) : BossAI(creature, BOSS_THADDIUS), stalaggAlive(true), feugenAlive(true), ballLightningUnlocked(false), ballLightningEnabled(false), shockingEligibility(true) {}
+
+ void InitializeAI() override
{
if (instance->GetBossState(BOSS_THADDIUS) != DONE)
- {
+ {
events.SetPhase(PHASE_NOT_ENGAGED);
SetCombatMovement(false);
@@ -184,12 +190,33 @@ public:
Talk(SAY_SLAY);
}
- void Reset() override
+ void Reset() override { }
+
+ void EnterEvadeMode(EvadeReason why) override
{
+ if (!ballLightningEnabled && why == EVADE_REASON_NO_HOSTILES)
+ {
+ ballLightningEnabled = true;
+ return; // try again
+ }
if (events.IsInPhase(PHASE_TRANSITION) || (events.IsInPhase(PHASE_THADDIUS) && me->IsAlive()))
BeginResetEncounter();
}
+ bool CanAIAttack(Unit const* who) const override
+ {
+ if (ballLightningEnabled || me->IsWithinMeleeRange(who))
+ return BossAI::CanAIAttack(who);
+ else
+ return false;
+ }
+
+ void JustRespawned() override
+ {
+ if (events.IsInPhase(PHASE_RESETTING))
+ ResetEncounter();
+ }
+
void JustDied(Unit* /*killer*/) override
{
_JustDied();
@@ -217,18 +244,25 @@ public:
case ACTION_FEUGEN_AGGRO:
case ACTION_STALAGG_AGGRO:
if (events.IsInPhase(PHASE_RESETTING))
- return BeginResetEncounter();
+ {
+ BeginResetEncounter();
+ return;
+ }
if (!events.IsInPhase(PHASE_NOT_ENGAGED))
return;
events.SetPhase(PHASE_PETS);
shockingEligibility = true;
-
+
if (!instance->CheckRequiredBosses(BOSS_THADDIUS))
- return BeginResetEncounter();
+ {
+ BeginResetEncounter();
+ return;
+ }
instance->SetBossState(BOSS_THADDIUS, IN_PROGRESS);
me->setActive(true);
+ DoZoneInCombat();
if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG)))
stalagg->setActive(true);
if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN)))
@@ -239,7 +273,7 @@ public:
feugen->AI()->DoAction(ACTION_FEUGEN_REVIVING_FX);
feugenAlive = false;
if (stalaggAlive)
- events.ScheduleEvent(EVENT_REVIVE_FEUGEN, 5 * IN_MILLISECONDS, 0, PHASE_PETS);
+ events.ScheduleEvent(EVENT_REVIVE_FEUGEN, Seconds(5), 0, PHASE_PETS);
else
Transition();
@@ -249,7 +283,7 @@ public:
stalagg->AI()->DoAction(ACTION_STALAGG_REVIVING_FX);
stalaggAlive = false;
if (feugenAlive)
- events.ScheduleEvent(EVENT_REVIVE_STALAGG, 5 * IN_MILLISECONDS, 0, PHASE_PETS);
+ events.ScheduleEvent(EVENT_REVIVE_STALAGG, Seconds(5), 0, PHASE_PETS);
else
Transition();
@@ -274,9 +308,9 @@ public:
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- events.ScheduleEvent(EVENT_TRANSITION_1, 10 * IN_MILLISECONDS, 0, PHASE_TRANSITION);
- events.ScheduleEvent(EVENT_TRANSITION_2, 12 * IN_MILLISECONDS, 0, PHASE_TRANSITION);
- events.ScheduleEvent(EVENT_TRANSITION_3, 14 * IN_MILLISECONDS, 0, PHASE_TRANSITION);
+ events.ScheduleEvent(EVENT_TRANSITION_1, Seconds(10), 0, PHASE_TRANSITION);
+ events.ScheduleEvent(EVENT_TRANSITION_2, Seconds(12), 0, PHASE_TRANSITION);
+ events.ScheduleEvent(EVENT_TRANSITION_3, Seconds(14), 0, PHASE_TRANSITION);
}
void BeginResetEncounter(bool initial = false)
@@ -286,16 +320,12 @@ public:
if (events.IsInPhase(PHASE_RESETTING))
return;
- if (initial) // signal shorter spawn timer to instance script
- instance->SetBossState(BOSS_THADDIUS, SPECIAL);
- instance->ProcessEvent(me, EVENT_THADDIUS_BEGIN_RESET);
- instance->SetBossState(BOSS_THADDIUS, NOT_STARTED);
-
// remove polarity shift debuffs on reset
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_POSITIVE_CHARGE_APPLY);
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_NEGATIVE_CHARGE_APPLY);
me->DespawnOrUnsummon();
+ me->SetRespawnTime(initial ? 5 : 30);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED);
events.SetPhase(PHASE_RESETTING);
@@ -312,11 +342,9 @@ public:
feugenAlive = true;
stalaggAlive = true;
- me->Respawn(true);
_Reset();
events.SetPhase(PHASE_NOT_ENGAGED);
-
- me->CastSpell(me, SPELL_THADDIUS_INACTIVE_VISUAL, true);
+ me->SetReactState(REACT_PASSIVE);
if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN)))
feugen->AI()->DoAction(ACTION_RESET_ENCOUNTER);
@@ -361,16 +389,20 @@ public:
break;
case EVENT_TRANSITION_3: // thaddius becomes active
me->CastSpell(me, SPELL_THADDIUS_SPARK_VISUAL, true);
- ballLightningEnabled = false;
+ ballLightningUnlocked = false;
me->RemoveAura(SPELL_THADDIUS_INACTIVE_VISUAL);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
-
+ me->SetReactState(REACT_AGGRESSIVE);
+
DoZoneInCombat();
if (Unit* closest = SelectTarget(SELECT_TARGET_NEAREST, 0, 500.0f))
AttackStart(closest);
else // if there is no nearest target, then there is no target, meaning we should reset
- return BeginResetEncounter();
+ {
+ BeginResetEncounter();
+ return;
+ }
if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN)))
feugen->AI()->DoAction(ACTION_TRANSITION_3);
@@ -381,20 +413,20 @@ public:
Talk(SAY_AGGRO);
- events.ScheduleEvent(EVENT_ENABLE_BALL_LIGHTNING, 5 * IN_MILLISECONDS, 0, PHASE_THADDIUS);
- events.ScheduleEvent(EVENT_SHIFT, 10 * IN_MILLISECONDS, 0, PHASE_THADDIUS);
- events.ScheduleEvent(EVENT_CHAIN, urand(10, 20) * IN_MILLISECONDS, 0, PHASE_THADDIUS);
- events.ScheduleEvent(EVENT_BERSERK, 6 * MINUTE * IN_MILLISECONDS, 0, PHASE_THADDIUS);
+ events.ScheduleEvent(EVENT_ENABLE_BALL_LIGHTNING, Seconds(5), 0, PHASE_THADDIUS);
+ events.ScheduleEvent(EVENT_SHIFT, Seconds(10), 0, PHASE_THADDIUS);
+ events.ScheduleEvent(EVENT_CHAIN, randtime(Seconds(10), Seconds(20)), 0, PHASE_THADDIUS);
+ events.ScheduleEvent(EVENT_BERSERK, Minutes(6), 0, PHASE_THADDIUS);
break;
case EVENT_ENABLE_BALL_LIGHTNING:
- ballLightningEnabled = true;
+ ballLightningUnlocked = true;
break;
case EVENT_SHIFT:
me->CastStop(); // shift overrides all other spells
DoCastAOE(SPELL_POLARITY_SHIFT);
- events.ScheduleEvent(EVENT_SHIFT_TALK, 3 * IN_MILLISECONDS, PHASE_THADDIUS);
- events.ScheduleEvent(EVENT_SHIFT, 30 * IN_MILLISECONDS, PHASE_THADDIUS);
+ events.ScheduleEvent(EVENT_SHIFT_TALK, Seconds(3), PHASE_THADDIUS);
+ events.ScheduleEvent(EVENT_SHIFT, Seconds(30), PHASE_THADDIUS);
break;
case EVENT_SHIFT_TALK:
Talk(SAY_ELECT);
@@ -402,12 +434,12 @@ public:
break;
case EVENT_CHAIN:
if (me->FindCurrentSpellBySpellId(SPELL_POLARITY_SHIFT)) // delay until shift is over
- events.ScheduleEvent(EVENT_CHAIN, 3 * IN_MILLISECONDS, 0, PHASE_THADDIUS);
+ events.Repeat(Seconds(3));
else
{
me->CastStop();
DoCastVictim(SPELL_CHAIN_LIGHTNING);
- events.ScheduleEvent(EVENT_CHAIN, urand(10, 20) * IN_MILLISECONDS, PHASE_THADDIUS);
+ events.Repeat(randtime(Seconds(10), Seconds(20)));
}
break;
case EVENT_BERSERK:
@@ -418,22 +450,24 @@ public:
break;
}
}
-
- if (events.IsInPhase(PHASE_THADDIUS))
+ if (events.IsInPhase(PHASE_THADDIUS) && !me->HasUnitState(UNIT_STATE_CASTING) && me->isAttackReady())
{
if (me->IsWithinMeleeRange(me->GetVictim()))
+ {
+ ballLightningEnabled = false;
DoMeleeAttackIfReady();
- else
- if (ballLightningEnabled)
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
- DoCast(target, SPELL_BALL_LIGHTNING);
+ }
+ else if (ballLightningUnlocked)
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(target, SPELL_BALL_LIGHTNING);
}
}
private:
bool stalaggAlive;
bool feugenAlive;
- bool ballLightningEnabled;
+ bool ballLightningUnlocked; // whether the initial ball lightning grace period has expired and we should proceed to exterminate with extreme prejudice
+ bool ballLightningEnabled; // switch that is flipped to true if we try to evade due to no eligible targets in melee range
bool shockingEligibility;
};
@@ -521,7 +555,7 @@ public:
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
Talk(EMOTE_FEIGN_REVIVE);
isFeignDeath = false;
-
+
refreshBeam = true; // force beam refresh
if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN)))
@@ -586,7 +620,7 @@ public:
damage = 0;
return;
}
-
+
isFeignDeath = true;
isOverloading = false;
@@ -652,7 +686,7 @@ public:
else
{
DoCast(me, SPELL_STALAGG_POWERSURGE);
- powerSurgeTimer = urand(25, 30) * IN_MILLISECONDS;
+ powerSurgeTimer = urandms(25, 30);
}
}
else
@@ -790,7 +824,7 @@ public:
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
Talk(EMOTE_FEIGN_REVIVE);
isFeignDeath = false;
-
+
refreshBeam = true; // force beam refresh
if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG)))
@@ -836,7 +870,7 @@ public:
Talk(SAY_FEUGEN_AGGRO);
if (Creature* thaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS)))
- thaddius->AI()->DoAction(ACTION_STALAGG_AGGRO);
+ thaddius->AI()->DoAction(ACTION_FEUGEN_AGGRO);
if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG)))
if (!stalagg->IsInCombat())
@@ -922,7 +956,7 @@ public:
magneticPullTimer = 20 * IN_MILLISECONDS;
}
else magneticPullTimer -= uiDiff;
-
+
if (staticFieldTimer <= uiDiff)
{
DoCast(me, SPELL_FEUGEN_STATICFIELD);
@@ -971,7 +1005,7 @@ public:
ObjectGuid _myCoil;
ObjectGuid _myCoilGO;
-
+
bool isOverloading;
bool refreshBeam;
bool isFeignDeath;
@@ -1094,7 +1128,7 @@ class spell_thaddius_polarity_charge : public SpellScriptLoader
SpellScript* GetSpellScript() const override
{
- return new spell_thaddius_polarity_charge_SpellScript;
+ return new spell_thaddius_polarity_charge_SpellScript();
}
};
@@ -1169,7 +1203,7 @@ class spell_thaddius_magnetic_pull : public SpellScriptLoader
Unit* feugen = GetCaster();
if (!feugen || feugen->GetEntry() != NPC_FEUGEN)
return;
-
+
Unit* stalagg = ObjectAccessor::GetCreature(*feugen, feugen->GetInstanceScript()->GetGuidData(DATA_STALAGG));
if (!stalagg)
return;
@@ -1212,6 +1246,10 @@ class spell_thaddius_magnetic_pull : public SpellScriptLoader
feugenTank->CastSpell(stalaggTank, SPELL_MAGNETIC_PULL_EFFECT, true);
stalaggTank->CastSpell(feugenTank, SPELL_MAGNETIC_PULL_EFFECT, true);
+ // @hack prevent mmaps clusterfucks from breaking tesla while tanks are midair
+ feugen->AddAura(SPELL_ROOT_SELF, feugen);
+ stalagg->AddAura(SPELL_ROOT_SELF, stalagg);
+
// and make both attack their respective new tanks
if (feugen->GetAI())
feugen->GetAI()->AttackStart(stalaggTank);
diff --git a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
index c8a4eb7fbc8..02b82d255cd 100644
--- a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
@@ -20,7 +20,7 @@
#include "InstanceScript.h"
#include "naxxramas.h"
-BossBoundaryData const boundaries =
+BossBoundaryData const boundaries =
{
/* Arachnid Quarter */
{ BOSS_ANUBREKHAN, new CircleBoundary(Position(3273.376709f, -3475.876709f), Position(3195.668213f, -3475.930176f)) },
@@ -100,36 +100,6 @@ ObjectData const objectData[] =
{ 0, 0, }
};
-// from P2 teleport spell stored target
-float const HeiganPos[2] = { 2793.86f, -3707.38f };
-float const HeiganEruptionSlope[3] =
-{
- (-3703.303223f - HeiganPos[1]) / (2777.494141f - HeiganPos[0]), // between right center and far right
- (-3696.948242f - HeiganPos[1]) / (2785.624268f - HeiganPos[0]), // between left and right halves
- (-3691.880615f - HeiganPos[1]) / (2790.280029f - HeiganPos[0]) // between far left and left center
-};
-
-// 0 H x
-// 1 ^
-// 2 |
-// 3 y<--o
-inline uint32 GetEruptionSection(float x, float y)
-{
- y -= HeiganPos[1];
- if (y < 1.0f)
- return 0;
-
- x -= HeiganPos[0];
- if (x > -1.0f)
- return 3;
-
- float slope = y/x;
- for (uint32 i = 0; i < 3; ++i)
- if (slope > HeiganEruptionSlope[i])
- return i;
- return 3;
-}
-
class instance_naxxramas : public InstanceMapScript
{
public:
@@ -149,6 +119,7 @@ class instance_naxxramas : public InstanceMapScript
hadAnubRekhanGreet = false;
hadFaerlinaGreet = false;
hadThaddiusGreet = false;
+ hadSapphironBirth = false;
CurrentWingTaunt = SAY_KELTHUZAD_FIRST_WING_TAUNT;
playerDied = 0;
@@ -208,28 +179,8 @@ class instance_naxxramas : public InstanceMapScript
}
}
- void ProcessEvent(WorldObject* /*source*/, uint32 eventId) override
- {
- switch (eventId)
- {
- case EVENT_THADDIUS_BEGIN_RESET:
- if (GetBossState(BOSS_THADDIUS) == SPECIAL) // this is the initial spawn, we want a shorter spawn time
- events.ScheduleEvent(EVENT_THADDIUS_RESET, 5 * IN_MILLISECONDS);
- else
- events.ScheduleEvent(EVENT_THADDIUS_RESET, 30 * IN_MILLISECONDS);
- break;
- }
- }
-
void OnGameObjectCreate(GameObject* go) override
{
- if (go->GetGOInfo()->displayId == 6785 || go->GetGOInfo()->displayId == 1287)
- {
- uint32 section = GetEruptionSection(go->GetPositionX(), go->GetPositionY());
- HeiganEruptionGUID[section].insert(go->GetGUID());
- return;
- }
-
switch (go->GetEntry())
{
case GO_GOTHIK_GATE:
@@ -273,37 +224,18 @@ class instance_naxxramas : public InstanceMapScript
if (GetBossState(BOSS_HORSEMEN) == DONE)
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
break;
- default:
- break;
- }
-
- InstanceScript::OnGameObjectCreate(go);
- }
-
- void OnGameObjectRemove(GameObject* go) override
- {
- if (go->GetGOInfo()->displayId == 6785 || go->GetGOInfo()->displayId == 1287)
- {
- uint32 section = GetEruptionSection(go->GetPositionX(), go->GetPositionY());
- HeiganEruptionGUID[section].erase(go->GetGUID());
- return;
- }
-
- switch (go->GetEntry())
- {
case GO_BIRTH:
- if (SapphironGUID)
+ if (hadSapphironBirth || GetBossState(BOSS_SAPPHIRON) == DONE)
{
- if (Creature* sapphiron = instance->GetCreature(SapphironGUID))
- sapphiron->AI()->DoAction(DATA_SAPPHIRON_BIRTH);
- return;
+ hadSapphironBirth = true;
+ go->Delete();
}
break;
default:
break;
}
- InstanceScript::OnGameObjectRemove(go);
+ InstanceScript::OnGameObjectCreate(go);
}
void OnUnitDeath(Unit* unit) override
@@ -328,9 +260,6 @@ class instance_naxxramas : public InstanceMapScript
{
switch (id)
{
- case DATA_HEIGAN_ERUPT:
- HeiganErupt(value);
- break;
case DATA_GOTHIK_GATE:
if (GameObject* gate = instance->GetGameObject(GothikGateGUID))
gate->SetGoState(GOState(value));
@@ -347,6 +276,9 @@ class instance_naxxramas : public InstanceMapScript
case DATA_HAD_THADDIUS_GREET:
hadThaddiusGreet = (value == 1u);
break;
+ case DATA_HAD_SAPPHIRON_BIRTH:
+ hadSapphironBirth = (value == 1u);
+ break;
default:
break;
}
@@ -364,6 +296,8 @@ class instance_naxxramas : public InstanceMapScript
return hadFaerlinaGreet ? 1u : 0u;
case DATA_HAD_THADDIUS_GREET:
return hadThaddiusGreet ? 1u : 0u;
+ case DATA_HAD_SAPPHIRON_BIRTH:
+ return hadSapphironBirth ? 1u : 0u;
default:
break;
}
@@ -399,6 +333,8 @@ class instance_naxxramas : public InstanceMapScript
return StalaggGUID;
case DATA_THADDIUS:
return ThaddiusGUID;
+ case DATA_SAPPHIRON:
+ return SapphironGUID;
case DATA_KELTHUZAD:
return KelthuzadGUID;
case DATA_KELTHUZAD_PORTAL01:
@@ -431,7 +367,7 @@ class instance_naxxramas : public InstanceMapScript
if (GameObject* teleporter = GetGameObject(DATA_NAXX_PORTAL_ARACHNID))
teleporter->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
- events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, 6000);
+ events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, Seconds(6));
}
break;
case BOSS_LOATHEB:
@@ -440,7 +376,7 @@ class instance_naxxramas : public InstanceMapScript
if (GameObject* teleporter = GetGameObject(DATA_NAXX_PORTAL_PLAGUE))
teleporter->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
- events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, 6000);
+ events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, Seconds(6));
}
break;
case BOSS_THADDIUS:
@@ -449,12 +385,12 @@ class instance_naxxramas : public InstanceMapScript
if (GameObject* teleporter = GetGameObject(DATA_NAXX_PORTAL_CONSTRUCT))
teleporter->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
- events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, 6000);
+ events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, Seconds(6));
}
break;
case BOSS_GOTHIK:
if (state == DONE)
- events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_KORTHAZZ, 10000);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_KORTHAZZ, Seconds(10));
break;
case BOSS_HORSEMEN:
if (state == DONE)
@@ -468,12 +404,12 @@ class instance_naxxramas : public InstanceMapScript
if (GameObject* teleporter = GetGameObject(DATA_NAXX_PORTAL_MILITARY))
teleporter->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
- events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, 6000);
+ events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, Seconds(6));
}
break;
case BOSS_SAPPHIRON:
if (state == DONE)
- events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD, 6000);
+ events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD, Seconds(6));
break;
default:
break;
@@ -493,37 +429,37 @@ class instance_naxxramas : public InstanceMapScript
case EVENT_DIALOGUE_GOTHIK_KORTHAZZ:
if (Creature* korthazz = instance->GetCreature(ThaneGUID))
korthazz->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN);
- events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_ZELIEK, 5000);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_ZELIEK, Seconds(5));
break;
case EVENT_DIALOGUE_GOTHIK_ZELIEK:
if (Creature* zeliek = instance->GetCreature(SirGUID))
zeliek->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN);
- events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_BLAUMEUX, 6000);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_BLAUMEUX, Seconds(6));
break;
case EVENT_DIALOGUE_GOTHIK_BLAUMEUX:
if (Creature* blaumeux = instance->GetCreature(LadyGUID))
blaumeux->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN);
- events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_RIVENDARE, 6000);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_RIVENDARE, Seconds(6));
break;
case EVENT_DIALOGUE_GOTHIK_RIVENDARE:
if (Creature* rivendare = instance->GetCreature(BaronGUID))
rivendare->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN);
- events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_BLAUMEUX2, 6000);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_BLAUMEUX2, Seconds(6));
break;
case EVENT_DIALOGUE_GOTHIK_BLAUMEUX2:
if (Creature* blaumeux = instance->GetCreature(LadyGUID))
blaumeux->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN2);
- events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_ZELIEK2, 6000);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_ZELIEK2, Seconds(6));
break;
case EVENT_DIALOGUE_GOTHIK_ZELIEK2:
if (Creature* zeliek = instance->GetCreature(SirGUID))
zeliek->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN2);
- events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_KORTHAZZ2, 6000);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_KORTHAZZ2, Seconds(6));
break;
case EVENT_DIALOGUE_GOTHIK_KORTHAZZ2:
if (Creature* korthazz = instance->GetCreature(ThaneGUID))
korthazz->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN2);
- events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_RIVENDARE2, 6000);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_RIVENDARE2, Seconds(6));
break;
case EVENT_DIALOGUE_GOTHIK_RIVENDARE2:
if (Creature* rivendare = instance->GetCreature(BaronGUID))
@@ -540,62 +476,39 @@ class instance_naxxramas : public InstanceMapScript
if (Creature* kelthuzad = instance->GetCreature(KelthuzadGUID))
kelthuzad->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_KELTHUZAD);
HandleGameObject(KelthuzadDoorGUID, false);
- events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_LICHKING, 6000);
+ events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_LICHKING, Seconds(6));
break;
case EVENT_DIALOGUE_SAPPHIRON_LICHKING:
if (Creature* lichKing = instance->GetCreature(LichKingGUID))
lichKing->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_LICH_KING);
- events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD2, 16000);
+ events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD2, Seconds(16));
break;
case EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD2:
if (Creature* kelthuzad = instance->GetCreature(KelthuzadGUID))
kelthuzad->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_KELTHUZAD2);
- events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_LICHKING2, 9000);
+ events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_LICHKING2, Seconds(9));
break;
case EVENT_DIALOGUE_SAPPHIRON_LICHKING2:
if (Creature* lichKing = instance->GetCreature(LichKingGUID))
lichKing->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_LICH_KING2);
- events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD3, 12000);
+ events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD3, Seconds(12));
break;
case EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD3:
if (Creature* kelthuzad = instance->GetCreature(KelthuzadGUID))
kelthuzad->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_KELTHUZAD3);
- events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD4, 6000);
+ events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD4, Seconds(6));
break;
case EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD4:
if (Creature* kelthuzad = instance->GetCreature(KelthuzadGUID))
kelthuzad->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_KELTHUZAD4);
HandleGameObject(KelthuzadDoorGUID, true);
break;
- case EVENT_THADDIUS_RESET:
- if (GetBossState(BOSS_THADDIUS) != DONE)
- if (Creature* thaddius = instance->GetCreature(ThaddiusGUID))
- thaddius->AI()->DoAction(-1);
- break;
default:
break;
}
}
}
- void HeiganErupt(uint32 section)
- {
- for (uint32 i = 0; i < 4; ++i)
- {
- if (i == section)
- continue;
-
- for (ObjectGuid guid : HeiganEruptionGUID[i])
- {
- if (GameObject* heiganEruption = instance->GetGameObject(guid))
- {
- heiganEruption->SendCustomAnim(heiganEruption->GetGoAnimProgress());
- heiganEruption->CastSpell(NULL, SPELL_ERUPTION);
- }
- }
- }
- }
-
// This Function is called in CheckAchievementCriteriaMeet and CheckAchievementCriteriaMeet is called before SetBossState(bossId, DONE),
// so to check if all bosses are done the checker must exclude 1 boss, the last done, if there is at most 1 encouter in progress when is
// called this function then all bosses are done. The one boss that check is the boss that calls this function, so it is dead.
@@ -653,7 +566,6 @@ class instance_naxxramas : public InstanceMapScript
/* The Plague Quarter */
// Heigan the Unclean
- GuidSet HeiganEruptionGUID[4];
ObjectGuid HeiganGUID;
/* The Military Quarter */
@@ -688,6 +600,7 @@ class instance_naxxramas : public InstanceMapScript
bool hadAnubRekhanGreet;
bool hadFaerlinaGreet;
bool hadThaddiusGreet;
+ bool hadSapphironBirth;
uint8 CurrentWingTaunt;
/* The Immortal / The Undying */
diff --git a/src/server/scripts/Northrend/Naxxramas/naxxramas.h b/src/server/scripts/Northrend/Naxxramas/naxxramas.h
index c0caa86e93f..bece5a60bee 100644
--- a/src/server/scripts/Northrend/Naxxramas/naxxramas.h
+++ b/src/server/scripts/Northrend/Naxxramas/naxxramas.h
@@ -43,12 +43,11 @@ enum Encounter
enum Data
{
- DATA_HEIGAN_ERUPT,
DATA_GOTHIK_GATE,
- DATA_SAPPHIRON_BIRTH,
DATA_HAD_ANUBREKHAN_GREET,
DATA_HAD_FAERLINA_GREET,
DATA_HAD_THADDIUS_GREET,
+ DATA_HAD_SAPPHIRON_BIRTH,
DATA_HORSEMEN_CHECK_ACHIEVEMENT_CREDIT,
DATA_ABOMINATION_KILLED,
@@ -73,6 +72,7 @@ enum Data64
DATA_HEIGAN,
DATA_FEUGEN,
DATA_STALAGG,
+ DATA_SAPPHIRON,
DATA_KELTHUZAD,
DATA_KELTHUZAD_PORTAL01,
DATA_KELTHUZAD_PORTAL02,
@@ -158,12 +158,6 @@ enum GameObjectsIds
GO_NAXX_PORTAL_MILITARY = 181578
};
-enum SpellIds
-{
- SPELL_ERUPTION = 29371,
- SPELL_SLIME = 28801
-};
-
enum InstanceEvents
{
// Dialogue that happens after Gothik's death.
@@ -176,10 +170,6 @@ enum InstanceEvents
EVENT_DIALOGUE_GOTHIK_KORTHAZZ2,
EVENT_DIALOGUE_GOTHIK_RIVENDARE2,
- // Thaddius AI requesting timed encounter (re-)spawn
- EVENT_THADDIUS_BEGIN_RESET,
- EVENT_THADDIUS_RESET,
-
// Dialogue that happens after each wing.
EVENT_KELTHUZAD_WING_TAUNT,
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp
index 89868fc7bf2..b2a1bb70077 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp
@@ -1164,6 +1164,7 @@ class spell_algalon_trigger_3_adds : public SpellScriptLoader
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_algalon_trigger_3_adds_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
+ OnEffectHitTarget += SpellEffectFn(spell_algalon_trigger_3_adds_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
index 6dfc3bf01e7..98827fb3e00 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
@@ -334,7 +334,8 @@ class boss_flame_leviathan : public CreatureScript
void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
{
if (spell->Id == SPELL_START_THE_ENGINE)
- ASSERT_NOTNULL(me->GetVehicleKit())->InstallAllAccessories(false);
+ if (Vehicle* vehicleKit = me->GetVehicleKit())
+ vehicleKit->InstallAllAccessories(false);
if (spell->Id == SPELL_ELECTROSHOCK)
me->InterruptSpell(CURRENT_CHANNELED_SPELL);
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp
index e694433c614..309d5d4c62f 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp
@@ -2759,7 +2759,7 @@ class achievement_setup_boom : public AchievementCriteriaScript
public:
achievement_setup_boom() : AchievementCriteriaScript("achievement_setup_boom") { }
- bool OnCheck(Player* /*source*/, Unit* target)
+ bool OnCheck(Player* /*source*/, Unit* target) override
{
return target && target->GetAI()->GetData(DATA_SETUP_BOMB);
}
@@ -2770,7 +2770,7 @@ class achievement_setup_mine : public AchievementCriteriaScript
public:
achievement_setup_mine() : AchievementCriteriaScript("achievement_setup_mine") { }
- bool OnCheck(Player* /*source*/, Unit* target)
+ bool OnCheck(Player* /*source*/, Unit* target) override
{
return target && target->GetAI()->GetData(DATA_SETUP_MINE);
}
@@ -2781,7 +2781,7 @@ class achievement_setup_rocket : public AchievementCriteriaScript
public:
achievement_setup_rocket() : AchievementCriteriaScript("achievement_setup_rocket") { }
- bool OnCheck(Player* /*source*/, Unit* target)
+ bool OnCheck(Player* /*source*/, Unit* target) override
{
return target && target->GetAI()->GetData(DATA_SETUP_ROCKET);
}
@@ -2792,7 +2792,7 @@ class achievement_firefighter : public AchievementCriteriaScript
public:
achievement_firefighter() : AchievementCriteriaScript("achievement_firefighter") { }
- bool OnCheck(Player* /*source*/, Unit* target)
+ bool OnCheck(Player* /*source*/, Unit* target) override
{
return target && target->GetAI()->GetData(DATA_FIREFIGHTER);
}
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp
index 8cb20eadc9f..f3aeec85af2 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp
@@ -637,7 +637,7 @@ class BoomEvent : public BasicEvent
{
}
- bool Execute(uint64 /*time*/, uint32 /*diff*/)
+ bool Execute(uint64 /*time*/, uint32 /*diff*/) override
{
// This hack is here because we suspect our implementation of spell effect execution on targets
// is done in the wrong order. We suspect that EFFECT_0 needs to be applied on all targets,
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp
index 7da67171b5c..675268b4e93 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp
@@ -230,6 +230,9 @@ enum Spells
// Descend Into Madness
SPELL_TELEPORT_PORTAL_VISUAL = 64416,
+ SPELL_TELEPORT_TO_STORMWIND_ILLUSION = 63989,
+ SPELL_TELEPORT_TO_CHAMBER_ILLUSION = 63997,
+ SPELL_TELEPORT_TO_ICECROWN_ILLUSION = 63998,
// Illusions
SPELL_GRIM_REPRISAL = 63305,
@@ -395,6 +398,14 @@ enum MiscData
{
ACHIEV_TIMED_START_EVENT = 21001,
SOUND_LUNATIC_GAZE = 15757,
+ MAX_ILLUSION_ROOMS = 3
+};
+
+uint32 const IllusionSpells[MAX_ILLUSION_ROOMS]
+{
+ SPELL_TELEPORT_TO_CHAMBER_ILLUSION,
+ SPELL_TELEPORT_TO_ICECROWN_ILLUSION,
+ SPELL_TELEPORT_TO_STORMWIND_ILLUSION
};
class StartAttackEvent : public BasicEvent
@@ -405,7 +416,7 @@ class StartAttackEvent : public BasicEvent
{
}
- bool Execute(uint64 /*time*/, uint32 /*diff*/)
+ bool Execute(uint64 /*time*/, uint32 /*diff*/) override
{
_owner->SetReactState(REACT_AGGRESSIVE);
if (Creature* _summoner = ObjectAccessor::GetCreature(*_owner, _summonerGuid))
@@ -1419,7 +1430,11 @@ class npc_descend_into_madness : public CreatureScript
{
if (!result)
return;
+
clicker->RemoveAurasDueToSpell(SPELL_BRAIN_LINK);
+ uint32 illusion = _instance->GetData(DATA_ILLUSION);
+ if (illusion < MAX_ILLUSION_ROOMS)
+ DoCast(clicker, IllusionSpells[illusion], true);
me->DespawnOrUnsummon();
}
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/instance_utgarde_pinnacle.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/instance_utgarde_pinnacle.cpp
index 8f2d5a61770..547dc681ac6 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/instance_utgarde_pinnacle.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/instance_utgarde_pinnacle.cpp
@@ -19,7 +19,7 @@
#include "InstanceScript.h"
#include "utgarde_pinnacle.h"
-BossBoundaryData const boundaries =
+BossBoundaryData const boundaries =
{
{ DATA_KING_YMIRON, new RectangleBoundary(340.0f, 450.0f, -412.0f, -275.0f) }
};
diff --git a/src/server/scripts/Northrend/isle_of_conquest.cpp b/src/server/scripts/Northrend/isle_of_conquest.cpp
index 68121e940c9..11cc645f0cb 100644
--- a/src/server/scripts/Northrend/isle_of_conquest.cpp
+++ b/src/server/scripts/Northrend/isle_of_conquest.cpp
@@ -210,7 +210,7 @@ class StartLaunchEvent : public BasicEvent
{
}
- bool Execute(uint64 /*time*/, uint32 /*diff*/)
+ bool Execute(uint64 /*time*/, uint32 /*diff*/) override
{
Player* player = sObjectMgr->GetPlayerByLowGUID(_lowGuid);
if (!player || !player->GetVehicle())
diff --git a/src/server/scripts/Northrend/northrend_script_loader.cpp b/src/server/scripts/Northrend/northrend_script_loader.cpp
new file mode 100644
index 00000000000..7d104b85f6d
--- /dev/null
+++ b/src/server/scripts/Northrend/northrend_script_loader.cpp
@@ -0,0 +1,374 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// This is where scripts' loading functions should be declared:
+void AddSC_boss_slad_ran();
+void AddSC_boss_moorabi();
+void AddSC_boss_drakkari_colossus();
+void AddSC_boss_gal_darah();
+void AddSC_boss_eck();
+void AddSC_instance_gundrak();
+
+// Azjol-Nerub - Azjol-Nerub
+void AddSC_boss_krik_thir();
+void AddSC_boss_hadronox();
+void AddSC_boss_anub_arak();
+void AddSC_instance_azjol_nerub();
+
+// Azjol-Nerub - Ahn'kahet
+void AddSC_boss_elder_nadox();
+void AddSC_boss_taldaram();
+void AddSC_boss_amanitar();
+void AddSC_boss_jedoga_shadowseeker();
+void AddSC_boss_volazj();
+void AddSC_instance_ahnkahet();
+
+// Drak'Tharon Keep
+void AddSC_boss_trollgore();
+void AddSC_boss_novos();
+void AddSC_boss_king_dred();
+void AddSC_boss_tharon_ja();
+void AddSC_instance_drak_tharon_keep();
+
+void AddSC_boss_argent_challenge(); //Trial of the Champion
+void AddSC_boss_black_knight();
+void AddSC_boss_grand_champions();
+void AddSC_instance_trial_of_the_champion();
+void AddSC_trial_of_the_champion();
+void AddSC_boss_anubarak_trial(); //Trial of the Crusader
+void AddSC_boss_faction_champions();
+void AddSC_boss_jaraxxus();
+void AddSC_boss_northrend_beasts();
+void AddSC_boss_twin_valkyr();
+void AddSC_trial_of_the_crusader();
+void AddSC_instance_trial_of_the_crusader();
+void AddSC_boss_anubrekhan(); //Naxxramas
+void AddSC_boss_maexxna();
+void AddSC_boss_patchwerk();
+void AddSC_boss_grobbulus();
+void AddSC_boss_razuvious();
+void AddSC_boss_kelthuzad();
+void AddSC_boss_loatheb();
+void AddSC_boss_noth();
+void AddSC_boss_gluth();
+void AddSC_boss_sapphiron();
+void AddSC_boss_four_horsemen();
+void AddSC_boss_faerlina();
+void AddSC_boss_heigan();
+void AddSC_boss_gothik();
+void AddSC_boss_thaddius();
+void AddSC_instance_naxxramas();
+void AddSC_boss_nexus_commanders(); // The Nexus Nexus
+void AddSC_boss_magus_telestra();
+void AddSC_boss_anomalus();
+void AddSC_boss_ormorok();
+void AddSC_boss_keristrasza();
+void AddSC_instance_nexus();
+void AddSC_boss_drakos(); //The Nexus The Oculus
+void AddSC_boss_urom();
+void AddSC_boss_varos();
+void AddSC_boss_eregos();
+void AddSC_instance_oculus();
+void AddSC_oculus();
+void AddSC_boss_malygos(); // The Nexus: Eye of Eternity
+void AddSC_instance_eye_of_eternity();
+void AddSC_boss_sartharion(); //Obsidian Sanctum
+void AddSC_obsidian_sanctum();
+void AddSC_instance_obsidian_sanctum();
+void AddSC_boss_bjarngrim(); //Ulduar Halls of Lightning
+void AddSC_boss_loken();
+void AddSC_boss_ionar();
+void AddSC_boss_volkhan();
+void AddSC_instance_halls_of_lightning();
+void AddSC_boss_maiden_of_grief(); //Ulduar Halls of Stone
+void AddSC_boss_krystallus();
+void AddSC_boss_sjonnir();
+void AddSC_instance_halls_of_stone();
+void AddSC_halls_of_stone();
+void AddSC_boss_auriaya(); //Ulduar Ulduar
+void AddSC_boss_flame_leviathan();
+void AddSC_boss_ignis();
+void AddSC_boss_razorscale();
+void AddSC_boss_xt002();
+void AddSC_boss_kologarn();
+void AddSC_boss_assembly_of_iron();
+void AddSC_boss_general_vezax();
+void AddSC_boss_mimiron();
+void AddSC_boss_hodir();
+void AddSC_boss_freya();
+void AddSC_boss_yogg_saron();
+void AddSC_boss_algalon_the_observer();
+void AddSC_instance_ulduar();
+
+// Utgarde Keep - Utgarde Keep
+void AddSC_boss_keleseth();
+void AddSC_boss_skarvald_dalronn();
+void AddSC_boss_ingvar_the_plunderer();
+void AddSC_instance_utgarde_keep();
+void AddSC_utgarde_keep();
+
+// Utgarde Keep - Utgarde Pinnacle
+void AddSC_boss_svala();
+void AddSC_boss_palehoof();
+void AddSC_boss_skadi();
+void AddSC_boss_ymiron();
+void AddSC_instance_utgarde_pinnacle();
+
+// Vault of Archavon
+void AddSC_boss_archavon();
+void AddSC_boss_emalon();
+void AddSC_boss_koralon();
+void AddSC_boss_toravon();
+void AddSC_instance_vault_of_archavon();
+
+void AddSC_boss_cyanigosa(); //Violet Hold
+void AddSC_boss_erekem();
+void AddSC_boss_ichoron();
+void AddSC_boss_lavanthor();
+void AddSC_boss_moragg();
+void AddSC_boss_xevozz();
+void AddSC_boss_zuramat();
+void AddSC_instance_violet_hold();
+void AddSC_violet_hold();
+void AddSC_instance_forge_of_souls(); //Forge of Souls
+void AddSC_forge_of_souls();
+void AddSC_boss_bronjahm();
+void AddSC_boss_devourer_of_souls();
+void AddSC_instance_pit_of_saron(); //Pit of Saron
+void AddSC_pit_of_saron();
+void AddSC_boss_garfrost();
+void AddSC_boss_ick();
+void AddSC_boss_tyrannus();
+void AddSC_instance_halls_of_reflection(); // Halls of Reflection
+void AddSC_halls_of_reflection();
+void AddSC_boss_falric();
+void AddSC_boss_marwyn();
+void AddSC_boss_lord_marrowgar(); // Icecrown Citadel
+void AddSC_boss_lady_deathwhisper();
+void AddSC_boss_icecrown_gunship_battle();
+void AddSC_boss_deathbringer_saurfang();
+void AddSC_boss_festergut();
+void AddSC_boss_rotface();
+void AddSC_boss_professor_putricide();
+void AddSC_boss_blood_prince_council();
+void AddSC_boss_blood_queen_lana_thel();
+void AddSC_boss_valithria_dreamwalker();
+void AddSC_boss_sindragosa();
+void AddSC_boss_the_lich_king();
+void AddSC_icecrown_citadel_teleport();
+void AddSC_instance_icecrown_citadel();
+void AddSC_icecrown_citadel();
+void AddSC_instance_ruby_sanctum(); // Ruby Sanctum
+void AddSC_ruby_sanctum();
+void AddSC_boss_baltharus_the_warborn();
+void AddSC_boss_saviana_ragefire();
+void AddSC_boss_general_zarithrian();
+void AddSC_boss_halion();
+
+void AddSC_dalaran();
+void AddSC_borean_tundra();
+void AddSC_dragonblight();
+void AddSC_grizzly_hills();
+void AddSC_howling_fjord();
+void AddSC_icecrown();
+void AddSC_sholazar_basin();
+void AddSC_storm_peaks();
+void AddSC_wintergrasp();
+void AddSC_zuldrak();
+void AddSC_crystalsong_forest();
+void AddSC_isle_of_conquest();
+
+// The name of this function should match:
+// void Add${NameOfDirectory}Scripts()
+void AddNorthrendScripts()
+{
+ AddSC_boss_slad_ran(); //Gundrak
+ AddSC_boss_moorabi();
+ AddSC_boss_drakkari_colossus();
+ AddSC_boss_gal_darah();
+ AddSC_boss_eck();
+ AddSC_instance_gundrak();
+
+ // Azjol-Nerub - Ahn'kahet
+ AddSC_boss_elder_nadox();
+ AddSC_boss_taldaram();
+ AddSC_boss_amanitar();
+ AddSC_boss_jedoga_shadowseeker();
+ AddSC_boss_volazj();
+ AddSC_instance_ahnkahet();
+
+ // Azjol-Nerub - Azjol-Nerub
+ AddSC_boss_krik_thir();
+ AddSC_boss_hadronox();
+ AddSC_boss_anub_arak();
+ AddSC_instance_azjol_nerub();
+
+ // Drak'Tharon Keep
+ AddSC_boss_trollgore();
+ AddSC_boss_novos();
+ AddSC_boss_king_dred();
+ AddSC_boss_tharon_ja();
+ AddSC_instance_drak_tharon_keep();
+
+ AddSC_boss_argent_challenge(); //Trial of the Champion
+ AddSC_boss_black_knight();
+ AddSC_boss_grand_champions();
+ AddSC_instance_trial_of_the_champion();
+ AddSC_trial_of_the_champion();
+ AddSC_boss_anubarak_trial(); //Trial of the Crusader
+ AddSC_boss_faction_champions();
+ AddSC_boss_jaraxxus();
+ AddSC_trial_of_the_crusader();
+ AddSC_boss_twin_valkyr();
+ AddSC_boss_northrend_beasts();
+ AddSC_instance_trial_of_the_crusader();
+ AddSC_boss_anubrekhan(); //Naxxramas
+ AddSC_boss_maexxna();
+ AddSC_boss_patchwerk();
+ AddSC_boss_grobbulus();
+ AddSC_boss_razuvious();
+ AddSC_boss_kelthuzad();
+ AddSC_boss_loatheb();
+ AddSC_boss_noth();
+ AddSC_boss_gluth();
+ AddSC_boss_sapphiron();
+ AddSC_boss_four_horsemen();
+ AddSC_boss_faerlina();
+ AddSC_boss_heigan();
+ AddSC_boss_gothik();
+ AddSC_boss_thaddius();
+ AddSC_instance_naxxramas();
+ AddSC_boss_nexus_commanders(); // The Nexus Nexus
+ AddSC_boss_magus_telestra();
+ AddSC_boss_anomalus();
+ AddSC_boss_ormorok();
+ AddSC_boss_keristrasza();
+ AddSC_instance_nexus();
+ AddSC_boss_drakos(); //The Nexus The Oculus
+ AddSC_boss_urom();
+ AddSC_boss_varos();
+ AddSC_boss_eregos();
+ AddSC_instance_oculus();
+ AddSC_oculus();
+ AddSC_boss_malygos(); // The Nexus: Eye of Eternity
+ AddSC_instance_eye_of_eternity();
+ AddSC_boss_sartharion(); //Obsidian Sanctum
+ AddSC_obsidian_sanctum();
+ AddSC_instance_obsidian_sanctum();
+ AddSC_boss_bjarngrim(); //Ulduar Halls of Lightning
+ AddSC_boss_loken();
+ AddSC_boss_ionar();
+ AddSC_boss_volkhan();
+ AddSC_instance_halls_of_lightning();
+ AddSC_boss_maiden_of_grief(); //Ulduar Halls of Stone
+ AddSC_boss_krystallus();
+ AddSC_boss_sjonnir();
+ AddSC_instance_halls_of_stone();
+ AddSC_halls_of_stone();
+ AddSC_boss_auriaya(); //Ulduar Ulduar
+ AddSC_boss_flame_leviathan();
+ AddSC_boss_ignis();
+ AddSC_boss_razorscale();
+ AddSC_boss_xt002();
+ AddSC_boss_general_vezax();
+ AddSC_boss_assembly_of_iron();
+ AddSC_boss_kologarn();
+ AddSC_boss_mimiron();
+ AddSC_boss_hodir();
+ AddSC_boss_freya();
+ AddSC_boss_yogg_saron();
+ AddSC_boss_algalon_the_observer();
+ AddSC_instance_ulduar();
+
+ // Utgarde Keep - Utgarde Keep
+ AddSC_boss_keleseth();
+ AddSC_boss_skarvald_dalronn();
+ AddSC_boss_ingvar_the_plunderer();
+ AddSC_instance_utgarde_keep();
+ AddSC_utgarde_keep();
+
+ // Utgarde Keep - Utgarde Pinnacle
+ AddSC_boss_svala();
+ AddSC_boss_palehoof();
+ AddSC_boss_skadi();
+ AddSC_boss_ymiron();
+ AddSC_instance_utgarde_pinnacle();
+
+ // Vault of Archavon
+ AddSC_boss_archavon();
+ AddSC_boss_emalon();
+ AddSC_boss_koralon();
+ AddSC_boss_toravon();
+ AddSC_instance_vault_of_archavon();
+
+ AddSC_boss_cyanigosa(); //Violet Hold
+ AddSC_boss_erekem();
+ AddSC_boss_ichoron();
+ AddSC_boss_lavanthor();
+ AddSC_boss_moragg();
+ AddSC_boss_xevozz();
+ AddSC_boss_zuramat();
+ AddSC_instance_violet_hold();
+ AddSC_violet_hold();
+ AddSC_instance_forge_of_souls(); //Forge of Souls
+ AddSC_forge_of_souls();
+ AddSC_boss_bronjahm();
+ AddSC_boss_devourer_of_souls();
+ AddSC_instance_pit_of_saron(); //Pit of Saron
+ AddSC_pit_of_saron();
+ AddSC_boss_garfrost();
+ AddSC_boss_ick();
+ AddSC_boss_tyrannus();
+ AddSC_instance_halls_of_reflection(); // Halls of Reflection
+ AddSC_halls_of_reflection();
+ AddSC_boss_falric();
+ AddSC_boss_marwyn();
+ AddSC_boss_lord_marrowgar(); // Icecrown Citadel
+ AddSC_boss_lady_deathwhisper();
+ AddSC_boss_icecrown_gunship_battle();
+ AddSC_boss_deathbringer_saurfang();
+ AddSC_boss_festergut();
+ AddSC_boss_rotface();
+ AddSC_boss_professor_putricide();
+ AddSC_boss_blood_prince_council();
+ AddSC_boss_blood_queen_lana_thel();
+ AddSC_boss_valithria_dreamwalker();
+ AddSC_boss_sindragosa();
+ AddSC_boss_the_lich_king();
+ AddSC_icecrown_citadel_teleport();
+ AddSC_instance_icecrown_citadel();
+ AddSC_icecrown_citadel();
+ AddSC_instance_ruby_sanctum(); // Ruby Sanctum
+ AddSC_ruby_sanctum();
+ AddSC_boss_baltharus_the_warborn();
+ AddSC_boss_saviana_ragefire();
+ AddSC_boss_general_zarithrian();
+ AddSC_boss_halion();
+
+ AddSC_dalaran();
+ AddSC_borean_tundra();
+ AddSC_dragonblight();
+ AddSC_grizzly_hills();
+ AddSC_howling_fjord();
+ AddSC_icecrown();
+ AddSC_sholazar_basin();
+ AddSC_storm_peaks();
+ AddSC_wintergrasp();
+ AddSC_zuldrak();
+ AddSC_crystalsong_forest();
+ AddSC_isle_of_conquest();
+}
diff --git a/src/server/scripts/Northrend/zone_dragonblight.cpp b/src/server/scripts/Northrend/zone_dragonblight.cpp
index 2ec2af80624..d7ff1e5cb4d 100644
--- a/src/server/scripts/Northrend/zone_dragonblight.cpp
+++ b/src/server/scripts/Northrend/zone_dragonblight.cpp
@@ -360,7 +360,7 @@ class npc_commander_eligor_dawnbringer : public CreatureScript
uint8 talkWing;
};
- CreatureAI* GetAI(Creature* creature) const
+ CreatureAI* GetAI(Creature* creature) const override
{
return new npc_commander_eligor_dawnbringerAI(creature);
}
@@ -695,7 +695,7 @@ class npc_torturer_lecraft : public CreatureScript
ObjectGuid _playerGUID;
};
- CreatureAI* GetAI(Creature* creature) const
+ CreatureAI* GetAI(Creature* creature) const override
{
return new npc_torturer_lecraftAI(creature);
}
diff --git a/src/server/scripts/OutdoorPvP/CMakeLists.txt b/src/server/scripts/OutdoorPvP/CMakeLists.txt
deleted file mode 100644
index 91ce4ce4186..00000000000
--- a/src/server/scripts/OutdoorPvP/CMakeLists.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
-#
-# This file is free software; as a special exception the author gives
-# unlimited permission to copy and/or distribute it, with or without
-# modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-set(scripts_STAT_SRCS
- ${scripts_STAT_SRCS}
- OutdoorPvP/OutdoorPvPTF.cpp
- OutdoorPvP/OutdoorPvPSI.cpp
- OutdoorPvP/OutdoorPvPSI.h
- OutdoorPvP/OutdoorPvPZM.cpp
- OutdoorPvP/OutdoorPvPNA.cpp
- OutdoorPvP/OutdoorPvPHP.cpp
- OutdoorPvP/OutdoorPvPTF.h
- OutdoorPvP/OutdoorPvPEP.h
- OutdoorPvP/OutdoorPvPEP.cpp
- OutdoorPvP/OutdoorPvPHP.h
- OutdoorPvP/OutdoorPvPZM.h
- OutdoorPvP/OutdoorPvPNA.h
-)
-
-message(" -> Prepared: Outdoor PVP Zones")
diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPHP.h b/src/server/scripts/OutdoorPvP/OutdoorPvPHP.h
index 71dbd139ea0..4fd608ccd1c 100644
--- a/src/server/scripts/OutdoorPvP/OutdoorPvPHP.h
+++ b/src/server/scripts/OutdoorPvP/OutdoorPvPHP.h
@@ -96,9 +96,9 @@ class OPvPCapturePointHP : public OPvPCapturePoint
public:
OPvPCapturePointHP(OutdoorPvP* pvp, OutdoorPvPHPTowerType type);
- void ChangeState();
+ void ChangeState() override;
- void FillInitialWorldStates(WorldPacket & data);
+ void FillInitialWorldStates(WorldPacket & data) override;
private:
OutdoorPvPHPTowerType m_TowerType;
@@ -109,18 +109,18 @@ class OutdoorPvPHP : public OutdoorPvP
public:
OutdoorPvPHP();
- bool SetupOutdoorPvP();
+ bool SetupOutdoorPvP() override;
- void HandlePlayerEnterZone(Player* player, uint32 zone);
- void HandlePlayerLeaveZone(Player* player, uint32 zone);
+ void HandlePlayerEnterZone(Player* player, uint32 zone) override;
+ void HandlePlayerLeaveZone(Player* player, uint32 zone) override;
- bool Update(uint32 diff);
+ bool Update(uint32 diff) override;
- void FillInitialWorldStates(WorldPacket &data);
+ void FillInitialWorldStates(WorldPacket &data) override;
- void SendRemoveWorldStates(Player* player);
+ void SendRemoveWorldStates(Player* player) override;
- void HandleKillImpl(Player* player, Unit* killed);
+ void HandleKillImpl(Player* player, Unit* killed) override;
uint32 GetAllianceTowersControlled() const;
void SetAllianceTowersControlled(uint32 count);
diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPNA.h b/src/server/scripts/OutdoorPvP/OutdoorPvPNA.h
index 4ed47c42206..80878828d44 100644
--- a/src/server/scripts/OutdoorPvP/OutdoorPvPNA.h
+++ b/src/server/scripts/OutdoorPvP/OutdoorPvPNA.h
@@ -311,18 +311,18 @@ class OutdoorPvPNA : public OutdoorPvP
public:
OutdoorPvPNA();
- bool SetupOutdoorPvP();
+ bool SetupOutdoorPvP() override;
- void HandlePlayerEnterZone(Player* player, uint32 zone);
- void HandlePlayerLeaveZone(Player* player, uint32 zone);
+ void HandlePlayerEnterZone(Player* player, uint32 zone) override;
+ void HandlePlayerLeaveZone(Player* player, uint32 zone) override;
- bool Update(uint32 diff);
+ bool Update(uint32 diff) override;
- void FillInitialWorldStates(WorldPacket &data);
+ void FillInitialWorldStates(WorldPacket &data) override;
- void SendRemoveWorldStates(Player* player);
+ void SendRemoveWorldStates(Player* player) override;
- void HandleKillImpl(Player* player, Unit* killed);
+ void HandleKillImpl(Player* player, Unit* killed) override;
private:
OPvPCapturePointNA * m_obj;
diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPSI.h b/src/server/scripts/OutdoorPvP/OutdoorPvPSI.h
index f28fea926fc..fae2ea9738e 100644
--- a/src/server/scripts/OutdoorPvP/OutdoorPvPSI.h
+++ b/src/server/scripts/OutdoorPvP/OutdoorPvPSI.h
@@ -56,22 +56,22 @@ class OutdoorPvPSI : public OutdoorPvP
public:
OutdoorPvPSI();
- bool SetupOutdoorPvP();
+ bool SetupOutdoorPvP() override;
- void HandlePlayerEnterZone(Player* player, uint32 zone);
- void HandlePlayerLeaveZone(Player* player, uint32 zone);
+ void HandlePlayerEnterZone(Player* player, uint32 zone) override;
+ void HandlePlayerLeaveZone(Player* player, uint32 zone) override;
- bool Update(uint32 diff);
+ bool Update(uint32 diff) override;
- void FillInitialWorldStates(WorldPacket &data);
+ void FillInitialWorldStates(WorldPacket &data) override;
- void SendRemoveWorldStates(Player* player);
+ void SendRemoveWorldStates(Player* player) override;
- bool HandleAreaTrigger(Player* player, uint32 trigger);
+ bool HandleAreaTrigger(Player* player, uint32 trigger) override;
- bool HandleDropFlag(Player* player, uint32 spellId);
+ bool HandleDropFlag(Player* player, uint32 spellId) override;
- bool HandleCustomSpell(Player* player, uint32 spellId, GameObject* go);
+ bool HandleCustomSpell(Player* player, uint32 spellId, GameObject* go) override;
void UpdateWorldState();
diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPScriptLoader.cpp b/src/server/scripts/OutdoorPvP/OutdoorPvPScriptLoader.cpp
new file mode 100644
index 00000000000..ebf29910046
--- /dev/null
+++ b/src/server/scripts/OutdoorPvP/OutdoorPvPScriptLoader.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// This is where scripts' loading functions should be declared:
+void AddSC_outdoorpvp_ep();
+void AddSC_outdoorpvp_hp();
+void AddSC_outdoorpvp_na();
+void AddSC_outdoorpvp_si();
+void AddSC_outdoorpvp_tf();
+void AddSC_outdoorpvp_zm();
+
+// The name of this function should match:
+// void Add${NameOfDirectory}Scripts()
+void AddOutdoorPvPScripts()
+{
+ AddSC_outdoorpvp_ep();
+ AddSC_outdoorpvp_hp();
+ AddSC_outdoorpvp_na();
+ AddSC_outdoorpvp_si();
+ AddSC_outdoorpvp_tf();
+ AddSC_outdoorpvp_zm();
+}
diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPTF.h b/src/server/scripts/OutdoorPvP/OutdoorPvPTF.h
index 237fee3283b..ebbccfd63cb 100644
--- a/src/server/scripts/OutdoorPvP/OutdoorPvPTF.h
+++ b/src/server/scripts/OutdoorPvP/OutdoorPvPTF.h
@@ -132,11 +132,11 @@ class OPvPCapturePointTF : public OPvPCapturePoint
public:
OPvPCapturePointTF(OutdoorPvP* pvp, OutdoorPvPTF_TowerType type);
- bool Update(uint32 diff);
+ bool Update(uint32 diff) override;
- void ChangeState();
+ void ChangeState() override;
- void FillInitialWorldStates(WorldPacket & data);
+ void FillInitialWorldStates(WorldPacket & data) override;
void UpdateTowerState();
@@ -151,16 +151,16 @@ class OutdoorPvPTF : public OutdoorPvP
public:
OutdoorPvPTF();
- bool SetupOutdoorPvP();
+ bool SetupOutdoorPvP() override;
- void HandlePlayerEnterZone(Player* player, uint32 zone);
- void HandlePlayerLeaveZone(Player* player, uint32 zone);
+ void HandlePlayerEnterZone(Player* player, uint32 zone) override;
+ void HandlePlayerLeaveZone(Player* player, uint32 zone) override;
- bool Update(uint32 diff);
+ bool Update(uint32 diff) override;
- void FillInitialWorldStates(WorldPacket &data);
+ void FillInitialWorldStates(WorldPacket &data) override;
- void SendRemoveWorldStates(Player* player);
+ void SendRemoveWorldStates(Player* player) override;
uint32 GetAllianceTowersControlled() const;
void SetAllianceTowersControlled(uint32 count);
diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPZM.h b/src/server/scripts/OutdoorPvP/OutdoorPvPZM.h
index e71fbf79280..352e6f108ea 100644
--- a/src/server/scripts/OutdoorPvP/OutdoorPvPZM.h
+++ b/src/server/scripts/OutdoorPvP/OutdoorPvPZM.h
@@ -161,9 +161,9 @@ class OPvPCapturePointZM_Beacon : public OPvPCapturePoint
public:
OPvPCapturePointZM_Beacon(OutdoorPvP* pvp, ZM_BeaconType type);
- void ChangeState();
+ void ChangeState() override;
- void FillInitialWorldStates(WorldPacket & data);
+ void FillInitialWorldStates(WorldPacket & data) override;
void UpdateTowerState();
@@ -218,18 +218,18 @@ class OutdoorPvPZM : public OutdoorPvP
public:
OutdoorPvPZM();
- bool SetupOutdoorPvP();
+ bool SetupOutdoorPvP() override;
- void HandlePlayerEnterZone(Player* player, uint32 zone);
- void HandlePlayerLeaveZone(Player* player, uint32 zone);
+ void HandlePlayerEnterZone(Player* player, uint32 zone) override;
+ void HandlePlayerLeaveZone(Player* player, uint32 zone) override;
- bool Update(uint32 diff);
+ bool Update(uint32 diff) override;
- void FillInitialWorldStates(WorldPacket &data);
+ void FillInitialWorldStates(WorldPacket &data) override;
- void SendRemoveWorldStates(Player* player);
+ void SendRemoveWorldStates(Player* player) override;
- void HandleKillImpl(Player* player, Unit* killed);
+ void HandleKillImpl(Player* player, Unit* killed) override;
uint32 GetAllianceTowersControlled() const;
void SetAllianceTowersControlled(uint32 count);
diff --git a/src/server/scripts/Outland/CMakeLists.txt b/src/server/scripts/Outland/CMakeLists.txt
deleted file mode 100644
index 55b0452fb0b..00000000000
--- a/src/server/scripts/Outland/CMakeLists.txt
+++ /dev/null
@@ -1,128 +0,0 @@
-# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
-#
-# This file is free software; as a special exception the author gives
-# unlimited permission to copy and/or distribute it, with or without
-# modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-set(scripts_STAT_SRCS
- ${scripts_STAT_SRCS}
- Outland/zone_nagrand.cpp
- Outland/HellfireCitadel/MagtheridonsLair/magtheridons_lair.h
- Outland/HellfireCitadel/MagtheridonsLair/instance_magtheridons_lair.cpp
- Outland/HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp
- Outland/HellfireCitadel/HellfireRamparts/instance_hellfire_ramparts.cpp
- Outland/HellfireCitadel/HellfireRamparts/boss_omor_the_unscarred.cpp
- Outland/HellfireCitadel/HellfireRamparts/boss_watchkeeper_gargolmar.cpp
- Outland/HellfireCitadel/HellfireRamparts/boss_vazruden_the_herald.cpp
- Outland/HellfireCitadel/HellfireRamparts/hellfire_ramparts.h
- Outland/HellfireCitadel/BloodFurnace/boss_the_maker.cpp
- Outland/HellfireCitadel/BloodFurnace/boss_kelidan_the_breaker.cpp
- Outland/HellfireCitadel/BloodFurnace/blood_furnace.h
- Outland/HellfireCitadel/BloodFurnace/instance_blood_furnace.cpp
- Outland/HellfireCitadel/BloodFurnace/boss_broggok.cpp
- Outland/HellfireCitadel/ShatteredHalls/shattered_halls.h
- Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp
- Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp
- Outland/HellfireCitadel/ShatteredHalls/shattered_halls.cpp
- Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp
- Outland/HellfireCitadel/ShatteredHalls/boss_warbringer_omrogg.cpp
- Outland/CoilfangReservoir/SteamVault/boss_mekgineer_steamrigger.cpp
- Outland/CoilfangReservoir/SteamVault/instance_steam_vault.cpp
- Outland/CoilfangReservoir/SteamVault/boss_hydromancer_thespia.cpp
- Outland/CoilfangReservoir/SteamVault/boss_warlord_kalithresh.cpp
- Outland/CoilfangReservoir/SteamVault/steam_vault.h
- Outland/CoilfangReservoir/SerpentShrine/boss_hydross_the_unstable.cpp
- Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp
- Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp
- Outland/CoilfangReservoir/SerpentShrine/serpent_shrine.h
- Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp
- Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp
- Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp
- Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp
- Outland/CoilfangReservoir/TheSlavePens/instance_the_slave_pens.cpp
- Outland/CoilfangReservoir/TheSlavePens/the_slave_pens.h
- Outland/CoilfangReservoir/TheSlavePens/boss_mennu_the_betrayer.cpp
- Outland/CoilfangReservoir/TheSlavePens/boss_rokmar_the_crackler.cpp
- Outland/CoilfangReservoir/TheSlavePens/boss_quagmirran.cpp
- Outland/CoilfangReservoir/TheUnderbog/instance_the_underbog.cpp
- Outland/CoilfangReservoir/TheUnderbog/boss_hungarfen.cpp
- Outland/CoilfangReservoir/TheUnderbog/boss_the_black_stalker.cpp
- Outland/zone_shattrath_city.cpp
- Outland/TempestKeep/Mechanar/boss_mechano_lord_capacitus.cpp
- Outland/TempestKeep/Mechanar/boss_pathaleon_the_calculator.cpp
- Outland/TempestKeep/Mechanar/boss_nethermancer_sepethrea.cpp
- Outland/TempestKeep/Mechanar/mechanar.h
- Outland/TempestKeep/Mechanar/boss_gatewatcher_gyrokill.cpp
- Outland/TempestKeep/Mechanar/instance_mechanar.cpp
- Outland/TempestKeep/Mechanar/boss_gatewatcher_ironhand.cpp
- Outland/TempestKeep/Eye/the_eye.h
- Outland/TempestKeep/Eye/instance_the_eye.cpp
- Outland/TempestKeep/Eye/boss_void_reaver.cpp
- Outland/TempestKeep/Eye/boss_astromancer.cpp
- Outland/TempestKeep/Eye/boss_alar.cpp
- Outland/TempestKeep/Eye/boss_kaelthas.cpp
- Outland/TempestKeep/Eye/the_eye.cpp
- Outland/TempestKeep/botanica/the_botanica.h
- Outland/TempestKeep/botanica/instance_the_botanica.cpp
- Outland/TempestKeep/botanica/boss_commander_sarannis.cpp
- Outland/TempestKeep/botanica/boss_thorngrin_the_tender.cpp
- Outland/TempestKeep/botanica/boss_high_botanist_freywinn.cpp
- Outland/TempestKeep/botanica/boss_warp_splinter.cpp
- Outland/TempestKeep/botanica/boss_laj.cpp
- Outland/TempestKeep/arcatraz/boss_zereketh_the_unbound.cpp
- Outland/TempestKeep/arcatraz/boss_dalliah_the_doomsayer.cpp
- Outland/TempestKeep/arcatraz/boss_wrath_scryer_soccothrates.cpp
- Outland/TempestKeep/arcatraz/boss_harbinger_skyriss.cpp
- Outland/TempestKeep/arcatraz/instance_arcatraz.cpp
- Outland/TempestKeep/arcatraz/arcatraz.h
- Outland/TempestKeep/arcatraz/arcatraz.cpp
- Outland/Auchindoun/AuchenaiCrypts/boss_shirrak_the_dead_watcher.cpp
- Outland/Auchindoun/AuchenaiCrypts/boss_exarch_maladaar.cpp
- Outland/Auchindoun/AuchenaiCrypts/instance_auchenai_crypts.cpp
- Outland/Auchindoun/AuchenaiCrypts/auchenai_crypts.h
- Outland/Auchindoun/ManaTombs/boss_pandemonius.cpp
- Outland/Auchindoun/ManaTombs/boss_nexusprince_shaffar.cpp
- Outland/Auchindoun/ManaTombs/instance_mana_tombs.cpp
- Outland/Auchindoun/ManaTombs/mana_tombs.h
- Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp
- Outland/Auchindoun/SethekkHalls/boss_talon_king_ikiss.cpp
- Outland/Auchindoun/SethekkHalls/boss_anzu.cpp
- Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp
- Outland/Auchindoun/SethekkHalls/sethekk_halls.h
- Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp
- Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp
- Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp
- Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp
- Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp
- Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.h
- Outland/boss_doomwalker.cpp
- Outland/zone_terokkar_forest.cpp
- Outland/zone_hellfire_peninsula.cpp
- Outland/boss_doomlord_kazzak.cpp
- Outland/BlackTemple/boss_teron_gorefiend.cpp
- Outland/BlackTemple/black_temple.h
- Outland/BlackTemple/illidari_council.cpp
- Outland/BlackTemple/boss_shade_of_akama.cpp
- Outland/BlackTemple/boss_supremus.cpp
- Outland/BlackTemple/black_temple.cpp
- Outland/BlackTemple/boss_mother_shahraz.cpp
- Outland/BlackTemple/instance_black_temple.cpp
- Outland/BlackTemple/boss_reliquary_of_souls.cpp
- Outland/BlackTemple/boss_warlord_najentus.cpp
- Outland/BlackTemple/boss_gurtogg_bloodboil.cpp
- Outland/BlackTemple/boss_illidan.cpp
- Outland/zone_shadowmoon_valley.cpp
- Outland/zone_blades_edge_mountains.cpp
- Outland/GruulsLair/boss_high_king_maulgar.cpp
- Outland/GruulsLair/boss_gruul.cpp
- Outland/GruulsLair/gruuls_lair.h
- Outland/GruulsLair/instance_gruuls_lair.cpp
- Outland/zone_netherstorm.cpp
- Outland/zone_zangarmarsh.cpp
-)
-
-message(" -> Prepared: Outland")
diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp
index 102d567e810..56010c09897 100644
--- a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp
+++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp
@@ -289,6 +289,7 @@ class boss_alar : public CreatureScript
me->SetPosition(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0.0f);
me->StopMoving();
WaitEvent = WE_LAND;
+ return;
}
else
{
diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp
index 46388c3a185..edfa2aedf92 100644
--- a/src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp
+++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -16,13 +15,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Boss_Void_Reaver
-SD%Complete: 90
-SDComment: Should reset if raid are out of room.
-SDCategory: Tempest Keep, The Eye
-EndScriptData */
-
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "the_eye.h"
@@ -43,10 +35,17 @@ enum Spells
SPELL_BERSERK = 27680
};
+enum Events
+{
+ EVENT_POUNDING = 1,
+ EVENT_ARCANE_ORB,
+ EVENT_KNOCK_AWAY,
+ EVENT_BERSERK
+};
+
class boss_void_reaver : public CreatureScript
{
public:
-
boss_void_reaver() : CreatureScript("boss_void_reaver") { }
struct boss_void_reaverAI : public BossAI
@@ -58,21 +57,9 @@ class boss_void_reaver : public CreatureScript
void Initialize()
{
- Pounding_Timer = 15000;
- ArcaneOrb_Timer = 3000;
- KnockAway_Timer = 30000;
- Berserk_Timer = 600000;
-
Enraged = false;
}
- uint32 Pounding_Timer;
- uint32 ArcaneOrb_Timer;
- uint32 KnockAway_Timer;
- uint32 Berserk_Timer;
-
- bool Enraged;
-
void Reset() override
{
Initialize();
@@ -95,71 +82,84 @@ class boss_void_reaver : public CreatureScript
{
Talk(SAY_AGGRO);
_EnterCombat();
+
+ events.ScheduleEvent(EVENT_POUNDING, 15000);
+ events.ScheduleEvent(EVENT_ARCANE_ORB, 3000);
+ events.ScheduleEvent(EVENT_KNOCK_AWAY, 30000);
+ events.ScheduleEvent(EVENT_BERSERK, 600000);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
- // Pounding
- if (Pounding_Timer <= diff)
- {
- DoCastVictim(SPELL_POUNDING);
- Talk(SAY_POUNDING);
- Pounding_Timer = 15000; //cast time(3000) + cooldown time(12000)
- }
- else
- Pounding_Timer -= diff;
- // Arcane Orb
- if (ArcaneOrb_Timer <= diff)
- {
- Unit* target = NULL;
- std::list<HostileReference*> t_list = me->getThreatManager().getThreatList();
- std::vector<Unit*> target_list;
- for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
- {
- target = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid());
- if (!target)
- continue;
- // exclude pets & totems, 18 yard radius minimum
- if (target->GetTypeId() == TYPEID_PLAYER && target->IsAlive() && !target->IsWithinDist(me, 18, false))
- target_list.push_back(target);
- target = NULL;
- }
- if (!target_list.empty())
- target = *(target_list.begin() + rand32() % target_list.size());
- else
- target = me->GetVictim();
+ events.Update(diff);
- if (target)
- me->CastSpell(target, SPELL_ARCANE_ORB, false, NULL, NULL);
- ArcaneOrb_Timer = 3000;
- }
- else
- ArcaneOrb_Timer -= diff;
- // Single Target knock back, reduces aggro
- if (KnockAway_Timer <= diff)
- {
- DoCastVictim(SPELL_KNOCK_AWAY);
- //Drop 25% aggro
- if (DoGetThreat(me->GetVictim()))
- DoModifyThreatPercent(me->GetVictim(), -25);
- KnockAway_Timer = 30000;
- }
- else
- KnockAway_Timer -= diff;
- //Berserk
- if (Berserk_Timer < diff && !Enraged)
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
{
- DoCast(me, SPELL_BERSERK);
- Enraged = true;
+ switch (eventId)
+ {
+ case EVENT_POUNDING:
+ DoCastVictim(SPELL_POUNDING);
+ Talk(SAY_POUNDING);
+ events.ScheduleEvent(EVENT_POUNDING, 15000);
+ break;
+ case EVENT_ARCANE_ORB:
+ {
+ Unit* target = NULL;
+ std::list<HostileReference*> t_list = me->getThreatManager().getThreatList();
+ std::vector<Unit*> target_list;
+ for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr != t_list.end(); ++itr)
+ {
+ target = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid());
+ if (!target)
+ continue;
+ // exclude pets & totems, 18 yard radius minimum
+ if (target->GetTypeId() == TYPEID_PLAYER && target->IsAlive() && !target->IsWithinDist(me, 18, false))
+ target_list.push_back(target);
+ target = NULL;
+ }
+
+ if (!target_list.empty())
+ target = *(target_list.begin() + rand32() % target_list.size());
+ else
+ target = me->GetVictim();
+
+ if (target)
+ me->CastSpell(target, SPELL_ARCANE_ORB, false, NULL, NULL);
+
+ events.ScheduleEvent(EVENT_ARCANE_ORB, 3000);
+ break;
+ }
+ case EVENT_KNOCK_AWAY:
+ DoCastVictim(SPELL_KNOCK_AWAY);
+ // Drop 25% aggro
+ if (DoGetThreat(me->GetVictim()))
+ DoModifyThreatPercent(me->GetVictim(), -25);
+
+ events.ScheduleEvent(EVENT_KNOCK_AWAY, 30000);
+ break;
+ case EVENT_BERSERK:
+ if (!Enraged)
+ {
+ DoCast(me, SPELL_BERSERK);
+ Enraged = true;
+ }
+ break;
+ default:
+ break;
+ }
}
- else
- Berserk_Timer -= diff;
DoMeleeAttackIfReady();
}
+
+ private:
+ bool Enraged;
};
CreatureAI* GetAI(Creature* creature) const override
diff --git a/src/server/scripts/Outland/outland_script_loader.cpp b/src/server/scripts/Outland/outland_script_loader.cpp
new file mode 100644
index 00000000000..91ba4e5689f
--- /dev/null
+++ b/src/server/scripts/Outland/outland_script_loader.cpp
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// This is where scripts' loading functions should be declared:
+// Auchindoun - Auchenai Crypts
+void AddSC_boss_shirrak_the_dead_watcher();
+void AddSC_boss_exarch_maladaar();
+void AddSC_instance_auchenai_crypts();
+
+// Auchindoun - Mana Tombs
+void AddSC_boss_pandemonius();
+void AddSC_boss_nexusprince_shaffar();
+void AddSC_instance_mana_tombs();
+
+// Auchindoun - Sekketh Halls
+void AddSC_boss_darkweaver_syth();
+void AddSC_boss_talon_king_ikiss();
+void AddSC_boss_anzu();
+void AddSC_instance_sethekk_halls();
+
+// Auchindoun - Shadow Labyrinth
+void AddSC_boss_ambassador_hellmaw();
+void AddSC_boss_blackheart_the_inciter();
+void AddSC_boss_grandmaster_vorpil();
+void AddSC_boss_murmur();
+void AddSC_instance_shadow_labyrinth();
+
+// Black Temple
+void AddSC_black_temple();
+void AddSC_boss_illidan();
+void AddSC_boss_shade_of_akama();
+void AddSC_boss_supremus();
+void AddSC_boss_gurtogg_bloodboil();
+void AddSC_boss_mother_shahraz();
+void AddSC_boss_reliquary_of_souls();
+void AddSC_boss_teron_gorefiend();
+void AddSC_boss_najentus();
+void AddSC_boss_illidari_council();
+void AddSC_instance_black_temple();
+
+// Coilfang Reservoir - Serpent Shrine Cavern
+void AddSC_boss_fathomlord_karathress();
+void AddSC_boss_hydross_the_unstable();
+void AddSC_boss_lady_vashj();
+void AddSC_boss_leotheras_the_blind();
+void AddSC_boss_morogrim_tidewalker();
+void AddSC_instance_serpentshrine_cavern();
+void AddSC_boss_the_lurker_below();
+
+// Coilfang Reservoir - The Steam Vault
+void AddSC_boss_hydromancer_thespia();
+void AddSC_boss_mekgineer_steamrigger();
+void AddSC_boss_warlord_kalithresh();
+void AddSC_instance_steam_vault();
+
+// Coilfang Reservoir - The Slave Pens
+void AddSC_instance_the_slave_pens();
+void AddSC_boss_mennu_the_betrayer();
+void AddSC_boss_rokmar_the_crackler();
+void AddSC_boss_quagmirran();
+
+// Coilfang Reservoir - The Underbog
+void AddSC_instance_the_underbog();
+void AddSC_boss_hungarfen();
+void AddSC_boss_the_black_stalker();
+
+// Gruul's Lair
+void AddSC_boss_gruul();
+void AddSC_boss_high_king_maulgar();
+void AddSC_instance_gruuls_lair();
+void AddSC_boss_broggok(); //HC Blood Furnace
+void AddSC_boss_kelidan_the_breaker();
+void AddSC_boss_the_maker();
+void AddSC_instance_blood_furnace();
+void AddSC_boss_magtheridon(); //HC Magtheridon's Lair
+void AddSC_instance_magtheridons_lair();
+void AddSC_boss_grand_warlock_nethekurse(); //HC Shattered Halls
+void AddSC_boss_warbringer_omrogg();
+void AddSC_boss_warchief_kargath_bladefist();
+void AddSC_shattered_halls();
+void AddSC_instance_shattered_halls();
+void AddSC_boss_watchkeeper_gargolmar(); //HC Ramparts
+void AddSC_boss_omor_the_unscarred();
+void AddSC_boss_vazruden_the_herald();
+void AddSC_instance_ramparts();
+void AddSC_arcatraz(); //TK Arcatraz
+void AddSC_boss_zereketh_the_unbound();
+void AddSC_boss_dalliah_the_doomsayer();
+void AddSC_boss_wrath_scryer_soccothrates();
+void AddSC_boss_harbinger_skyriss();
+void AddSC_instance_arcatraz();
+void AddSC_boss_high_botanist_freywinn(); //TK Botanica
+void AddSC_boss_laj();
+void AddSC_boss_warp_splinter();
+void AddSC_boss_thorngrin_the_tender();
+void AddSC_boss_commander_sarannis();
+void AddSC_instance_the_botanica();
+void AddSC_boss_alar(); //TK The Eye
+void AddSC_boss_kaelthas();
+void AddSC_boss_void_reaver();
+void AddSC_boss_high_astromancer_solarian();
+void AddSC_instance_the_eye();
+void AddSC_the_eye();
+void AddSC_boss_gatewatcher_iron_hand(); //TK The Mechanar
+void AddSC_boss_gatewatcher_gyrokill();
+void AddSC_boss_nethermancer_sepethrea();
+void AddSC_boss_pathaleon_the_calculator();
+void AddSC_boss_mechano_lord_capacitus();
+void AddSC_instance_mechanar();
+
+void AddSC_blades_edge_mountains();
+void AddSC_boss_doomlordkazzak();
+void AddSC_boss_doomwalker();
+void AddSC_hellfire_peninsula();
+void AddSC_nagrand();
+void AddSC_netherstorm();
+void AddSC_shadowmoon_valley();
+void AddSC_shattrath_city();
+void AddSC_terokkar_forest();
+void AddSC_zangarmarsh();
+
+// The name of this function should match:
+// void Add${NameOfDirectory}Scripts()
+void AddOutlandScripts()
+{
+ // Auchindoun - Auchenai Crypts
+ AddSC_boss_shirrak_the_dead_watcher();
+ AddSC_boss_exarch_maladaar();
+ AddSC_instance_auchenai_crypts();
+
+ // Auchindoun - Mana Tombs
+ AddSC_boss_pandemonius();
+ AddSC_boss_nexusprince_shaffar();
+ AddSC_instance_mana_tombs();
+
+ // Auchindoun - Sekketh Halls
+ AddSC_boss_darkweaver_syth();
+ AddSC_boss_talon_king_ikiss();
+ AddSC_boss_anzu();
+ AddSC_instance_sethekk_halls();
+
+ // Auchindoun - Shadow Labyrinth
+ AddSC_boss_ambassador_hellmaw();
+ AddSC_boss_blackheart_the_inciter();
+ AddSC_boss_grandmaster_vorpil();
+ AddSC_boss_murmur();
+ AddSC_instance_shadow_labyrinth();
+
+ // Black Temple
+ AddSC_black_temple();
+ AddSC_boss_illidan();
+ AddSC_boss_shade_of_akama();
+ AddSC_boss_supremus();
+ AddSC_boss_gurtogg_bloodboil();
+ AddSC_boss_mother_shahraz();
+ AddSC_boss_reliquary_of_souls();
+ AddSC_boss_teron_gorefiend();
+ AddSC_boss_najentus();
+ AddSC_boss_illidari_council();
+ AddSC_instance_black_temple();
+
+ // Coilfang Reservoir - Serpent Shrine Cavern
+ AddSC_boss_fathomlord_karathress();
+ AddSC_boss_hydross_the_unstable();
+ AddSC_boss_lady_vashj();
+ AddSC_boss_leotheras_the_blind();
+ AddSC_boss_morogrim_tidewalker();
+ AddSC_instance_serpentshrine_cavern();
+ AddSC_boss_the_lurker_below();
+
+ // Coilfang Reservoir - The Steam Vault
+ AddSC_instance_steam_vault();
+ AddSC_boss_hydromancer_thespia();
+ AddSC_boss_mekgineer_steamrigger();
+ AddSC_boss_warlord_kalithresh();
+
+ // Coilfang Reservoir - The Slave Pens
+ AddSC_instance_the_slave_pens();
+ AddSC_boss_mennu_the_betrayer();
+ AddSC_boss_rokmar_the_crackler();
+ AddSC_boss_quagmirran();
+
+ // Coilfang Reservoir - The Underbog
+ AddSC_instance_the_underbog();
+ AddSC_boss_hungarfen();
+ AddSC_boss_the_black_stalker();
+
+ // Gruul's Lair
+ AddSC_boss_gruul();
+ AddSC_boss_high_king_maulgar();
+ AddSC_instance_gruuls_lair();
+ AddSC_boss_broggok(); //HC Blood Furnace
+ AddSC_boss_kelidan_the_breaker();
+ AddSC_boss_the_maker();
+ AddSC_instance_blood_furnace();
+ AddSC_boss_magtheridon(); //HC Magtheridon's Lair
+ AddSC_instance_magtheridons_lair();
+ AddSC_boss_grand_warlock_nethekurse(); //HC Shattered Halls
+ AddSC_boss_warbringer_omrogg();
+ AddSC_boss_warchief_kargath_bladefist();
+ AddSC_shattered_halls();
+ AddSC_instance_shattered_halls();
+ AddSC_boss_watchkeeper_gargolmar(); //HC Ramparts
+ AddSC_boss_omor_the_unscarred();
+ AddSC_boss_vazruden_the_herald();
+ AddSC_instance_ramparts();
+ AddSC_arcatraz(); //TK Arcatraz
+ AddSC_boss_zereketh_the_unbound();
+ AddSC_boss_dalliah_the_doomsayer();
+ AddSC_boss_wrath_scryer_soccothrates();
+ AddSC_boss_harbinger_skyriss();
+ AddSC_instance_arcatraz();
+ AddSC_boss_high_botanist_freywinn(); //TK Botanica
+ AddSC_boss_laj();
+ AddSC_boss_warp_splinter();
+ AddSC_boss_thorngrin_the_tender();
+ AddSC_boss_commander_sarannis();
+ AddSC_instance_the_botanica();
+ AddSC_boss_alar(); //TK The Eye
+ AddSC_boss_kaelthas();
+ AddSC_boss_void_reaver();
+ AddSC_boss_high_astromancer_solarian();
+ AddSC_instance_the_eye();
+ AddSC_the_eye();
+ AddSC_boss_gatewatcher_iron_hand(); //TK The Mechanar
+ AddSC_boss_gatewatcher_gyrokill();
+ AddSC_boss_nethermancer_sepethrea();
+ AddSC_boss_pathaleon_the_calculator();
+ AddSC_boss_mechano_lord_capacitus();
+ AddSC_instance_mechanar();
+
+ AddSC_blades_edge_mountains();
+ AddSC_boss_doomlordkazzak();
+ AddSC_boss_doomwalker();
+ AddSC_hellfire_peninsula();
+ AddSC_nagrand();
+ AddSC_netherstorm();
+ AddSC_shadowmoon_valley();
+ AddSC_shattrath_city();
+ AddSC_terokkar_forest();
+ AddSC_zangarmarsh();
+}
diff --git a/src/server/scripts/Outland/zone_terokkar_forest.cpp b/src/server/scripts/Outland/zone_terokkar_forest.cpp
index 06a8af947b7..4b757544d65 100644
--- a/src/server/scripts/Outland/zone_terokkar_forest.cpp
+++ b/src/server/scripts/Outland/zone_terokkar_forest.cpp
@@ -27,7 +27,6 @@ EndScriptData */
npc_unkor_the_ruthless
npc_infested_root_walker
npc_rotting_forest_rager
-npc_netherweb_victim
npc_floon
npc_isla_starmane
npc_slim
@@ -47,13 +46,13 @@ EndContentData */
enum UnkorTheRuthless
{
- SAY_SUBMIT = 0,
-
- FACTION_HOSTILE = 45,
- FACTION_FRIENDLY = 35,
- QUEST_DONTKILLTHEFATONE = 9889,
-
- SPELL_PULVERIZE = 2676
+ SAY_SUBMIT = 0,
+ REQUIRED_KILL_COUNT = 10,
+ FACTION_FRIENDLY = 35,
+ FACTION_HOSTILE = 45,
+ SPELL_PULVERIZE = 2676,
+ QUEST_DONTKILLTHEFATONE = 9889,
+ NPC_BOULDERFIST_INVADER = 18260
};
class npc_unkor_the_ruthless : public CreatureScript
@@ -117,7 +116,7 @@ public:
Player* groupie = itr->GetSource();
if (groupie &&
groupie->GetQuestStatus(QUEST_DONTKILLTHEFATONE) == QUEST_STATUS_INCOMPLETE &&
- groupie->GetReqKillOrCastCurrentCount(QUEST_DONTKILLTHEFATONE, 18260) == 10)
+ groupie->GetReqKillOrCastCurrentCount(QUEST_DONTKILLTHEFATONE, NPC_BOULDERFIST_INVADER) == REQUIRED_KILL_COUNT)
{
groupie->AreaExploredOrEventHappens(QUEST_DONTKILLTHEFATONE);
if (!CanDoQuest)
@@ -126,7 +125,7 @@ public:
}
}
else if (player->GetQuestStatus(QUEST_DONTKILLTHEFATONE) == QUEST_STATUS_INCOMPLETE &&
- player->GetReqKillOrCastCurrentCount(QUEST_DONTKILLTHEFATONE, 18260) == 10)
+ player->GetReqKillOrCastCurrentCount(QUEST_DONTKILLTHEFATONE, NPC_BOULDERFIST_INVADER) == REQUIRED_KILL_COUNT)
{
player->AreaExploredOrEventHappens(QUEST_DONTKILLTHEFATONE);
CanDoQuest = true;
@@ -171,6 +170,11 @@ public:
## npc_infested_root_walker
######*/
+enum InfestedRootWalker
+{
+ SPELL_SUMMON_WOOD_MITES = 39130
+};
+
class npc_infested_root_walker : public CreatureScript
{
public:
@@ -194,7 +198,7 @@ public:
if (me->GetHealth() <= damage)
if (rand32() % 100 < 75)
//Summon Wood Mites
- DoCast(me, 39130, true);
+ DoCast(me, SPELL_SUMMON_WOOD_MITES, true);
}
};
};
@@ -202,6 +206,12 @@ public:
/*######
## npc_skywing
######*/
+
+enum Skywing
+{
+ QUEST_SKYWING = 10898
+};
+
class npc_skywing : public CreatureScript
{
public:
@@ -226,7 +236,7 @@ public:
switch (waypointId)
{
case 8:
- player->AreaExploredOrEventHappens(10898);
+ player->AreaExploredOrEventHappens(QUEST_SKYWING);
break;
}
}
@@ -240,7 +250,7 @@ public:
return;
Player* player = who->ToPlayer();
- if (player && player->GetQuestStatus(10898) == QUEST_STATUS_INCOMPLETE)
+ if (player && player->GetQuestStatus(QUEST_SKYWING) == QUEST_STATUS_INCOMPLETE)
if (me->IsWithinDistInMap(who, 10.0f))
Start(false, false, who->GetGUID());
}
@@ -258,6 +268,11 @@ public:
## npc_rotting_forest_rager
######*/
+enum RottingForestRager
+{
+ SPELL_SUMMON_LOTS_OF_WOOD_MITES = 39134
+};
+
class npc_rotting_forest_rager : public CreatureScript
{
public:
@@ -280,67 +295,8 @@ public:
if (done_by->GetTypeId() == TYPEID_PLAYER)
if (me->GetHealth() <= damage)
if (rand32() % 100 < 75)
- //Summon Lots of Wood Mights
- DoCast(me, 39134, true);
- }
- };
-};
-
-/*######
-## npc_netherweb_victim
-######*/
-
-enum NetherwebVictim
-{
- QUEST_TARGET = 22459
- //SPELL_FREE_WEBBED = 38950
-};
-
-const uint32 netherwebVictims[6] =
-{
- 18470, 16805, 21242, 18452, 22482, 21285
-};
-
-class npc_netherweb_victim : public CreatureScript
-{
-public:
- npc_netherweb_victim() : CreatureScript("npc_netherweb_victim") { }
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new npc_netherweb_victimAI(creature);
- }
-
- struct npc_netherweb_victimAI : public ScriptedAI
- {
- npc_netherweb_victimAI(Creature* creature) : ScriptedAI(creature) { }
-
- void Reset() override { }
- void EnterCombat(Unit* /*who*/) override { }
- void MoveInLineOfSight(Unit* /*who*/) override { }
-
-
- void JustDied(Unit* killer) override
- {
- Player* player = killer->ToPlayer();
- if (!player)
- return;
-
- if (player->GetQuestStatus(10873) == QUEST_STATUS_INCOMPLETE)
- {
- if (rand32() % 100 < 25)
- {
- me->SummonCreature(QUEST_TARGET, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000);
- player->KilledMonsterCredit(QUEST_TARGET);
- }
- else
- me->SummonCreature(netherwebVictims[rand32() % 6], 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000);
-
- if (rand32() % 100 < 75)
- me->SummonCreature(netherwebVictims[rand32() % 6], 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000);
-
- me->SummonCreature(netherwebVictims[rand32() % 6], 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000);
- }
+ //Summon Lots of Wood Mites
+ DoCast(me, SPELL_SUMMON_LOTS_OF_WOOD_MITES, true);
}
};
};
@@ -349,19 +305,22 @@ public:
## npc_floon
######*/
-#define GOSSIP_FLOON1 "You owe Sim'salabim money. Hand them over or die!"
-#define GOSSIP_FLOON2 "Hand over the money or die...again!"
-
enum Floon
{
- SAY_FLOON_ATTACK = 0,
-
- SPELL_SILENCE = 6726,
- SPELL_FROSTBOLT = 9672,
- SPELL_FROST_NOVA = 11831,
-
- FACTION_HOSTILE_FL = 1738,
- QUEST_CRACK_SKULLS = 10009
+ SAY_FLOON_ATTACK = 0,
+ OPTION_ID_PAY_UP_OR_DIE = 0,
+ OPTION_ID_COLLECT_A_DEBT = 0,
+ FACTION_HOSTILE_FLOON = 1738,
+ MENU_ID_PAY_UP_OR_DIE = 7731,
+ MENU_ID_COLLECT_A_DEBT = 7732,
+ GOSSIP_FLOON_STRANGE_SOUNDS = 9442,
+ GOSSIP_HE_ALREADY_KILLED_ME = 9443,
+
+ SPELL_SILENCE = 6726,
+ SPELL_FROSTBOLT = 9672,
+ SPELL_FROST_NOVA = 11831,
+
+ QUEST_CRACKIN_SOME_SKULLS = 10009
};
class npc_floon : public CreatureScript
@@ -374,13 +333,13 @@ public:
player->PlayerTalkClass->ClearMenus();
if (action == GOSSIP_ACTION_INFO_DEF)
{
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_FLOON2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
- player->SEND_GOSSIP_MENU(9443, creature->GetGUID());
+ player->ADD_GOSSIP_ITEM_DB(MENU_ID_PAY_UP_OR_DIE, OPTION_ID_PAY_UP_OR_DIE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ player->SEND_GOSSIP_MENU(GOSSIP_HE_ALREADY_KILLED_ME, creature->GetGUID());
}
if (action == GOSSIP_ACTION_INFO_DEF+1)
{
player->CLOSE_GOSSIP_MENU();
- creature->setFaction(FACTION_HOSTILE_FL);
+ creature->setFaction(FACTION_HOSTILE_FLOON);
creature->AI()->Talk(SAY_FLOON_ATTACK, player);
creature->AI()->AttackStart(player);
}
@@ -389,10 +348,10 @@ public:
bool OnGossipHello(Player* player, Creature* creature) override
{
- if (player->GetQuestStatus(QUEST_CRACK_SKULLS) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_FLOON1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
+ if (player->GetQuestStatus(QUEST_CRACKIN_SOME_SKULLS) == QUEST_STATUS_INCOMPLETE)
+ player->ADD_GOSSIP_ITEM_DB(MENU_ID_COLLECT_A_DEBT, OPTION_ID_COLLECT_A_DEBT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
- player->SEND_GOSSIP_MENU(9442, creature->GetGUID());
+ player->SEND_GOSSIP_MENU(GOSSIP_FLOON_STRANGE_SOUNDS, creature->GetGUID());
return true;
}
@@ -463,15 +422,16 @@ public:
######*/
enum IslaStarmaneData
{
- SAY_PROGRESS_1 = 0,
- SAY_PROGRESS_2 = 1,
- SAY_PROGRESS_3 = 2,
- SAY_PROGRESS_4 = 3,
-
- QUEST_EFTW_H = 10052,
- QUEST_EFTW_A = 10051,
- GO_CAGE = 182794,
- SPELL_CAT = 32447,
+ SAY_PROGRESS_1 = 0,
+ SAY_PROGRESS_2 = 1,
+ SAY_PROGRESS_3 = 2,
+ SAY_PROGRESS_4 = 3,
+ GO_DISTANCE = 10,
+ FACTION_ESCORTEE = 113,
+ ESCAPE_FROM_FIREWING_POINT_A = 10051,
+ ESCAPE_FROM_FIREWING_POINT_H = 10052,
+ SPELL_TRAVEL_FORM_CAT = 32447,
+ GO_CAGE = 182794
};
class npc_isla_starmane : public CreatureScript
@@ -492,7 +452,7 @@ public:
switch (waypointId)
{
case 0:
- if (GameObject* Cage = me->FindNearestGameObject(GO_CAGE, 10))
+ if (GameObject* Cage = me->FindNearestGameObject(GO_CAGE, GO_DISTANCE))
Cage->SetGoState(GO_STATE_ACTIVE);
break;
case 2:
@@ -507,16 +467,16 @@ public:
case 29:
Talk(SAY_PROGRESS_4, player);
if (player->GetTeam() == ALLIANCE)
- player->GroupEventHappens(QUEST_EFTW_A, me);
+ player->GroupEventHappens(ESCAPE_FROM_FIREWING_POINT_A, me);
else if (player->GetTeam() == HORDE)
- player->GroupEventHappens(QUEST_EFTW_H, me);
+ player->GroupEventHappens(ESCAPE_FROM_FIREWING_POINT_H, me);
me->SetInFront(player);
break;
case 30:
me->HandleEmoteCommand(EMOTE_ONESHOT_WAVE);
break;
case 31:
- DoCast(me, SPELL_CAT);
+ DoCast(me, SPELL_TRAVEL_FORM_CAT);
me->SetWalk(false);
break;
}
@@ -532,19 +492,19 @@ public:
if (Player* player = GetPlayerForEscort())
{
if (player->GetTeam() == ALLIANCE)
- player->FailQuest(QUEST_EFTW_A);
+ player->FailQuest(ESCAPE_FROM_FIREWING_POINT_A);
else if (player->GetTeam() == HORDE)
- player->FailQuest(QUEST_EFTW_H);
+ player->FailQuest(ESCAPE_FROM_FIREWING_POINT_H);
}
}
};
bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) override
{
- if (quest->GetQuestId() == QUEST_EFTW_H || quest->GetQuestId() == QUEST_EFTW_A)
+ if (quest->GetQuestId() == ESCAPE_FROM_FIREWING_POINT_H || quest->GetQuestId() == ESCAPE_FROM_FIREWING_POINT_A)
{
ENSURE_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID());
- creature->setFaction(113);
+ creature->setFaction(FACTION_ESCORTEE);
}
return true;
}
@@ -558,10 +518,20 @@ public:
/*######
## go_skull_pile
######*/
-#define GOSSIP_S_DARKSCREECHER_AKKARAI "Summon Darkscreecher Akkarai"
-#define GOSSIP_S_KARROG "Summon Karrog"
-#define GOSSIP_S_GEZZARAK_THE_HUNTRESS "Summon Gezzarak the Huntress"
-#define GOSSIP_S_VAKKIZ_THE_WINDRAGER "Summon Vakkiz the Windrager"
+
+enum SkullPile
+{
+ OPTION_ID_GEZZARAK_THE_HUNTRESS = 0,
+ OPTION_ID_DARKSCREECHER_AKKARAI = 1,
+ OPTION_ID_KARROG = 2,
+ OPTION_ID_VAKKIZ_THE_WINDRAGER = 3,
+ GOSSIP_MENU_ID_SKULL_PILE = 8660,
+ ADVERSARIAL_BLOOD = 11885,
+ SUMMON_GEZZARAK_THE_HUNTRESS = 40632,
+ SUMMON_KARROG = 40640,
+ SUMMON_DARKSCREECHER_AKKARAI = 40642,
+ SUMMON_VAKKIZ_THE_WINDRAGER = 40644
+};
class go_skull_pile : public GameObjectScript
{
@@ -580,12 +550,12 @@ public:
bool OnGossipHello(Player* player, GameObject* go) override
{
- if ((player->GetQuestStatus(11885) == QUEST_STATUS_INCOMPLETE) || player->GetQuestRewardStatus(11885))
+ if ((player->GetQuestStatus(ADVERSARIAL_BLOOD) == QUEST_STATUS_INCOMPLETE) || player->GetQuestRewardStatus(ADVERSARIAL_BLOOD))
{
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_S_DARKSCREECHER_AKKARAI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_S_KARROG, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_S_GEZZARAK_THE_HUNTRESS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_S_VAKKIZ_THE_WINDRAGER, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
+ player->ADD_GOSSIP_ITEM_DB(GOSSIP_MENU_ID_SKULL_PILE, OPTION_ID_GEZZARAK_THE_HUNTRESS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
+ player->ADD_GOSSIP_ITEM_DB(GOSSIP_MENU_ID_SKULL_PILE, OPTION_ID_DARKSCREECHER_AKKARAI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
+ player->ADD_GOSSIP_ITEM_DB(GOSSIP_MENU_ID_SKULL_PILE, OPTION_ID_KARROG, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
+ player->ADD_GOSSIP_ITEM_DB(GOSSIP_MENU_ID_SKULL_PILE, OPTION_ID_VAKKIZ_THE_WINDRAGER, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
}
player->SEND_GOSSIP_MENU(go->GetGOInfo()->questgiver.gossipID, go->GetGUID());
@@ -597,16 +567,16 @@ public:
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1:
- player->CastSpell(player, 40642, false);
+ player->CastSpell(player, SUMMON_GEZZARAK_THE_HUNTRESS, false);
break;
case GOSSIP_ACTION_INFO_DEF + 2:
- player->CastSpell(player, 40640, false);
+ player->CastSpell(player, SUMMON_DARKSCREECHER_AKKARAI, false);
break;
case GOSSIP_ACTION_INFO_DEF + 3:
- player->CastSpell(player, 40632, false);
+ player->CastSpell(player, SUMMON_KARROG, false);
break;
case GOSSIP_ACTION_INFO_DEF + 4:
- player->CastSpell(player, 40644, false);
+ player->CastSpell(player, SUMMON_VAKKIZ_THE_WINDRAGER, false);
break;
}
}
@@ -618,7 +588,9 @@ public:
enum Slim
{
- FACTION_CONSORTIUM = 933
+ FACTION_CONSORTIUM = 933,
+ NPC_TEXT_NEITHER_SLIM_NOR_SHADY = 9895,
+ NPC_TEXT_I_SEE_YOU_ARE_A_FRIEND = 9896
};
class npc_slim : public CreatureScript
@@ -640,10 +612,10 @@ public:
if (creature->IsVendor() && player->GetReputationRank(FACTION_CONSORTIUM) >= REP_FRIENDLY)
{
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
- player->SEND_GOSSIP_MENU(9896, creature->GetGUID());
+ player->SEND_GOSSIP_MENU(NPC_TEXT_I_SEE_YOU_ARE_A_FRIEND, creature->GetGUID());
}
else
- player->SEND_GOSSIP_MENU(9895, creature->GetGUID());
+ player->SEND_GOSSIP_MENU(NPC_TEXT_NEITHER_SLIM_NOR_SHADY, creature->GetGUID());
return true;
}
@@ -719,7 +691,6 @@ void AddSC_terokkar_forest()
new npc_unkor_the_ruthless();
new npc_infested_root_walker();
new npc_rotting_forest_rager();
- new npc_netherweb_victim();
new npc_floon();
new npc_isla_starmane();
new go_skull_pile();
diff --git a/src/server/scripts/Pet/CMakeLists.txt b/src/server/scripts/Pet/CMakeLists.txt
deleted file mode 100644
index 9ca268a9a3f..00000000000
--- a/src/server/scripts/Pet/CMakeLists.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
-#
-# This file is free software; as a special exception the author gives
-# unlimited permission to copy and/or distribute it, with or without
-# modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-set(scripts_STAT_SRCS
- ${scripts_STAT_SRCS}
- Pet/pet_dk.cpp
- Pet/pet_generic.cpp
- Pet/pet_hunter.cpp
- Pet/pet_mage.cpp
- Pet/pet_priest.cpp
- Pet/pet_shaman.cpp
-)
-
-message(" -> Prepared: Pet")
diff --git a/src/server/scripts/Pet/pet_generic.cpp b/src/server/scripts/Pet/pet_generic.cpp
index 35455bc474b..0ec6f08ae58 100644
--- a/src/server/scripts/Pet/pet_generic.cpp
+++ b/src/server/scripts/Pet/pet_generic.cpp
@@ -20,10 +20,181 @@
* Scriptnames of files in this file should be prefixed with "npc_pet_gen_".
*/
+ /* ContentData
+ npc_pet_gen_egbert 100% Egbert run's around
+ npc_pet_gen_pandaren_monk 100% Pandaren Monk drinks and bows with you
+ npc_pet_gen_mojo 100% Mojo follows you when you kiss it
+ EndContentData */
+
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
+#include "PassiveAI.h"
#include "Player.h"
+enum EgbertMisc
+{
+ SPELL_EGBERT = 40669,
+ EVENT_RETURN = 3
+};
+
+class npc_pet_gen_egbert : public CreatureScript
+{
+public:
+ npc_pet_gen_egbert() : CreatureScript("npc_pet_gen_egbert") {}
+
+ struct npc_pet_gen_egbertAI : public NullCreatureAI
+ {
+ npc_pet_gen_egbertAI(Creature* creature) : NullCreatureAI(creature)
+ {
+ if (Unit* owner = me->GetCharmerOrOwner())
+ if (owner->GetMap()->GetEntry()->addon > 1)
+ me->SetCanFly(true);
+ }
+
+ void Reset() override
+ {
+ _events.Reset();
+ if (Unit* owner = me->GetCharmerOrOwner())
+ me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, me->GetFollowAngle());
+ }
+
+ void EnterEvadeMode(EvadeReason why) override
+ {
+ if (!_EnterEvadeMode(why))
+ return;
+
+ Reset();
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ _events.Update(diff);
+
+ if (Unit* owner = me->GetCharmerOrOwner())
+ {
+ if (!me->IsWithinDist(owner, 40.f))
+ {
+ me->RemoveAura(SPELL_EGBERT);
+ me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, me->GetFollowAngle());
+ }
+ }
+
+ if (me->HasAura(SPELL_EGBERT))
+ _events.ScheduleEvent(EVENT_RETURN, urandms(5, 20));
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_RETURN:
+ me->RemoveAura(SPELL_EGBERT);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ private:
+ EventMap _events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_pet_gen_egbertAI(creature);
+ }
+};
+
+enum PandarenMonkMisc
+{
+ SPELL_PANDAREN_MONK = 69800,
+ EVENT_FOCUS = 1,
+ EVENT_EMOTE = 2,
+ EVENT_FOLLOW = 3,
+ EVENT_DRINK = 4
+};
+
+class npc_pet_gen_pandaren_monk : public CreatureScript
+{
+public:
+ npc_pet_gen_pandaren_monk() : CreatureScript("npc_pet_gen_pandaren_monk") {}
+
+ struct npc_pet_gen_pandaren_monkAI : public NullCreatureAI
+ {
+ npc_pet_gen_pandaren_monkAI(Creature* creature) : NullCreatureAI(creature) { }
+
+ void Reset() override
+ {
+ _events.Reset();
+ _events.ScheduleEvent(EVENT_FOCUS, 1000);
+ }
+
+ void EnterEvadeMode(EvadeReason why) override
+ {
+ if (!_EnterEvadeMode(why))
+ return;
+
+ Reset();
+ }
+
+ void ReceiveEmote(Player* /*player*/, uint32 emote) override
+ {
+ me->InterruptSpell(CURRENT_CHANNELED_SPELL);
+ me->StopMoving();
+
+ switch (emote)
+ {
+ case TEXT_EMOTE_BOW:
+ _events.ScheduleEvent(EVENT_FOCUS, 1000);
+ break;
+ case TEXT_EMOTE_DRINK:
+ _events.ScheduleEvent(EVENT_DRINK, 1000);
+ break;
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ _events.Update(diff);
+
+ if (Unit* owner = me->GetCharmerOrOwner())
+ if (!me->IsWithinDist(owner, 30.f))
+ me->InterruptSpell(CURRENT_CHANNELED_SPELL);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_FOCUS:
+ if (Unit* owner = me->GetCharmerOrOwner())
+ me->SetFacingToObject(owner);
+ _events.ScheduleEvent(EVENT_EMOTE, 1000);
+ break;
+ case EVENT_EMOTE:
+ me->HandleEmoteCommand(EMOTE_ONESHOT_BOW);
+ _events.ScheduleEvent(EVENT_FOLLOW, 1000);
+ break;
+ case EVENT_FOLLOW:
+ if (Unit* owner = me->GetCharmerOrOwner())
+ me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
+ break;
+ case EVENT_DRINK:
+ me->CastSpell(me, SPELL_PANDAREN_MONK, false);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ private:
+ EventMap _events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_pet_gen_pandaren_monkAI(creature);
+ }
+};
+
enum Mojo
{
SAY_MOJO = 0,
@@ -89,5 +260,7 @@ class npc_pet_gen_mojo : public CreatureScript
void AddSC_generic_pet_scripts()
{
+ new npc_pet_gen_egbert();
+ new npc_pet_gen_pandaren_monk();
new npc_pet_gen_mojo();
}
diff --git a/src/server/scripts/Pet/pet_script_loader.cpp b/src/server/scripts/Pet/pet_script_loader.cpp
new file mode 100644
index 00000000000..c3c0079fd46
--- /dev/null
+++ b/src/server/scripts/Pet/pet_script_loader.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// This is where scripts' loading functions should be declared:
+void AddSC_deathknight_pet_scripts();
+void AddSC_generic_pet_scripts();
+void AddSC_hunter_pet_scripts();
+void AddSC_mage_pet_scripts();
+void AddSC_priest_pet_scripts();
+void AddSC_shaman_pet_scripts();
+
+// The name of this function should match:
+// void Add${NameOfDirectory}Scripts()
+void AddPetScripts()
+{
+ AddSC_deathknight_pet_scripts();
+ AddSC_generic_pet_scripts();
+ AddSC_hunter_pet_scripts();
+ AddSC_mage_pet_scripts();
+ AddSC_priest_pet_scripts();
+ AddSC_shaman_pet_scripts();
+}
diff --git a/src/server/scripts/ScriptLoader.cpp b/src/server/scripts/ScriptLoader.cpp
new file mode 100644
index 00000000000..57c848d5981
--- /dev/null
+++ b/src/server/scripts/ScriptLoader.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ScriptLoader.h"
+#include "World.h"
+
+void AddSpellsScripts();
+void AddCommandsScripts();
+
+#ifdef SCRIPTS
+void AddWorldScripts();
+void AddEasternKingdomsScripts();
+void AddKalimdorScripts();
+void AddOutlandScripts();
+void AddNorthrendScripts();
+void AddEventsScripts();
+void AddPetScripts();
+void AddOutdoorPvPScripts();
+void AddCustomScripts();
+#endif
+
+void AddScripts()
+{
+ AddSpellsScripts();
+ AddCommandsScripts();
+#ifdef SCRIPTS
+ AddWorldScripts();
+ AddEasternKingdomsScripts();
+ AddKalimdorScripts();
+ AddOutlandScripts();
+ AddNorthrendScripts();
+ AddEventsScripts();
+ AddPetScripts();
+ AddOutdoorPvPScripts();
+ AddCustomScripts();
+#endif
+}
diff --git a/src/server/game/Scripting/ScriptLoader.h b/src/server/scripts/ScriptLoader.h
index 4adb215e130..57b62df22d1 100644
--- a/src/server/game/Scripting/ScriptLoader.h
+++ b/src/server/scripts/ScriptLoader.h
@@ -19,17 +19,5 @@
#define SC_SCRIPTLOADER_H
void AddScripts();
-void AddSpellScripts();
-void AddCommandScripts();
-void AddWorldScripts();
-void AddEasternKingdomsScripts();
-void AddKalimdorScripts();
-void AddOutlandScripts();
-void AddNorthrendScripts();
-void AddEventScripts();
-void AddPetScripts();
-void AddBattlegroundScripts();
-void AddOutdoorPvPScripts();
-void AddCustomScripts();
#endif
diff --git a/src/server/scripts/Spells/CMakeLists.txt b/src/server/scripts/Spells/CMakeLists.txt
deleted file mode 100644
index 7434d98cf49..00000000000
--- a/src/server/scripts/Spells/CMakeLists.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
-#
-# This file is free software; as a special exception the author gives
-# unlimited permission to copy and/or distribute it, with or without
-# modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-set(scripts_STAT_SRCS
- ${scripts_STAT_SRCS}
- Spells/spell_shaman.cpp
- Spells/spell_hunter.cpp
- Spells/spell_rogue.cpp
- Spells/spell_druid.cpp
- Spells/spell_dk.cpp
- Spells/spell_quest.cpp
- Spells/spell_warrior.cpp
- Spells/spell_generic.cpp
- Spells/spell_warlock.cpp
- Spells/spell_priest.cpp
- Spells/spell_mage.cpp
- Spells/spell_paladin.cpp
- Spells/spell_item.cpp
- Spells/spell_holiday.cpp
- Spells/spell_pet.cpp
-)
-
-message(" -> Prepared: Spells")
diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp
index 3cea620559a..d210eda9045 100644
--- a/src/server/scripts/Spells/spell_dk.cpp
+++ b/src/server/scripts/Spells/spell_dk.cpp
@@ -22,7 +22,7 @@
*/
#include "Player.h"
-#include "UnitAI.h"
+#include "PlayerAI.h"
#include "ScriptMgr.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
@@ -65,8 +65,6 @@ enum DeathKnightSpells
SPELL_DK_UNHOLY_PRESENCE_TRIGGERED = 49772,
SPELL_DK_WILL_OF_THE_NECROPOLIS_TALENT_R1 = 49189,
SPELL_DK_WILL_OF_THE_NECROPOLIS_AURA_R1 = 52284,
- SPELL_DK_RAISE_ALLY_INITIAL = 61999,
- SPELL_DK_RAISE_ALLY = 46619,
SPELL_DK_GHOUL_THRASH = 47480
};
@@ -1733,36 +1731,39 @@ public:
{
PrepareSpellScript(spell_dk_raise_ally_initial_SpellScript);
- bool Validate(SpellInfo const* /*spellInfo*/) override
+ bool Validate(SpellInfo const* spellInfo) override
{
- if (!sSpellMgr->GetSpellInfo(SPELL_DK_RAISE_ALLY_INITIAL))
+ if (!sSpellMgr->GetSpellInfo(uint32(spellInfo->Effects[EFFECT_0].CalcValue())))
return false;
return true;
}
+ bool Load() override
+ {
+ return GetCaster()->GetTypeId() == TYPEID_PLAYER;
+ }
+
SpellCastResult CheckCast()
{
- // Raise Ally cannot be casted on alive players
Unit* target = GetExplTargetUnit();
if (!target)
return SPELL_FAILED_NO_VALID_TARGETS;
if (target->IsAlive())
return SPELL_FAILED_TARGET_NOT_DEAD;
- if (Player* playerCaster = GetCaster()->ToPlayer())
- if (playerCaster->InArena())
- return SPELL_FAILED_NOT_IN_ARENA;
if (target->IsGhouled())
return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW;
-
return SPELL_CAST_OK;
}
void HandleDummy(SpellEffIndex /*effIndex*/)
{
- Player* caster = GetCaster()->ToPlayer();
- Player* target = GetHitPlayer();
- if (caster && target)
- caster->SendGhoulResurrectRequest(target);
+ if (Player* target = GetHitPlayer())
+ {
+ if (target->IsResurrectRequested()) // already have one active request
+ return;
+ target->SetResurrectRequestData(GetCaster(), 0, 0, uint32(GetEffectValue()));
+ GetSpell()->SendResurrectRequest(target);
+ }
}
void Register() override
@@ -1785,12 +1786,8 @@ class player_ghoulAI : public PlayerAI
void UpdateAI(uint32 /*diff*/) override
{
- if (Creature* ghoul = ObjectAccessor::GetCreature(*me, _ghoulGUID))
- {
- if (!ghoul->IsAlive())
- me->RemoveAura(SPELL_DK_RAISE_ALLY);
- }
- else
+ Creature* ghoul = ObjectAccessor::GetCreature(*me, _ghoulGUID);
+ if (!ghoul || !ghoul->IsAlive())
me->RemoveAura(SPELL_DK_RAISE_ALLY);
}
@@ -1799,28 +1796,25 @@ class player_ghoulAI : public PlayerAI
};
// 46619 - Raise Ally
+#define DkRaiseAllyScriptName "spell_dk_raise_ally"
class spell_dk_raise_ally : public SpellScriptLoader
{
public:
- spell_dk_raise_ally() : SpellScriptLoader("spell_dk_raise_ally") { }
+ spell_dk_raise_ally() : SpellScriptLoader(DkRaiseAllyScriptName) { }
class spell_dk_raise_ally_SpellScript : public SpellScript
{
PrepareSpellScript(spell_dk_raise_ally_SpellScript);
- bool Validate(SpellInfo const* /*spellInfo*/) override
+ bool Load() override
{
- if (!sSpellMgr->GetSpellInfo(SPELL_DK_RAISE_ALLY))
- return false;
- return true;
+ return GetCaster()->GetTypeId() == TYPEID_PLAYER;
}
void SendText()
{
- Player* caster = GetCaster()->ToPlayer();
- Unit* original = GetOriginalCaster();
- if (caster && original)
- original->Whisper(TEXT_RISE_ALLY, caster, true);
+ if (Unit* original = GetOriginalCaster())
+ original->Whisper(TEXT_RISE_ALLY, GetCaster()->ToPlayer(), true);
}
void HandleSummon(SpellEffIndex effIndex)
@@ -1839,9 +1833,8 @@ public:
SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(829);
uint32 duration = uint32(GetSpellInfo()->GetDuration());
- Position pos = caster->GetPosition();
- TempSummon* summon = originalCaster->GetMap()->SummonCreature(entry, pos, properties, duration, originalCaster, GetSpellInfo()->Id);
+ TempSummon* summon = originalCaster->GetMap()->SummonCreature(entry, *GetHitDest(), properties, duration, originalCaster, GetSpellInfo()->Id);
if (!summon)
return;
@@ -1868,15 +1861,25 @@ public:
// SMSG_POWER_UPDATE is sent
summon->SetMaxPower(POWER_ENERGY, 100);
- if (Player* player = GetCaster()->ToPlayer())
- player->SetGhoulResurrectGhoulGUID(summon->GetGUID());
+ _ghoulGuid = summon->GetGUID();
+ }
+
+ void SetGhoul(SpellEffIndex /*effIndex*/)
+ {
+ if (Aura* aura = GetHitAura())
+ if (spell_dk_raise_ally_AuraScript* script = dynamic_cast<spell_dk_raise_ally_AuraScript*>(aura->GetScriptByName(DkRaiseAllyScriptName)))
+ script->SetGhoulGuid(_ghoulGuid);
}
void Register() override
{
AfterHit += SpellHitFn(spell_dk_raise_ally_SpellScript::SendText);
OnEffectHit += SpellEffectFn(spell_dk_raise_ally_SpellScript::HandleSummon, EFFECT_0, SPELL_EFFECT_SUMMON);
+ OnEffectHitTarget += SpellEffectFn(spell_dk_raise_ally_SpellScript::SetGhoul, EFFECT_1, SPELL_EFFECT_APPLY_AURA);
}
+
+ private:
+ ObjectGuid _ghoulGuid;
};
SpellScript* GetSpellScript() const override
@@ -1895,45 +1898,45 @@ public:
oldAIState = false;
}
+ void SetGhoulGuid(ObjectGuid guid)
+ {
+ ghoulGuid = guid;
+ }
+
private:
- bool Validate(SpellInfo const* /*spellInfo*/) override
+ bool Load() override
{
- if (!sSpellMgr->GetSpellInfo(SPELL_DK_RAISE_ALLY))
- return false;
- return true;
+ return GetUnitOwner()->GetTypeId() == TYPEID_PLAYER;
}
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Player* player = GetTarget()->ToPlayer();
- if (!player || player->GetGhoulResurrectGhoulGUID().IsEmpty())
+ if (ghoulGuid.IsEmpty())
return;
- oldAI = player->GetAI();
+ oldAI = player->AI();
oldAIState = player->IsAIEnabled;
- player->SetAI(new player_ghoulAI(player, player->GetGhoulResurrectGhoulGUID()));
+ player->SetAI(new player_ghoulAI(player, ghoulGuid));
player->IsAIEnabled = true;
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Player* player = GetTarget()->ToPlayer();
- if (!player)
- return;
player->IsAIEnabled = oldAIState;
- UnitAI* thisAI = player->GetAI();
+ PlayerAI* thisAI = player->AI();
player->SetAI(oldAI);
delete thisAI;
// Dismiss ghoul if necessary
- if (Creature* ghoul = ObjectAccessor::GetCreature(*player, player->GetGhoulResurrectGhoulGUID()))
+ if (Creature* ghoul = ObjectAccessor::GetCreature(*player, ghoulGuid))
{
- ghoul->RemoveCharmedBy(nullptr);
+ ghoul->RemoveCharmedBy(player);
ghoul->DespawnOrUnsummon(1000);
}
- player->SetGhoulResurrectGhoulGUID(ObjectGuid::Empty);
player->RemoveAura(SPELL_GHOUL_FRENZY);
}
@@ -1943,7 +1946,8 @@ public:
AfterEffectRemove += AuraEffectRemoveFn(spell_dk_raise_ally_AuraScript::OnRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
- UnitAI* oldAI;
+ ObjectGuid ghoulGuid;
+ PlayerAI* oldAI;
bool oldAIState;
};
@@ -1965,7 +1969,7 @@ public:
bool Validate(SpellInfo const* /*spellInfo*/) override
{
- if (!sSpellMgr->GetSpellInfo(SPELL_DK_GHOUL_THRASH))
+ if (!sSpellMgr->GetSpellInfo(SPELL_GHOUL_FRENZY))
return false;
return true;
}
diff --git a/src/server/scripts/Spells/spell_holiday.cpp b/src/server/scripts/Spells/spell_holiday.cpp
index 7fe1f54a594..a3359fdf6f9 100644
--- a/src/server/scripts/Spells/spell_holiday.cpp
+++ b/src/server/scripts/Spells/spell_holiday.cpp
@@ -29,6 +29,7 @@
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
#include "CellImpl.h"
+#include "Vehicle.h"
// 45102 Romantic Picnic
enum SpellsPicnic
@@ -410,6 +411,84 @@ class spell_pilgrims_bounty_buff_food : public SpellScriptLoader
}
};
+enum FeastOnSpells
+{
+ FEAST_ON_TURKEY = 61784,
+ FEAST_ON_CRANBERRIES = 61785,
+ FEAST_ON_SWEET_POTATOES = 61786,
+ FEAST_ON_PIE = 61787,
+ FEAST_ON_STUFFING = 61788,
+ SPELL_CRANBERRY_HELPINS = 61841,
+ SPELL_TURKEY_HELPINS = 61842,
+ SPELL_STUFFING_HELPINS = 61843,
+ SPELL_SWEET_POTATO_HELPINS = 61844,
+ SPELL_PIE_HELPINS = 61845,
+ SPELL_ON_PLATE_EAT_VISUAL = 61826
+};
+
+class spell_pilgrims_bounty_feast_on : public SpellScriptLoader
+{
+ public:
+ spell_pilgrims_bounty_feast_on() : SpellScriptLoader("spell_pilgrims_bounty_feast_on") { }
+
+ class spell_pilgrims_bounty_feast_on_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_pilgrims_bounty_feast_on_SpellScript);
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ Unit* caster = GetCaster();
+
+ uint32 _spellId = 0;
+ switch (GetSpellInfo()->Id)
+ {
+ case FEAST_ON_TURKEY:
+ _spellId = SPELL_TURKEY_HELPINS;
+ break;
+ case FEAST_ON_CRANBERRIES:
+ _spellId = SPELL_CRANBERRY_HELPINS;
+ break;
+ case FEAST_ON_SWEET_POTATOES:
+ _spellId = SPELL_SWEET_POTATO_HELPINS;
+ break;
+ case FEAST_ON_PIE:
+ _spellId = SPELL_PIE_HELPINS;
+ break;
+ case FEAST_ON_STUFFING:
+ _spellId = SPELL_STUFFING_HELPINS;
+ break;
+ default:
+ return;
+ }
+
+ if (Vehicle* vehicle = caster->GetVehicleKit())
+ if (Unit* target = vehicle->GetPassenger(0))
+ if (Player* player = target->ToPlayer())
+ {
+ player->CastSpell(player, SPELL_ON_PLATE_EAT_VISUAL, true);
+ caster->CastSpell(player, _spellId, true, NULL, NULL, player->GetGUID());
+ }
+
+ if (Aura* aura = caster->GetAura(GetEffectValue()))
+ {
+ if (aura->GetStackAmount() == 1)
+ caster->RemoveAurasDueToSpell(aura->GetSpellInfo()->Effects[EFFECT_0].CalcValue());
+ aura->ModStackAmount(-1);
+ }
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_pilgrims_bounty_feast_on_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_pilgrims_bounty_feast_on_SpellScript();
+ }
+};
+
enum TheTurkinator
{
SPELL_KILL_COUNTER_VISUAL = 62015,
@@ -429,7 +508,7 @@ class spell_pilgrims_bounty_turkey_tracker : public SpellScriptLoader
{
PrepareSpellScript(spell_pilgrims_bounty_turkey_tracker_SpellScript);
- bool Validate(SpellInfo const* /*spell*/)
+ bool Validate(SpellInfo const* /*spell*/) override
{
if (!sSpellMgr->GetSpellInfo(SPELL_KILL_COUNTER_VISUAL) || !sSpellMgr->GetSpellInfo(SPELL_KILL_COUNTER_VISUAL_MAX))
return false;
@@ -472,18 +551,90 @@ class spell_pilgrims_bounty_turkey_tracker : public SpellScriptLoader
}
}
- void Register()
+ void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_pilgrims_bounty_turkey_tracker_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
- SpellScript* GetSpellScript() const
+ SpellScript* GetSpellScript() const override
{
return new spell_pilgrims_bounty_turkey_tracker_SpellScript();
}
};
+enum SpiritOfSharing
+{
+ SPELL_THE_SPIRIT_OF_SHARING = 61849
+};
+
+class spell_pilgrims_bounty_well_fed : public SpellScriptLoader
+{
+ private:
+ uint32 _triggeredSpellId;
+
+ public:
+ spell_pilgrims_bounty_well_fed(const char* name, uint32 triggeredSpellId) : SpellScriptLoader(name), _triggeredSpellId(triggeredSpellId) { }
+
+ class spell_pilgrims_bounty_well_fed_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_pilgrims_bounty_well_fed_SpellScript);
+ private:
+ uint32 _triggeredSpellId;
+
+ public:
+ spell_pilgrims_bounty_well_fed_SpellScript(uint32 triggeredSpellId) : SpellScript(), _triggeredSpellId(triggeredSpellId) { }
+
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(_triggeredSpellId))
+ return false;
+ return true;
+ }
+
+ void HandleScript(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+ Player* target = GetHitPlayer();
+ if (!target)
+ return;
+
+ if (Aura const* aura = target->GetAura(GetSpellInfo()->Id))
+ {
+ if (aura->GetStackAmount() == 5)
+ target->CastSpell(target, _triggeredSpellId, true);
+ }
+
+ Aura const* turkey = target->GetAura(SPELL_TURKEY_HELPINS);
+ Aura const* cranberies = target->GetAura(SPELL_CRANBERRY_HELPINS);
+ Aura const* stuffing = target->GetAura(SPELL_STUFFING_HELPINS);
+ Aura const* sweetPotatoes = target->GetAura(SPELL_SWEET_POTATO_HELPINS);
+ Aura const* pie = target->GetAura(SPELL_PIE_HELPINS);
+
+ if ((turkey && turkey->GetStackAmount() == 5) && (cranberies && cranberies->GetStackAmount() == 5) && (stuffing && stuffing->GetStackAmount() == 5)
+ && (sweetPotatoes && sweetPotatoes->GetStackAmount() == 5) && (pie && pie->GetStackAmount() == 5))
+ {
+ target->CastSpell(target, SPELL_THE_SPIRIT_OF_SHARING, true);
+ target->RemoveAurasDueToSpell(SPELL_TURKEY_HELPINS);
+ target->RemoveAurasDueToSpell(SPELL_CRANBERRY_HELPINS);
+ target->RemoveAurasDueToSpell(SPELL_STUFFING_HELPINS);
+ target->RemoveAurasDueToSpell(SPELL_SWEET_POTATO_HELPINS);
+ target->RemoveAurasDueToSpell(SPELL_PIE_HELPINS);
+ }
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_pilgrims_bounty_well_fed_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_pilgrims_bounty_well_fed_SpellScript(_triggeredSpellId);
+ }
+};
+
enum Mistletoe
{
SPELL_CREATE_MISTLETOE = 26206,
@@ -1047,6 +1198,12 @@ void AddSC_holiday_spell_scripts()
new spell_pilgrims_bounty_buff_food("spell_gen_spice_bread_stuffing", SPELL_WELL_FED_HIT_TRIGGER);
new spell_pilgrims_bounty_buff_food("spell_gen_pumpkin_pie", SPELL_WELL_FED_SPIRIT_TRIGGER);
new spell_pilgrims_bounty_buff_food("spell_gen_candied_sweet_potato", SPELL_WELL_FED_HASTE_TRIGGER);
+ new spell_pilgrims_bounty_feast_on();
+ new spell_pilgrims_bounty_well_fed("spell_pilgrims_bounty_well_fed_turkey", SPELL_WELL_FED_AP_TRIGGER);
+ new spell_pilgrims_bounty_well_fed("spell_pilgrims_bounty_well_fed_cranberry", SPELL_WELL_FED_ZM_TRIGGER);
+ new spell_pilgrims_bounty_well_fed("spell_pilgrims_bounty_well_fed_stuffing", SPELL_WELL_FED_HIT_TRIGGER);
+ new spell_pilgrims_bounty_well_fed("spell_pilgrims_bounty_well_fed_sweet_potatoes", SPELL_WELL_FED_HASTE_TRIGGER);
+ new spell_pilgrims_bounty_well_fed("spell_pilgrims_bounty_well_fed_pie", SPELL_WELL_FED_SPIRIT_TRIGGER);
new spell_pilgrims_bounty_turkey_tracker();
// Winter Veil
new spell_winter_veil_mistletoe();
diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp
index abf4c6c1ad8..4d7cc277ff6 100644
--- a/src/server/scripts/Spells/spell_hunter.cpp
+++ b/src/server/scripts/Spells/spell_hunter.cpp
@@ -40,6 +40,7 @@ enum HunterSpells
SPELL_HUNTER_CHIMERA_SHOT_SERPENT = 53353,
SPELL_HUNTER_CHIMERA_SHOT_VIPER = 53358,
SPELL_HUNTER_CHIMERA_SHOT_SCORPID = 53359,
+ SPELL_HUNTER_GLYPH_OF_ARCANE_SHOT = 61389,
SPELL_HUNTER_GLYPH_OF_ASPECT_OF_THE_VIPER = 56851,
SPELL_HUNTER_IMPROVED_MEND_PET = 24406,
SPELL_HUNTER_INVIGORATION_TRIGGERED = 53398,
@@ -192,8 +193,8 @@ class spell_hun_chimera_shot : public SpellScriptLoader
{
uint32 spellId = 0;
int32 basePoint = 0;
- Unit::AuraApplicationMap& Auras = unitTarget->GetAppliedAuras();
- for (Unit::AuraApplicationMap::iterator i = Auras.begin(); i != Auras.end(); ++i)
+ Unit::AuraApplicationMap const& auras = unitTarget->GetAppliedAuras();
+ for (Unit::AuraApplicationMap::const_iterator i = auras.begin(); i != auras.end(); ++i)
{
Aura* aura = i->second->GetBase();
if (aura->GetCasterGUID() != caster->GetGUID())
@@ -296,6 +297,68 @@ class spell_hun_disengage : public SpellScriptLoader
}
};
+// 56841 - Glyph of Arcane Shot
+class spell_hun_glyph_of_arcane_shot : public SpellScriptLoader
+{
+ public:
+ spell_hun_glyph_of_arcane_shot() : SpellScriptLoader("spell_hun_glyph_of_arcane_shot") { }
+
+ class spell_hun_glyph_of_arcane_shot_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_hun_glyph_of_arcane_shot_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_GLYPH_OF_ARCANE_SHOT))
+ return false;
+ return true;
+ }
+
+ bool CheckProc(ProcEventInfo& eventInfo)
+ {
+ if (Unit* procTarget = eventInfo.GetProcTarget())
+ {
+ Unit::AuraApplicationMap const& auras = procTarget->GetAppliedAuras();
+ for (Unit::AuraApplicationMap::const_iterator i = auras.begin(); i != auras.end(); ++i)
+ {
+ Aura const* aura = i->second->GetBase();
+ if (aura->GetCasterGUID() != GetTarget()->GetGUID())
+ continue;
+ // Search only Serpent Sting, Viper Sting, Scorpid Sting, Wyvern Sting
+ if (aura->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_HUNTER
+ && aura->GetSpellInfo()->SpellFamilyFlags.HasFlag(0xC000, 0x1080))
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ {
+ PreventDefaultAction();
+ SpellInfo const* procSpell = eventInfo.GetSpellInfo();
+ if (!procSpell)
+ return;
+
+ int32 mana = procSpell->CalcPowerCost(GetTarget(), procSpell->GetSchoolMask());
+ ApplyPct(mana, aurEff->GetAmount());
+
+ GetTarget()->CastCustomSpell(SPELL_HUNTER_GLYPH_OF_ARCANE_SHOT, SPELLVALUE_BASE_POINT0, mana, GetTarget());
+ }
+
+ void Register() override
+ {
+ DoCheckProc += AuraCheckProcFn(spell_hun_glyph_of_arcane_shot_AuraScript::CheckProc);
+ OnEffectProc += AuraEffectProcFn(spell_hun_glyph_of_arcane_shot_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_hun_glyph_of_arcane_shot_AuraScript();
+ }
+};
+
// -19572 - Improved Mend Pet
class spell_hun_improved_mend_pet : public SpellScriptLoader
{
@@ -336,6 +399,7 @@ class spell_hun_improved_mend_pet : public SpellScriptLoader
return new spell_hun_improved_mend_pet_AuraScript();
}
};
+
// 53412 - Invigoration
class spell_hun_invigoration : public SpellScriptLoader
{
@@ -952,6 +1016,7 @@ void AddSC_hunter_spell_scripts()
new spell_hun_ascpect_of_the_viper();
new spell_hun_chimera_shot();
new spell_hun_disengage();
+ new spell_hun_glyph_of_arcane_shot();
new spell_hun_improved_mend_pet();
new spell_hun_invigoration();
new spell_hun_last_stand_pet();
diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp
index 847de049128..8bd4b3eb070 100644
--- a/src/server/scripts/Spells/spell_paladin.cpp
+++ b/src/server/scripts/Spells/spell_paladin.cpp
@@ -1358,7 +1358,7 @@ class spell_pal_seal_of_righteousness : public SpellScriptLoader
float ap = GetTarget()->GetTotalAttackPowerValue(BASE_ATTACK);
int32 holy = GetTarget()->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_HOLY);
holy += eventInfo.GetProcTarget()->SpellBaseDamageBonusTaken(SPELL_SCHOOL_MASK_HOLY);
- int32 bp = int32((ap * 0.0225f + 0.0355f * holy) * GetTarget()->GetAttackTime(BASE_ATTACK) / 1000);
+ int32 bp = int32((ap * 0.022f + 0.044f * holy) * GetTarget()->GetAttackTime(BASE_ATTACK) / 1000);
GetTarget()->CastCustomSpell(SPELL_PALADIN_SEAL_OF_RIGHTEOUSNESS, SPELLVALUE_BASE_POINT0, bp, eventInfo.GetProcTarget(), true, NULL, aurEff);
}
diff --git a/src/server/scripts/Spells/spell_script_loader.cpp b/src/server/scripts/Spells/spell_script_loader.cpp
new file mode 100644
index 00000000000..b2c8d6663fa
--- /dev/null
+++ b/src/server/scripts/Spells/spell_script_loader.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// This is where scripts' loading functions should be declared:
+void AddSC_deathknight_spell_scripts();
+void AddSC_druid_spell_scripts();
+void AddSC_generic_spell_scripts();
+void AddSC_hunter_spell_scripts();
+void AddSC_mage_spell_scripts();
+void AddSC_paladin_spell_scripts();
+void AddSC_priest_spell_scripts();
+void AddSC_rogue_spell_scripts();
+void AddSC_shaman_spell_scripts();
+void AddSC_warlock_spell_scripts();
+void AddSC_warrior_spell_scripts();
+void AddSC_quest_spell_scripts();
+void AddSC_item_spell_scripts();
+void AddSC_holiday_spell_scripts();
+
+// The name of this function should match:
+// void Add${NameOfDirectory}Scripts()
+void AddSpellsScripts()
+{
+ AddSC_deathknight_spell_scripts();
+ AddSC_druid_spell_scripts();
+ AddSC_generic_spell_scripts();
+ AddSC_hunter_spell_scripts();
+ AddSC_mage_spell_scripts();
+ AddSC_paladin_spell_scripts();
+ AddSC_priest_spell_scripts();
+ AddSC_rogue_spell_scripts();
+ AddSC_shaman_spell_scripts();
+ AddSC_warlock_spell_scripts();
+ AddSC_warrior_spell_scripts();
+ AddSC_quest_spell_scripts();
+ AddSC_item_spell_scripts();
+ AddSC_holiday_spell_scripts();
+}
diff --git a/src/server/scripts/World/CMakeLists.txt b/src/server/scripts/World/CMakeLists.txt
deleted file mode 100644
index 17b3f2d8492..00000000000
--- a/src/server/scripts/World/CMakeLists.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
-#
-# This file is free software; as a special exception the author gives
-# unlimited permission to copy and/or distribute it, with or without
-# modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-file(GLOB_RECURSE sources_World World/*.cpp World/*.h)
-
-set(scripts_STAT_SRCS
- ${scripts_STAT_SRCS}
- ${sources_World}
-)
-
-message(" -> Prepared: World")
diff --git a/src/server/scripts/World/duel_reset.cpp b/src/server/scripts/World/duel_reset.cpp
index 3c46255a1bf..7982a5639ec 100644
--- a/src/server/scripts/World/duel_reset.cpp
+++ b/src/server/scripts/World/duel_reset.cpp
@@ -98,7 +98,7 @@ class DuelResetScript : public PlayerScript
static void ResetSpellCooldowns(Player* player, bool onStartDuel)
{
- if (onStartDuel)
+ if (onStartDuel)
{
// remove cooldowns on spells that have < 10 min CD > 30 sec and has no onHold
player->GetSpellHistory()->ResetCooldowns([](SpellHistory::CooldownStorageType::iterator itr) -> bool
@@ -106,8 +106,8 @@ class DuelResetScript : public PlayerScript
SpellHistory::Clock::time_point now = SpellHistory::Clock::now();
uint32 cooldownDuration = itr->second.CooldownEnd > now ? std::chrono::duration_cast<std::chrono::milliseconds>(itr->second.CooldownEnd - now).count() : 0;
SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first);
- return spellInfo->RecoveryTime < 10 * MINUTE * IN_MILLISECONDS
- && spellInfo->CategoryRecoveryTime < 10 * MINUTE * IN_MILLISECONDS
+ return spellInfo->RecoveryTime < 10 * MINUTE * IN_MILLISECONDS
+ && spellInfo->CategoryRecoveryTime < 10 * MINUTE * IN_MILLISECONDS
&& !itr->second.OnHold
&& cooldownDuration > 0
&& ( spellInfo->RecoveryTime - cooldownDuration ) > (MINUTE / 2) * IN_MILLISECONDS
@@ -120,10 +120,10 @@ class DuelResetScript : public PlayerScript
player->GetSpellHistory()->ResetCooldowns([](SpellHistory::CooldownStorageType::iterator itr) -> bool
{
SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first);
- return spellInfo->RecoveryTime < 10 * MINUTE * IN_MILLISECONDS
- && spellInfo->CategoryRecoveryTime < 10 * MINUTE * IN_MILLISECONDS
+ return spellInfo->RecoveryTime < 10 * MINUTE * IN_MILLISECONDS
+ && spellInfo->CategoryRecoveryTime < 10 * MINUTE * IN_MILLISECONDS
&& !itr->second.OnHold;
- }, true);
+ }, true);
}
// pet cooldowns
diff --git a/src/server/scripts/World/go_scripts.cpp b/src/server/scripts/World/go_scripts.cpp
index b90839f50c5..3094ecd660a 100644
--- a/src/server/scripts/World/go_scripts.cpp
+++ b/src/server/scripts/World/go_scripts.cpp
@@ -1211,7 +1211,7 @@ class go_toy_train_set : public GameObjectScript
struct go_toy_train_setAI : public GameObjectAI
{
go_toy_train_setAI(GameObject* go) : GameObjectAI(go), _pulseTimer(3 * IN_MILLISECONDS) { }
-
+
void UpdateAI(uint32 diff) override
{
if (diff < _pulseTimer)
diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp
index 80b4fac4333..159faa38c62 100644
--- a/src/server/scripts/World/npcs_special.cpp
+++ b/src/server/scripts/World/npcs_special.cpp
@@ -39,7 +39,6 @@ npc_shadowfiend 100% restore 5% of owner's mana when shadowfiend die f
npc_locksmith 75% list of keys needs to be confirmed
npc_firework 100% NPC's summoned by rockets and rocket clusters, for making them cast visual
npc_train_wrecker 100% Wind-Up Train Wrecker that kills train set
-npc_egbert 100% Egbert run's around
EndContentData */
#include "ScriptMgr.h"
@@ -58,7 +57,6 @@ EndContentData */
#include "SpellHistory.h"
#include "SpellAuras.h"
#include "Pet.h"
-#include "PetAI.h"
#include "CreatureTextMgr.h"
#include "SmartAI.h"
@@ -2573,170 +2571,6 @@ class npc_train_wrecker : public CreatureScript
}
};
-enum EgbertMisc
-{
- SPELL_EGBERT = 40669,
- EVENT_RETURN = 3
-};
-
-class npc_egbert : public CreatureScript
-{
-public:
- npc_egbert() : CreatureScript("npc_egbert") {}
-
- struct npc_egbertAI : public NullCreatureAI
- {
- npc_egbertAI(Creature* creature) : NullCreatureAI(creature)
- {
- if (Unit* owner = me->GetCharmerOrOwner())
- if (owner->GetMap()->GetEntry()->addon > 1)
- me->SetCanFly(true);
- }
-
- void Reset() override
- {
- _events.Reset();
- if (Unit* owner = me->GetCharmerOrOwner())
- me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, me->GetFollowAngle());
- }
-
- void EnterEvadeMode(EvadeReason why) override
- {
- if (!_EnterEvadeMode(why))
- return;
-
- Reset();
- }
-
- void UpdateAI(uint32 diff) override
- {
- _events.Update(diff);
-
- if (Unit* owner = me->GetCharmerOrOwner())
- {
- if (!me->IsWithinDist(owner, 40.f))
- {
- me->RemoveAura(SPELL_EGBERT);
- me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, me->GetFollowAngle());
- }
- }
-
- if (me->HasAura(SPELL_EGBERT))
- _events.ScheduleEvent(EVENT_RETURN, urandms(5, 20));
-
- while (uint32 eventId = _events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_RETURN:
- me->RemoveAura(SPELL_EGBERT);
- break;
- default:
- break;
- }
- }
- }
- private:
- EventMap _events;
- };
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new npc_egbertAI(creature);
- }
-};
-
-enum PandarenMonkMisc
-{
- SPELL_PANDAREN_MONK = 69800,
- EVENT_FOCUS = 1,
- EVENT_EMOTE = 2,
- EVENT_FOLLOW = 3,
- EVENT_DRINK = 4
-};
-
-class npc_pandaren_monk : public CreatureScript
-{
-public:
- npc_pandaren_monk() : CreatureScript("npc_pandaren_monk") {}
-
- struct npc_pandaren_monkAI : public NullCreatureAI
- {
- npc_pandaren_monkAI(Creature* creature) : NullCreatureAI(creature) { }
-
- void Reset() override
- {
- _events.Reset();
- _events.ScheduleEvent(EVENT_FOCUS, 1000);
- }
-
- void EnterEvadeMode(EvadeReason why) override
- {
- if (!_EnterEvadeMode(why))
- return;
-
- Reset();
- }
-
- void ReceiveEmote(Player* /*player*/, uint32 emote) override
- {
- me->InterruptSpell(CURRENT_CHANNELED_SPELL);
- me->StopMoving();
-
- switch (emote)
- {
- case TEXT_EMOTE_BOW:
- _events.ScheduleEvent(EVENT_FOCUS, 1000);
- break;
- case TEXT_EMOTE_DRINK:
- _events.ScheduleEvent(EVENT_DRINK, 1000);
- break;
- }
- }
-
- void UpdateAI(uint32 diff) override
- {
- _events.Update(diff);
-
- if (Unit* owner = me->GetCharmerOrOwner())
- if (!me->IsWithinDist(owner, 30.f))
- me->InterruptSpell(CURRENT_CHANNELED_SPELL);
-
- while (uint32 eventId = _events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_FOCUS:
- if (Unit* owner = me->GetCharmerOrOwner())
- me->SetFacingToObject(owner);
- _events.ScheduleEvent(EVENT_EMOTE, 1000);
- break;
- case EVENT_EMOTE:
- me->HandleEmoteCommand(EMOTE_ONESHOT_BOW);
- _events.ScheduleEvent(EVENT_FOLLOW, 1000);
- break;
- case EVENT_FOLLOW:
- if (Unit* owner = me->GetCharmerOrOwner())
- me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
- break;
- case EVENT_DRINK:
- me->CastSpell(me, SPELL_PANDAREN_MONK, false);
- break;
- default:
- break;
- }
- }
- }
- private:
- EventMap _events;
- };
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new npc_pandaren_monkAI(creature);
- }
-};
-
void AddSC_npcs_special()
{
new npc_air_force_bots();
@@ -2762,6 +2596,4 @@ void AddSC_npcs_special()
new npc_imp_in_a_ball();
new npc_stable_master();
new npc_train_wrecker();
- new npc_egbert();
- new npc_pandaren_monk();
}
diff --git a/src/server/scripts/World/world_script_loader.cpp b/src/server/scripts/World/world_script_loader.cpp
new file mode 100644
index 00000000000..0167024799f
--- /dev/null
+++ b/src/server/scripts/World/world_script_loader.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "World.h"
+
+// This is where scripts' loading functions should be declared:
+// world
+void AddSC_areatrigger_scripts();
+void AddSC_emerald_dragons();
+void AddSC_generic_creature();
+void AddSC_go_scripts();
+void AddSC_guards();
+void AddSC_item_scripts();
+void AddSC_npc_professions();
+void AddSC_npc_innkeeper();
+void AddSC_npcs_special();
+void AddSC_achievement_scripts();
+void AddSC_action_ip_logger();
+void AddSC_duel_reset();
+// player
+void AddSC_chat_log();
+void AddSC_action_ip_logger();
+
+// The name of this function should match:
+// void Add${NameOfDirectory}Scripts()
+void AddWorldScripts()
+{
+ AddSC_areatrigger_scripts();
+ AddSC_emerald_dragons();
+ AddSC_generic_creature();
+ AddSC_go_scripts();
+ AddSC_guards();
+ AddSC_item_scripts();
+ AddSC_npc_professions();
+ AddSC_npc_innkeeper();
+ AddSC_npcs_special();
+ AddSC_achievement_scripts();
+ AddSC_chat_log(); // location: scripts\World\chat_log.cpp
+
+ // FIXME: This should be moved in a script validation hook.
+ // To avoid duplicate code, we check once /*ONLY*/ if logging is permitted or not.
+ if (sWorld->getBoolConfig(CONFIG_IP_BASED_ACTION_LOGGING))
+ AddSC_action_ip_logger(); // location: scripts\World\action_ip_logger.cpp
+ AddSC_duel_reset();
+}
diff --git a/src/server/shared/CMakeLists.txt b/src/server/shared/CMakeLists.txt
index b6e5c8b1c6f..1ab340a4f3e 100644
--- a/src/server/shared/CMakeLists.txt
+++ b/src/server/shared/CMakeLists.txt
@@ -8,62 +8,60 @@
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-if( USE_COREPCH )
- include_directories(${CMAKE_CURRENT_BINARY_DIR})
-endif()
-
-file(GLOB_RECURSE sources_DataStores DataStores/*.cpp DataStores/*.h)
-file(GLOB_RECURSE sources_Dynamic Dynamic/*.cpp Dynamic/*.h)
-file(GLOB_RECURSE sources_Networking Networking/*.cpp Networking/*.h)
-file(GLOB_RECURSE sources_Packets Packets/*.cpp Packets/*.h)
-if( WIN32 )
- file(GLOB_RECURSE sources_Service Service/*.cpp Service/*.h)
-endif( WIN32 )
-file(GLOB sources_localdir *.cpp *.h)
-
-#
-# Build shared sourcelist
-#
+CollectSourceFiles(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ PRIVATE_SOURCES
+ # Exclude
+ ${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders)
if (USE_COREPCH)
- set(shared_STAT_PCH_HDR PrecompiledHeaders/sharedPCH.h)
- set(shared_STAT_PCH_SRC PrecompiledHeaders/sharedPCH.cpp)
+ set(PRIVATE_PCH_HEADER PrecompiledHeaders/sharedPCH.h)
+ set(PRIVATE_PCH_SOURCE PrecompiledHeaders/sharedPCH.cpp)
endif()
-set(shared_STAT_SRCS
- ${shared_STAT_SRCS}
- ${sources_DataStores}
- ${sources_Dynamic}
- ${sources_Networking}
- ${sources_Packets}
- ${sources_Utilities}
- ${sources_Service}
- ${sources_localdir}
-)
+GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
-include_directories(
- ${CMAKE_CURRENT_SOURCE_DIR}/Dynamic
- ${CMAKE_CURRENT_SOURCE_DIR}/Networking
- ${CMAKE_SOURCE_DIR}/dep/cppformat
- ${CMAKE_SOURCE_DIR}/src/common/
- ${CMAKE_SOURCE_DIR}/src/common/Debugging
- ${CMAKE_SOURCE_DIR}/src/common/Logging
- ${CMAKE_SOURCE_DIR}/src/common/Utilities
- ${MYSQL_INCLUDE_DIR}
- ${OPENSSL_INCLUDE_DIR}
- ${VALGRIND_INCLUDE_DIR}
+add_definitions(-DTRINITY_API_EXPORT_SHARED)
+
+add_library(shared
+ ${PRIVATE_SOURCES}
+ ${PRIVATE_PCH_SOURCE}
)
-GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
+CollectIncludeDirectories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ PUBLIC_INCLUDES
+ # Exclude
+ ${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders)
-add_library(shared STATIC
- ${shared_STAT_SRCS}
- ${shared_STAT_PCH_SRC}
-)
+target_include_directories(shared
+ PUBLIC
+ ${PUBLIC_INCLUDES}
+ PRIVATE
+ ${CMAKE_CURRENT_BINARY_DIR})
-add_dependencies(shared revision_data.h)
+target_link_libraries(shared
+ PUBLIC
+ database)
+
+set_target_properties(shared
+ PROPERTIES
+ FOLDER
+ "server")
+
+if( BUILD_SHARED_LIBS )
+ if( UNIX )
+ install(TARGETS shared
+ LIBRARY
+ DESTINATION lib)
+ elseif( WIN32 )
+ install(TARGETS shared
+ RUNTIME
+ DESTINATION "${CMAKE_INSTALL_PREFIX}")
+ endif()
+endif()
# Generate precompiled header
if (USE_COREPCH)
- add_cxx_pch(shared ${shared_STAT_PCH_HDR} ${shared_STAT_PCH_SRC})
+ add_cxx_pch(shared ${PRIVATE_PCH_HEADER} ${PRIVATE_PCH_SOURCE})
endif ()
diff --git a/src/server/shared/DataStores/DBCFileLoader.h b/src/server/shared/DataStores/DBCFileLoader.h
index 00b1ee54a4a..abe18d1425e 100644
--- a/src/server/shared/DataStores/DBCFileLoader.h
+++ b/src/server/shared/DataStores/DBCFileLoader.h
@@ -37,7 +37,7 @@ enum DbcFieldFormat
FT_SQL_ABSENT='a' //Used in sql format to mark column absent in sql dbc
};
-class DBCFileLoader
+class TC_SHARED_API DBCFileLoader
{
public:
DBCFileLoader();
diff --git a/src/server/shared/Networking/AsyncAcceptor.h b/src/server/shared/Networking/AsyncAcceptor.h
index 260e1c8ea11..f68da230553 100644
--- a/src/server/shared/Networking/AsyncAcceptor.h
+++ b/src/server/shared/Networking/AsyncAcceptor.h
@@ -20,34 +20,40 @@
#include "Log.h"
#include <boost/asio.hpp>
+#include <functional>
+#include <atomic>
using boost::asio::ip::tcp;
class AsyncAcceptor
{
public:
- typedef void(*ManagerAcceptHandler)(tcp::socket&& newSocket);
+ typedef void(*AcceptCallback)(tcp::socket&& newSocket, uint32 threadIndex);
AsyncAcceptor(boost::asio::io_service& ioService, std::string const& bindIp, uint16 port) :
_acceptor(ioService, tcp::endpoint(boost::asio::ip::address::from_string(bindIp), port)),
- _socket(ioService)
+ _socket(ioService), _closed(false), _socketFactory(std::bind(&AsyncAcceptor::DefeaultSocketFactory, this))
{
}
- template <class T>
+ template<class T>
void AsyncAccept();
- void AsyncAcceptManaged(ManagerAcceptHandler mgrHandler)
+ template<AcceptCallback acceptCallback>
+ void AsyncAcceptWithCallback()
{
- _acceptor.async_accept(_socket, [this, mgrHandler](boost::system::error_code error)
+ tcp::socket* socket;
+ uint32 threadIndex;
+ std::tie(socket, threadIndex) = _socketFactory();
+ _acceptor.async_accept(*socket, [this, socket, threadIndex](boost::system::error_code error)
{
if (!error)
{
try
{
- _socket.non_blocking(true);
+ socket->non_blocking(true);
- mgrHandler(std::move(_socket));
+ acceptCallback(std::move(*socket), threadIndex);
}
catch (boost::system::system_error const& err)
{
@@ -55,13 +61,29 @@ public:
}
}
- AsyncAcceptManaged(mgrHandler);
+ if (!_closed)
+ this->AsyncAcceptWithCallback<acceptCallback>();
});
}
+ void Close()
+ {
+ if (_closed.exchange(true))
+ return;
+
+ boost::system::error_code err;
+ _acceptor.close(err);
+ }
+
+ void SetSocketFactory(std::function<std::pair<tcp::socket*, uint32>()> func) { _socketFactory = func; }
+
private:
+ std::pair<tcp::socket*, uint32> DefeaultSocketFactory() { return std::make_pair(&_socket, 0); }
+
tcp::acceptor _acceptor;
tcp::socket _socket;
+ std::atomic<bool> _closed;
+ std::function<std::pair<tcp::socket*, uint32>()> _socketFactory;
};
template<class T>
@@ -83,7 +105,8 @@ void AsyncAcceptor::AsyncAccept()
}
// lets slap some more this-> on this so we can fix this bug with gcc 4.7.2 throwing internals in yo face
- this->AsyncAccept<T>();
+ if (!_closed)
+ this->AsyncAccept<T>();
});
}
diff --git a/src/server/shared/Networking/MessageBuffer.h b/src/server/shared/Networking/MessageBuffer.h
index 189a56f18b6..d68bee181b1 100644
--- a/src/server/shared/Networking/MessageBuffer.h
+++ b/src/server/shared/Networking/MessageBuffer.h
@@ -105,7 +105,7 @@ public:
return std::move(_storage);
}
- MessageBuffer& operator=(MessageBuffer& right)
+ MessageBuffer& operator=(MessageBuffer const& right)
{
if (this != &right)
{
diff --git a/src/server/shared/Networking/NetworkThread.h b/src/server/shared/Networking/NetworkThread.h
index ac216838bce..be0e9f10176 100644
--- a/src/server/shared/Networking/NetworkThread.h
+++ b/src/server/shared/Networking/NetworkThread.h
@@ -22,6 +22,8 @@
#include "Errors.h"
#include "Log.h"
#include "Timer.h"
+#include <boost/asio/ip/tcp.hpp>
+#include <boost/asio/deadline_timer.hpp>
#include <atomic>
#include <chrono>
#include <memory>
@@ -29,11 +31,14 @@
#include <set>
#include <thread>
+using boost::asio::ip::tcp;
+
template<class SocketType>
class NetworkThread
{
public:
- NetworkThread() : _connections(0), _stopped(false), _thread(nullptr)
+ NetworkThread() : _connections(0), _stopped(false), _thread(nullptr),
+ _acceptSocket(_io_service), _updateTimer(_io_service)
{
}
@@ -50,6 +55,7 @@ public:
void Stop()
{
_stopped = true;
+ _io_service.stop();
}
bool Start()
@@ -80,10 +86,12 @@ public:
std::lock_guard<std::mutex> lock(_newSocketsLock);
++_connections;
- _newSockets.insert(sock);
+ _newSockets.push_back(sock);
SocketAdded(sock);
}
+ tcp::socket* GetSocketForAccept() { return &_acceptSocket; }
+
protected:
virtual void SocketAdded(std::shared_ptr<SocketType> /*sock*/) { }
virtual void SocketRemoved(std::shared_ptr<SocketType> /*sock*/) { }
@@ -95,16 +103,15 @@ protected:
if (_newSockets.empty())
return;
- for (typename SocketSet::const_iterator i = _newSockets.begin(); i != _newSockets.end(); ++i)
+ for (std::shared_ptr<SocketType> sock : _newSockets)
{
- if (!(*i)->IsOpen())
+ if (!sock->IsOpen())
{
- SocketRemoved(*i);
-
+ SocketRemoved(sock);
--_connections;
}
else
- _Sockets.insert(*i);
+ _sockets.push_back(sock);
}
_newSockets.clear();
@@ -114,53 +121,58 @@ protected:
{
TC_LOG_DEBUG("misc", "Network Thread Starting");
- typename SocketSet::iterator i, t;
+ _updateTimer.expires_from_now(boost::posix_time::milliseconds(10));
+ _updateTimer.async_wait(std::bind(&NetworkThread<SocketType>::Update, this));
+ _io_service.run();
- uint32 sleepTime = 10;
- uint32 tickStart = 0, diff = 0;
- while (!_stopped)
- {
- std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
+ TC_LOG_DEBUG("misc", "Network Thread exits");
+ _newSockets.clear();
+ _sockets.clear();
+ }
+
+ void Update()
+ {
+ if (_stopped)
+ return;
- tickStart = getMSTime();
+ _updateTimer.expires_from_now(boost::posix_time::milliseconds(10));
+ _updateTimer.async_wait(std::bind(&NetworkThread<SocketType>::Update, this));
- AddNewSockets();
+ AddNewSockets();
- for (i = _Sockets.begin(); i != _Sockets.end();)
+ _sockets.erase(std::remove_if(_sockets.begin(), _sockets.end(), [this](std::shared_ptr<SocketType> sock)
+ {
+ if (!sock->Update())
{
- if (!(*i)->Update())
- {
- if ((*i)->IsOpen())
- (*i)->CloseSocket();
-
- SocketRemoved(*i);
-
- --_connections;
- _Sockets.erase(i++);
- }
- else
- ++i;
- }
+ if (sock->IsOpen())
+ sock->CloseSocket();
- diff = GetMSTimeDiffToNow(tickStart);
- sleepTime = diff > 10 ? 0 : 10 - diff;
- }
+ this->SocketRemoved(sock);
- TC_LOG_DEBUG("misc", "Network Thread exits");
+ --this->_connections;
+ return true;
+ }
+
+ return false;
+ }), _sockets.end());
}
private:
- typedef std::set<std::shared_ptr<SocketType> > SocketSet;
+ typedef std::vector<std::shared_ptr<SocketType>> SocketContainer;
std::atomic<int32> _connections;
std::atomic<bool> _stopped;
std::thread* _thread;
- SocketSet _Sockets;
+ SocketContainer _sockets;
std::mutex _newSocketsLock;
- SocketSet _newSockets;
+ SocketContainer _newSockets;
+
+ boost::asio::io_service _io_service;
+ tcp::socket _acceptSocket;
+ boost::asio::deadline_timer _updateTimer;
};
#endif // NetworkThread_h__
diff --git a/src/server/shared/Networking/Socket.h b/src/server/shared/Networking/Socket.h
index a2f57b5029e..0674ede57d8 100644
--- a/src/server/shared/Networking/Socket.h
+++ b/src/server/shared/Networking/Socket.h
@@ -21,15 +21,11 @@
#include "MessageBuffer.h"
#include "Log.h"
#include <atomic>
-#include <vector>
-#include <mutex>
#include <queue>
#include <memory>
#include <functional>
#include <type_traits>
#include <boost/asio/ip/tcp.hpp>
-#include <boost/asio/write.hpp>
-#include <boost/asio/read.hpp>
using boost::asio::ip::tcp;
@@ -59,18 +55,14 @@ public:
virtual bool Update()
{
- if (!IsOpen())
+ if (_closed)
return false;
#ifndef TC_SOCKET_USE_IOCP
- std::unique_lock<std::mutex> guard(_writeLock);
- if (!guard)
- return true;
-
- if (_isWritingAsync || (!_writeBuffer.GetActiveSize() && _writeQueue.empty()))
+ if (_isWritingAsync || (_writeQueue.empty() && !_closing))
return true;
- for (; WriteHandler(guard);)
+ for (; HandleQueue();)
;
#endif
@@ -98,14 +90,23 @@ public:
std::bind(&Socket<T>::ReadHandlerInternal, this->shared_from_this(), std::placeholders::_1, std::placeholders::_2));
}
- void QueuePacket(MessageBuffer&& buffer, std::unique_lock<std::mutex>& guard)
+ void AsyncReadWithCallback(void (T::*callback)(boost::system::error_code, std::size_t))
+ {
+ if (!IsOpen())
+ return;
+
+ _readBuffer.Normalize();
+ _readBuffer.EnsureFreeSpace();
+ _socket.async_read_some(boost::asio::buffer(_readBuffer.GetWritePointer(), _readBuffer.GetRemainingSpace()),
+ std::bind(callback, this->shared_from_this(), std::placeholders::_1, std::placeholders::_2));
+ }
+
+ void QueuePacket(MessageBuffer&& buffer)
{
_writeQueue.push(std::move(buffer));
#ifdef TC_SOCKET_USE_IOCP
- AsyncProcessQueue(guard);
-#else
- (void)guard;
+ AsyncProcessQueue();
#endif
}
@@ -135,7 +136,7 @@ protected:
virtual void ReadHandler() = 0;
- bool AsyncProcessQueue(std::unique_lock<std::mutex>&)
+ bool AsyncProcessQueue()
{
if (_isWritingAsync)
return false;
@@ -154,13 +155,14 @@ protected:
return false;
}
- std::mutex _writeLock;
- std::queue<MessageBuffer> _writeQueue;
-#ifndef TC_SOCKET_USE_IOCP
- MessageBuffer _writeBuffer;
-#endif
-
- boost::asio::io_service& io_service() { return _socket.get_io_service(); }
+ void SetNoDelay(bool enable)
+ {
+ boost::system::error_code err;
+ _socket.set_option(tcp::no_delay(enable), err);
+ if (err)
+ TC_LOG_DEBUG("network", "Socket::SetNoDelay: failed to set_option(boost::asio::ip::tcp::no_delay) for %s - %d (%s)",
+ GetRemoteIpAddress().to_string().c_str(), err.value(), err.message().c_str());
+ }
private:
void ReadHandlerInternal(boost::system::error_code error, size_t transferredBytes)
@@ -181,15 +183,13 @@ private:
{
if (!error)
{
- std::unique_lock<std::mutex> deleteGuard(_writeLock);
-
_isWritingAsync = false;
_writeQueue.front().ReadCompleted(transferedBytes);
if (!_writeQueue.front().GetActiveSize())
_writeQueue.pop();
if (!_writeQueue.empty())
- AsyncProcessQueue(deleteGuard);
+ AsyncProcessQueue();
else if (_closing)
CloseSocket();
}
@@ -201,47 +201,11 @@ private:
void WriteHandlerWrapper(boost::system::error_code /*error*/, std::size_t /*transferedBytes*/)
{
- std::unique_lock<std::mutex> guard(_writeLock);
_isWritingAsync = false;
- WriteHandler(guard);
+ HandleQueue();
}
- bool WriteHandler(std::unique_lock<std::mutex>& guard)
- {
- if (!IsOpen())
- return false;
-
- std::size_t bytesToSend = _writeBuffer.GetActiveSize();
-
- if (bytesToSend == 0)
- return HandleQueue(guard);
-
- boost::system::error_code error;
- std::size_t bytesWritten = _socket.write_some(boost::asio::buffer(_writeBuffer.GetReadPointer(), bytesToSend), error);
-
- if (error)
- {
- if (error == boost::asio::error::would_block || error == boost::asio::error::try_again)
- return AsyncProcessQueue(guard);
-
- return false;
- }
- else if (bytesWritten == 0)
- return false;
- else if (bytesWritten < bytesToSend)
- {
- _writeBuffer.ReadCompleted(bytesWritten);
- _writeBuffer.Normalize();
- return AsyncProcessQueue(guard);
- }
-
- // now bytesWritten == bytesToSend
- _writeBuffer.Reset();
-
- return HandleQueue(guard);
- }
-
- bool HandleQueue(std::unique_lock<std::mutex>& guard)
+ bool HandleQueue()
{
if (_writeQueue.empty())
return false;
@@ -256,23 +220,29 @@ private:
if (error)
{
if (error == boost::asio::error::would_block || error == boost::asio::error::try_again)
- return AsyncProcessQueue(guard);
+ return AsyncProcessQueue();
_writeQueue.pop();
+ if (_closing && _writeQueue.empty())
+ CloseSocket();
return false;
}
else if (bytesSent == 0)
{
_writeQueue.pop();
+ if (_closing && _writeQueue.empty())
+ CloseSocket();
return false;
}
else if (bytesSent < bytesToSend) // now n > 0
{
queuedMessage.ReadCompleted(bytesSent);
- return AsyncProcessQueue(guard);
+ return AsyncProcessQueue();
}
_writeQueue.pop();
+ if (_closing && _writeQueue.empty())
+ CloseSocket();
return !_writeQueue.empty();
}
@@ -284,6 +254,7 @@ private:
uint16 _remotePort;
MessageBuffer _readBuffer;
+ std::queue<MessageBuffer> _writeQueue;
std::atomic<bool> _closed;
std::atomic<bool> _closing;
diff --git a/src/server/shared/Networking/SocketMgr.h b/src/server/shared/Networking/SocketMgr.h
index ce5bc2d8fc2..b14aac4ca47 100644
--- a/src/server/shared/Networking/SocketMgr.h
+++ b/src/server/shared/Networking/SocketMgr.h
@@ -33,7 +33,7 @@ class SocketMgr
public:
virtual ~SocketMgr()
{
- delete[] _threads;
+ ASSERT(!_threads && !_acceptor && !_threadCount, "StopNetwork must be called prior to SocketMgr destruction");
}
virtual bool StartNetwork(boost::asio::io_service& service, std::string const& bindIp, uint16 port)
@@ -68,11 +68,19 @@ public:
virtual void StopNetwork()
{
+ _acceptor->Close();
+
if (_threadCount != 0)
for (int32 i = 0; i < _threadCount; ++i)
_threads[i].Stop();
Wait();
+
+ delete _acceptor;
+ _acceptor = nullptr;
+ delete[] _threads;
+ _threads = nullptr;
+ _threadCount = 0;
}
void Wait()
@@ -82,20 +90,14 @@ public:
_threads[i].Wait();
}
- virtual void OnSocketOpen(tcp::socket&& sock)
+ virtual void OnSocketOpen(tcp::socket&& sock, uint32 threadIndex)
{
- size_t min = 0;
-
- for (int32 i = 1; i < _threadCount; ++i)
- if (_threads[i].GetConnectionCount() < _threads[min].GetConnectionCount())
- min = i;
-
try
{
std::shared_ptr<SocketType> newSocket = std::make_shared<SocketType>(std::move(sock));
newSocket->Start();
- _threads[min].AddSocket(newSocket);
+ _threads[threadIndex].AddSocket(newSocket);
}
catch (boost::system::system_error const& err)
{
@@ -105,6 +107,23 @@ public:
int32 GetNetworkThreadCount() const { return _threadCount; }
+ uint32 SelectThreadWithMinConnections() const
+ {
+ uint32 min = 0;
+
+ for (int32 i = 1; i < _threadCount; ++i)
+ if (_threads[i].GetConnectionCount() < _threads[min].GetConnectionCount())
+ min = i;
+
+ return min;
+ }
+
+ std::pair<tcp::socket*, uint32> GetSocketForAccept()
+ {
+ uint32 threadIndex = SelectThreadWithMinConnections();
+ return std::make_pair(_threads[threadIndex].GetSocketForAccept(), threadIndex);
+ }
+
protected:
SocketMgr() : _acceptor(nullptr), _threads(nullptr), _threadCount(1)
{
diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h
index 5ebe5258a44..a779075e2ed 100644
--- a/src/server/shared/Packets/ByteBuffer.h
+++ b/src/server/shared/Packets/ByteBuffer.h
@@ -33,12 +33,11 @@
#include <time.h>
#include <cmath>
#include <type_traits>
-#include <boost/asio/buffer.hpp>
class MessageBuffer;
// Root of ByteBuffer exception hierarchy
-class ByteBufferException : public std::exception
+class TC_SHARED_API ByteBufferException : public std::exception
{
public:
~ByteBufferException() throw() { }
@@ -52,7 +51,7 @@ private:
std::string msg_;
};
-class ByteBufferPositionException : public ByteBufferException
+class TC_SHARED_API ByteBufferPositionException : public ByteBufferException
{
public:
ByteBufferPositionException(bool add, size_t pos, size_t size, size_t valueSize);
@@ -60,7 +59,7 @@ public:
~ByteBufferPositionException() throw() { }
};
-class ByteBufferSourceException : public ByteBufferException
+class TC_SHARED_API ByteBufferSourceException : public ByteBufferException
{
public:
ByteBufferSourceException(size_t pos, size_t size, size_t valueSize);
@@ -68,7 +67,7 @@ public:
~ByteBufferSourceException() throw() { }
};
-class ByteBuffer
+class TC_SHARED_API ByteBuffer
{
public:
const static size_t DEFAULT_SIZE = 0x1000;
@@ -628,15 +627,4 @@ inline void ByteBuffer::read_skip<std::string>()
read_skip<char*>();
}
-namespace boost
-{
- namespace asio
- {
- inline const_buffers_1 buffer(ByteBuffer const& packet)
- {
- return buffer(packet.contents(), packet.size());
- }
- }
-}
-
#endif
diff --git a/src/server/shared/Realm/Realm.cpp b/src/server/shared/Realm/Realm.cpp
new file mode 100644
index 00000000000..0c8f4d1d492
--- /dev/null
+++ b/src/server/shared/Realm/Realm.cpp
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Realm.h"
diff --git a/src/server/shared/Realm/Realm.h b/src/server/shared/Realm/Realm.h
new file mode 100644
index 00000000000..83a344dd817
--- /dev/null
+++ b/src/server/shared/Realm/Realm.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef Realm_h__
+#define Realm_h__
+
+#include "Common.h"
+#include <boost/asio/ip/address.hpp>
+#include <boost/asio/ip/tcp.hpp>
+
+using namespace boost::asio;
+
+enum RealmFlags
+{
+ REALM_FLAG_NONE = 0x00,
+ REALM_FLAG_VERSION_MISMATCH = 0x01,
+ REALM_FLAG_OFFLINE = 0x02,
+ REALM_FLAG_SPECIFYBUILD = 0x04,
+ REALM_FLAG_UNK1 = 0x08,
+ REALM_FLAG_UNK2 = 0x10,
+ REALM_FLAG_RECOMMENDED = 0x20,
+ REALM_FLAG_NEW = 0x40,
+ REALM_FLAG_FULL = 0x80
+};
+
+struct RealmHandle
+{
+ RealmHandle() : Realm(0) { }
+ RealmHandle(uint32 index) : Realm(index) { }
+
+ uint32 Realm; // primary key in `realmlist` table
+
+ bool operator<(RealmHandle const& r) const
+ {
+ return Realm < r.Realm;
+ }
+};
+
+/// Type of server, this is values from second column of Cfg_Configs.dbc
+enum RealmType
+{
+ REALM_TYPE_NORMAL = 0,
+ REALM_TYPE_PVP = 1,
+ REALM_TYPE_NORMAL2 = 4,
+ REALM_TYPE_RP = 6,
+ REALM_TYPE_RPPVP = 8,
+
+ MAX_CLIENT_REALM_TYPE = 14,
+
+ REALM_TYPE_FFA_PVP = 16 // custom, free for all pvp mode like arena PvP in all zones except rest activated places and sanctuaries
+ // replaced by REALM_PVP in realm list
+};
+
+// Storage object for a realm
+struct Realm
+{
+ RealmHandle Id;
+ uint32 Build;
+ ip::address ExternalAddress;
+ ip::address LocalAddress;
+ ip::address LocalSubnetMask;
+ uint16 Port;
+ std::string Name;
+ uint8 Type; // icon
+ RealmFlags Flags;
+ uint8 Timezone;
+ AccountTypes AllowedSecurityLevel;
+ float PopulationLevel;
+};
+
+#endif // Realm_h__
diff --git a/src/server/worldserver/CMakeLists.txt b/src/server/worldserver/CMakeLists.txt
index 535383ac605..7fb4c6d2b75 100644
--- a/src/server/worldserver/CMakeLists.txt
+++ b/src/server/worldserver/CMakeLists.txt
@@ -8,113 +8,29 @@
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-file(GLOB_RECURSE sources_CommandLine CommandLine/*.cpp CommandLine/*.h)
-file(GLOB_RECURSE sources_RemoteAccess RemoteAccess/*.cpp RemoteAccess/*.h)
-file(GLOB_RECURSE sources_TCSoap TCSoap/*.cpp TCSoap/*.h)
-file(GLOB sources_localdir *.cpp *.h)
-
-if (USE_COREPCH)
- set(worldserver_PCH_HDR PrecompiledHeaders/worldPCH.h)
- set(worldserver_PCH_SRC PrecompiledHeaders/worldPCH.cpp)
-endif()
-
-set(worldserver_SRCS
- ${worldserver_SRCS}
- ${sources_CommandLine}
- ${sources_RemoteAccess}
- ${sources_TCSoap}
- ${sources_localdir}
-)
+CollectSourceFiles(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ PRIVATE_SOURCES
+ # Exclude
+ ${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders)
if( WIN32 )
- set(worldserver_SRCS
- ${worldserver_SRCS}
- ${sources_windows_Debugging}
- )
+ list(APPEND PRIVATE_SOURCES ${sources_windows})
if ( MSVC )
- set(worldserver_SRCS
- ${worldserver_SRCS}
- worldserver.rc
- )
+ list(APPEND PRIVATE_SOURCES worldserver.rc)
endif()
endif()
-include_directories(
- ${CMAKE_BINARY_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR}/CommandLine
- ${CMAKE_CURRENT_SOURCE_DIR}/RemoteAccess
- ${CMAKE_CURRENT_SOURCE_DIR}/TCSoap
- ${CMAKE_SOURCE_DIR}/dep/cppformat
- ${CMAKE_SOURCE_DIR}/dep/g3dlite/include
- ${CMAKE_SOURCE_DIR}/dep/gsoap
- ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour/Include
- ${CMAKE_SOURCE_DIR}/src/common/
- ${CMAKE_SOURCE_DIR}/src/common/Collision
- ${CMAKE_SOURCE_DIR}/src/common/Collision/Models
- ${CMAKE_SOURCE_DIR}/src/common/Configuration
- ${CMAKE_SOURCE_DIR}/src/common/Cryptography
- ${CMAKE_SOURCE_DIR}/src/common/Cryptography/Authentication
- ${CMAKE_SOURCE_DIR}/src/common/Debugging
- ${CMAKE_SOURCE_DIR}/src/common/Logging
- ${CMAKE_SOURCE_DIR}/src/common/Threading
- ${CMAKE_SOURCE_DIR}/src/common/Utilities
- ${CMAKE_SOURCE_DIR}/src/server/authserver/Realms
- ${CMAKE_SOURCE_DIR}/src/server/database/
- ${CMAKE_SOURCE_DIR}/src/server/database/Database
- ${CMAKE_SOURCE_DIR}/src/server/database/Logging
- ${CMAKE_SOURCE_DIR}/src/server/game
- ${CMAKE_SOURCE_DIR}/src/server/game/Accounts
- ${CMAKE_SOURCE_DIR}/src/server/game/Addons
- ${CMAKE_SOURCE_DIR}/src/server/game/Battlegrounds
- ${CMAKE_SOURCE_DIR}/src/server/game/Chat
- ${CMAKE_SOURCE_DIR}/src/server/game/Combat
- ${CMAKE_SOURCE_DIR}/src/server/game/Conditions
- ${CMAKE_SOURCE_DIR}/src/server/game/DataStores
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Corpse
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Creature
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/DynamicObject
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/GameObject
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Item
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Item/Container
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Object
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Object/Updates
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Unit
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Vehicle
- ${CMAKE_SOURCE_DIR}/src/server/game/Globals
- ${CMAKE_SOURCE_DIR}/src/server/game/Grids
- ${CMAKE_SOURCE_DIR}/src/server/game/Grids/Cells
- ${CMAKE_SOURCE_DIR}/src/server/game/Handlers
- ${CMAKE_SOURCE_DIR}/src/server/game/Instances
- ${CMAKE_SOURCE_DIR}/src/server/game/Loot
- ${CMAKE_SOURCE_DIR}/src/server/game/Mails
- ${CMAKE_SOURCE_DIR}/src/server/game/Maps
- ${CMAKE_SOURCE_DIR}/src/server/game/Miscellaneous
- ${CMAKE_SOURCE_DIR}/src/server/game/Movement
- ${CMAKE_SOURCE_DIR}/src/server/game/Movement/Waypoints
- ${CMAKE_SOURCE_DIR}/src/server/game/Quests
- ${CMAKE_SOURCE_DIR}/src/server/game/Scripting
- ${CMAKE_SOURCE_DIR}/src/server/game/Server
- ${CMAKE_SOURCE_DIR}/src/server/game/Server/Protocol
- ${CMAKE_SOURCE_DIR}/src/server/game/Spells/Auras
- ${CMAKE_SOURCE_DIR}/src/server/game/Weather
- ${CMAKE_SOURCE_DIR}/src/server/game/World
- ${CMAKE_SOURCE_DIR}/src/server/shared
- ${CMAKE_SOURCE_DIR}/src/server/shared/DataStores
- ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic
- ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference
- ${CMAKE_SOURCE_DIR}/src/server/shared/Networking
- ${CMAKE_SOURCE_DIR}/src/server/shared/Packets
- ${CMAKE_SOURCE_DIR}/src/server/shared/Service
- ${MYSQL_INCLUDE_DIR}
- ${OPENSSL_INCLUDE_DIR}
- ${VALGRIND_INCLUDE_DIR}
-)
+if (USE_COREPCH)
+ set(PRIVATE_PCH_HEADER PrecompiledHeaders/worldPCH.h)
+ set(PRIVATE_PCH_SOURCE PrecompiledHeaders/worldPCH.cpp)
+endif()
GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
add_executable(worldserver
- ${worldserver_SRCS}
- ${worldserver_PCH_SRC}
+ ${PRIVATE_SOURCES}
+ ${PRIVATE_PCH_SOURCE}
)
if( NOT WIN32 )
@@ -130,24 +46,27 @@ endif()
set_target_properties(worldserver PROPERTIES LINK_FLAGS "${worldserver_LINK_FLAGS}")
target_link_libraries(worldserver
- game
- common
- shared
- database
- scripts
- g3dlib
- gsoap
- Detour
- format
- ${JEMALLOC_LIBRARY}
- ${READLINE_LIBRARY}
- ${TERMCAP_LIBRARY}
- ${MYSQL_LIBRARY}
- ${OPENSSL_LIBRARIES}
- ${ZLIB_LIBRARIES}
- ${CMAKE_THREAD_LIBS_INIT}
- ${Boost_LIBRARIES}
-)
+ PUBLIC
+ scripts
+ gsoap
+ readline)
+
+CollectIncludeDirectories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ PUBLIC_INCLUDES
+ # Exclude
+ ${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders)
+
+target_include_directories(worldserver
+ PUBLIC
+ ${PUBLIC_INCLUDES}
+ PRIVATE
+ ${CMAKE_CURRENT_BINARY_DIR})
+
+set_target_properties(worldserver
+ PROPERTIES
+ FOLDER
+ "server")
if( WIN32 )
if ( MSVC )
@@ -173,5 +92,5 @@ endif()
# Generate precompiled header
if( USE_COREPCH )
- add_cxx_pch(worldserver ${worldserver_PCH_HDR} ${worldserver_PCH_SRC})
+ add_cxx_pch(worldserver ${PRIVATE_PCH_HEADER} ${PRIVATE_PCH_SOURCE})
endif()
diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp
index 53c5f250851..229375c4e51 100644
--- a/src/server/worldserver/Main.cpp
+++ b/src/server/worldserver/Main.cpp
@@ -34,12 +34,12 @@
#include "OpenSSLCrypto.h"
#include "ProcessPriority.h"
#include "BigNumber.h"
-#include "RealmList.h"
#include "World.h"
#include "MapManager.h"
#include "InstanceSaveMgr.h"
#include "ObjectAccessor.h"
#include "ScriptMgr.h"
+#include "ScriptLoader.h"
#include "OutdoorPvP/OutdoorPvPMgr.h"
#include "BattlegroundMgr.h"
#include "TCSoap.h"
@@ -47,6 +47,7 @@
#include "GitRevision.h"
#include "WorldSocket.h"
#include "WorldSocketMgr.h"
+#include "Realm/Realm.h"
#include "DatabaseLoader.h"
#include "AppenderDB.h"
@@ -78,11 +79,6 @@ uint32 _worldLoopCounter(0);
uint32 _lastChangeMsTime(0);
uint32 _maxCoreStuckTimeInMs(0);
-WorldDatabaseWorkerPool WorldDatabase; ///< Accessor to the world database
-CharacterDatabaseWorkerPool CharacterDatabase; ///< Accessor to the character database
-LoginDatabaseWorkerPool LoginDatabase; ///< Accessor to the realm/login database
-uint32 realmID; ///< Id of the realm
-
void SignalHandler(const boost::system::error_code& error, int signalNumber);
void FreezeDetectorHandler(const boost::system::error_code& error);
AsyncAcceptor* StartRaSocketAcceptor(boost::asio::io_service& ioService);
@@ -92,11 +88,14 @@ void WorldUpdateLoop();
void ClearOnlineAccounts();
void ShutdownCLIThread(std::thread* cliThread);
void ShutdownThreadPool(std::vector<std::thread>& threadPool);
+bool LoadRealmInfo();
variables_map GetConsoleArguments(int argc, char** argv, std::string& cfg_file, std::string& cfg_service);
/// Launch the Trinity server
extern int main(int argc, char** argv)
{
+ signal(SIGABRT, &Trinity::AbortHandler);
+
std::string configFile = _TRINITY_CORE_CONFIG;
std::string configService;
@@ -188,9 +187,12 @@ extern int main(int argc, char** argv)
}
// Set server offline (not connectable)
- LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = (flag & ~%u) | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, REALM_FLAG_INVALID, realmID);
+ LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realm.Id.Realm);
+
+ LoadRealmInfo();
// Initialize the World
+ sScriptMgr->SetScriptLoader(AddScripts);
sWorld->SetInitialWorldSettings();
// Launch CliRunnable thread
@@ -223,7 +225,9 @@ extern int main(int argc, char** argv)
sWorldSocketMgr.StartNetwork(_ioService, worldListener, worldPort);
// Set server online (allow connecting now)
- LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag & ~%u, population = 0 WHERE id = '%u'", REALM_FLAG_INVALID, realmID);
+ LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag & ~%u, population = 0 WHERE id = '%u'", REALM_FLAG_OFFLINE, realm.Id.Realm);
+ realm.PopulationLevel = 0.0f;
+ realm.Flags = RealmFlags(realm.Flags & ~uint32(REALM_FLAG_OFFLINE));
// Start the freeze check callback cycle in 5 seconds (cycle itself is 1 sec)
if (int coreStuckTime = sConfigMgr->GetIntDefault("MaxCoreStuckTime", 0))
@@ -243,6 +247,8 @@ extern int main(int argc, char** argv)
// Shutdown starts here
ShutdownThreadPool(threadPool);
+ sLog->SetSynchronous();
+
sScriptMgr->OnShutdown();
sWorld->KickAll(); // save and kick all players
@@ -259,7 +265,7 @@ extern int main(int argc, char** argv)
sScriptMgr->Unload();
// set server offline
- LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realmID);
+ LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realm.Id.Realm);
// Clean up threads if any
if (soapThread != nullptr)
@@ -441,6 +447,59 @@ AsyncAcceptor* StartRaSocketAcceptor(boost::asio::io_service& ioService)
return acceptor;
}
+bool LoadRealmInfo()
+{
+ boost::asio::ip::tcp::resolver resolver(_ioService);
+ boost::asio::ip::tcp::resolver::iterator end;
+
+ QueryResult result = LoginDatabase.PQuery("SELECT id, name, address, localAddress, localSubnetMask, port, icon, flag, timezone, allowedSecurityLevel, population, gamebuild FROM realmlist WHERE id = %u", realm.Id.Realm);
+ if (!result)
+ return false;
+
+ Field* fields = result->Fetch();
+ realm.Name = fields[1].GetString();
+ boost::asio::ip::tcp::resolver::query externalAddressQuery(ip::tcp::v4(), fields[2].GetString(), "");
+
+ boost::system::error_code ec;
+ boost::asio::ip::tcp::resolver::iterator endPoint = resolver.resolve(externalAddressQuery, ec);
+ if (endPoint == end || ec)
+ {
+ TC_LOG_ERROR("server.worldserver", "Could not resolve address %s", fields[2].GetString().c_str());
+ return false;
+ }
+
+ realm.ExternalAddress = (*endPoint).endpoint().address();
+
+ boost::asio::ip::tcp::resolver::query localAddressQuery(ip::tcp::v4(), fields[3].GetString(), "");
+ endPoint = resolver.resolve(localAddressQuery, ec);
+ if (endPoint == end || ec)
+ {
+ TC_LOG_ERROR("server.worldserver", "Could not resolve address %s", fields[3].GetString().c_str());
+ return false;
+ }
+
+ realm.LocalAddress = (*endPoint).endpoint().address();
+
+ boost::asio::ip::tcp::resolver::query localSubmaskQuery(ip::tcp::v4(), fields[4].GetString(), "");
+ endPoint = resolver.resolve(localSubmaskQuery, ec);
+ if (endPoint == end || ec)
+ {
+ TC_LOG_ERROR("server.worldserver", "Could not resolve address %s", fields[4].GetString().c_str());
+ return false;
+ }
+
+ realm.LocalSubnetMask = (*endPoint).endpoint().address();
+
+ realm.Port = fields[5].GetUInt16();
+ realm.Type = fields[6].GetUInt8();
+ realm.Flags = RealmFlags(fields[7].GetUInt8());
+ realm.Timezone = fields[8].GetUInt8();
+ realm.AllowedSecurityLevel = AccountTypes(fields[9].GetUInt8());
+ realm.PopulationLevel = fields[10].GetFloat();
+ realm.Build = fields[11].GetUInt32();
+ return true;
+}
+
/// Initialize connection to the databases
bool StartDB()
{
@@ -449,21 +508,22 @@ bool StartDB()
// Load databases
DatabaseLoader loader("server.worldserver", DatabaseLoader::DATABASE_NONE);
loader
- .AddDatabase(WorldDatabase, "World")
+ .AddDatabase(LoginDatabase, "Login")
.AddDatabase(CharacterDatabase, "Character")
- .AddDatabase(LoginDatabase, "Login");
+ .AddDatabase(WorldDatabase, "World");
if (!loader.Load())
return false;
///- Get the realm Id from the configuration file
- realmID = sConfigMgr->GetIntDefault("RealmID", 0);
- if (!realmID)
+ realm.Id.Realm = sConfigMgr->GetIntDefault("RealmID", 0);
+ if (!realm.Id.Realm)
{
TC_LOG_ERROR("server.worldserver", "Realm ID not defined in configuration file");
return false;
}
- TC_LOG_INFO("server.worldserver", "Realm running as realm ID %d", realmID);
+
+ TC_LOG_INFO("server.worldserver", "Realm running as realm ID %d", realm.Id.Realm);
///- Clean the database before starting
ClearOnlineAccounts();
@@ -490,7 +550,7 @@ void StopDB()
void ClearOnlineAccounts()
{
// Reset online status for all accounts with characters on the current realm
- LoginDatabase.DirectPExecute("UPDATE account SET online = 0 WHERE online > 0 AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = %d)", realmID);
+ LoginDatabase.DirectPExecute("UPDATE account SET online = 0 WHERE online > 0 AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = %d)", realm.Id.Realm);
// Reset online status for all characters
CharacterDatabase.DirectExecute("UPDATE characters SET online = 0 WHERE online <> 0");
diff --git a/src/server/worldserver/RemoteAccess/RASession.cpp b/src/server/worldserver/RemoteAccess/RASession.cpp
index 59e7b138c48..1ad1ac1dc6c 100644
--- a/src/server/worldserver/RemoteAccess/RASession.cpp
+++ b/src/server/worldserver/RemoteAccess/RASession.cpp
@@ -121,7 +121,7 @@ bool RASession::CheckAccessLevel(const std::string& user)
{
std::string safeUser = user;
- AccountMgr::normalizeString(safeUser);
+ Utf8ToUpperOnlyLatin(safeUser);
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_ACCESS);
stmt->setString(0, safeUser);
@@ -153,10 +153,10 @@ bool RASession::CheckPassword(const std::string& user, const std::string& pass)
{
std::string safe_user = user;
std::transform(safe_user.begin(), safe_user.end(), safe_user.begin(), ::toupper);
- AccountMgr::normalizeString(safe_user);
+ Utf8ToUpperOnlyLatin(safe_user);
std::string safe_pass = pass;
- AccountMgr::normalizeString(safe_pass);
+ Utf8ToUpperOnlyLatin(safe_pass);
std::transform(safe_pass.begin(), safe_pass.end(), safe_pass.begin(), ::toupper);
std::string hash = AccountMgr::CalculateShaPassHash(safe_user, safe_pass);
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index 217995cb88a..8e68d9f08fe 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -161,6 +161,45 @@ BindIP = "0.0.0.0"
ThreadPool = 2
#
+# CMakeCommand
+# Description: The path to your CMake binary.
+# If the path is left empty, the built-in CMAKE_COMMAND is used.
+# Example: "C:/Program Files (x86)/CMake/bin/cmake.exe"
+# "/usr/bin/cmake"
+# Default: ""
+
+CMakeCommand = ""
+
+#
+# BuildDirectory
+# Description: The path to your build directory.
+# If the path is left empty, the built-in CMAKE_BINARY_DIR is used.
+# Example: "../TrinityCore"
+# Default: ""
+
+BuildDirectory = ""
+
+#
+# SourceDirectory
+# Description: The path to your TrinityCore source directory.
+# If the path is left empty, the built-in CMAKE_SOURCE_DIR is used.
+# Example: "../TrinityCore"
+# Default: ""
+
+SourceDirectory = ""
+
+#
+# MySQLExecutable
+# Description: The path to your mysql cli binary.
+# If the path is left empty, built-in path from cmake is used.
+# Example: "C:/Program Files/MySQL/MySQL Server 5.6/bin/mysql.exe"
+# "mysql.exe"
+# "/usr/bin/mysql"
+# Default: ""
+
+MySQLExecutable = ""
+
+#
###################################################################################################
###################################################################################################
@@ -231,6 +270,25 @@ MaxOverspeedPings = 2
GridUnload = 1
#
+# BaseMapLoadAllGrids
+# Description: Load all grids for base maps upon load. Requires GridUnload to be 0.
+# This will take around 5GB of ram upon server load, and will take some time
+# to initially load the server.
+# Default: 0 - (Don't pre-load all base maps, dynamically load as used)
+# 1 - (Preload all grids in all base maps upon load)
+
+BaseMapLoadAllGrids = 0
+
+#
+# InstanceMapLoadAllGrids
+# Description: Load all grids for instance maps upon load. Requires GridUnload to be 0.
+# Upon loading an instance map, all creatures/objects in the map will be pre-loaded
+# Default: 0 - (Don't pre-load all base maps, dynamically load as used)
+# 1 - (Preload all grids in the instance upon load)
+
+InstanceMapLoadAllGrids = 0
+
+#
# SocketTimeOutTime
# Description: Time (in milliseconds) after which a connection being idle on the character
# selection screen is disconnected.
@@ -1061,9 +1119,8 @@ BeepAtStart = 1
#
# Motd
-# Description: Message of the Day, displayed at login.
-# Use '@' for a newline and be sure to escape special characters.
-# Example: "Welcome to John\'s Server@This server runs on Trinity Core."
+# Description: Message of the Day, displayed at login. Use '@' for a newline.
+# Example: "Welcome to John's Server!@This server is proud to be powered by Trinity Core."
# Default: "Welcome to a Trinity Core server."
Motd = "Welcome to a Trinity Core server."
@@ -1167,26 +1224,6 @@ BirthdayTime = 1222964635
Updates.EnableDatabases = 7
#
-# Updates.SourcePath
-# Description: The path to your TrinityCore source directory.
-# If the path is left empty, built-in CMAKE_SOURCE_DIR is used.
-# Example: "../TrinityCore"
-# Default: ""
-
-Updates.SourcePath = ""
-
-#
-# Updates.MySqlCLIPath
-# Description: The path to your mysql cli binary.
-# If the path is left empty, built-in path from cmake is used.
-# Example: "C:/Program Files/MySQL/MySQL Server 5.6/bin/mysql.exe"
-# "mysql.exe"
-# "/usr/bin/mysql"
-# Default: ""
-
-Updates.MySqlCLIPath = ""
-
-#
# Updates.AutoSetup
# Description: Auto populate empty databases.
# Default: 1 - (Enabled)
@@ -1354,10 +1391,11 @@ AllowTwoSide.Trade = 0
#
# TalentsInspecting
-# Description: Allow inspecting characters from the opposing faction.
-# Doesn't affect characters in gamemaster mode.
-# Default: 1 - (Enabled)
-# 0 - (Disabled)
+# Description: Allow/disallow inspecting other characters' talents.
+# Doesn't affect game master accounts.
+# 2 - (Enabled for all characters)
+# Default: 1 - (Enabled for characters of the same faction)
+# 0 - (Talent inspecting is disabled)
TalentsInspecting = 1
@@ -3058,6 +3096,29 @@ AuctionHouseBot.Items.Orange.Price.Ratio = 100
AuctionHouseBot.Items.Yellow.Price.Ratio = 100
#
+# AuctionHouseBot.Class.CLASS.Price.Ratio
+# Description: Percentage by which the price of items sold of each class is incremented / decreased (for all houses)
+# Default: 100 - (No change)
+
+AuctionHouseBot.Class.Consumable.Price.Ratio = 100
+AuctionHouseBot.Class.Container.Price.Ratio = 100
+AuctionHouseBot.Class.Weapon.Price.Ratio = 100
+AuctionHouseBot.Class.Gem.Price.Ratio = 100
+AuctionHouseBot.Class.Armor.Price.Ratio = 100
+AuctionHouseBot.Class.Reagent.Price.Ratio = 100
+AuctionHouseBot.Class.Projectile.Price.Ratio = 100
+AuctionHouseBot.Class.TradeGood.Price.Ratio = 100
+AuctionHouseBot.Class.Generic.Price.Ratio = 100
+AuctionHouseBot.Class.Recipe.Price.Ratio = 100
+AuctionHouseBot.Class.Quiver.Price.Ratio = 100
+AuctionHouseBot.Class.Quest.Price.Ratio = 100
+AuctionHouseBot.Class.Key.Price.Ratio = 100
+AuctionHouseBot.Class.Misc.Price.Ratio = 100
+AuctionHouseBot.Class.Glyph.Price.Ratio = 100
+
+
+
+#
# AuctionHouseBot.Items.ItemLevel.*
# Description: Prevent seller from listing items below/above this item level
# Default: 0 - (Disabled)
@@ -3133,6 +3194,7 @@ AuctionHouseBot.Class.Key = 1
AuctionHouseBot.Class.Misc = 5
AuctionHouseBot.Class.Glyph = 3
+
#
###################################################################################################
@@ -3423,6 +3485,7 @@ Logger.server=3,Console Server
Logger.commands.gm=3,Console GM
Logger.sql.sql=5,Console DBErrors
Logger.sql.updates=3,Console Server
+Logger.mmaps=3,Server
#Logger.achievement=3,Console Server
#Logger.addon=3,Console Server
diff --git a/src/tools/map_extractor/CMakeLists.txt b/src/tools/map_extractor/CMakeLists.txt
index d0f3e42cef8..c0bd102f8e6 100644
--- a/src/tools/map_extractor/CMakeLists.txt
+++ b/src/tools/map_extractor/CMakeLists.txt
@@ -9,41 +9,38 @@
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-file(GLOB_RECURSE mapextractor_SRCS *.cpp *.h)
-
-set(include_Dirs
- ${CMAKE_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}/dep/cppformat
- ${CMAKE_SOURCE_DIR}/dep/g3dlite/include
- ${CMAKE_SOURCE_DIR}/dep/libmpq
- ${CMAKE_SOURCE_DIR}/src/common
- ${CMAKE_SOURCE_DIR}/src/common/Utilities
- ${CMAKE_SOURCE_DIR}/src/server/shared
- ${CMAKE_CURRENT_SOURCE_DIR}/loadlib
-)
-
-if( WIN32 )
- set(include_Dirs
- ${include_Dirs}
- ${CMAKE_SOURCE_DIR}/dep/libmpq/win
- )
-endif()
-
-include_directories(${include_Dirs})
+CollectSourceFiles(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ PRIVATE_SOURCES)
add_executable(mapextractor
- ${mapextractor_SRCS}
+ ${PRIVATE_SOURCES}
)
+target_include_directories(mapextractor
+ PUBLIC
+ ${CMAKE_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/loadlib)
+
target_link_libraries(mapextractor
- common
- format
- g3dlib
- mpq
- ${BZIP2_LIBRARIES}
- ${ZLIB_LIBRARIES}
- ${Boost_LIBRARIES}
-)
+ PUBLIC
+ common
+ mpq)
+
+CollectIncludeDirectories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ PUBLIC_INCLUDES)
+
+target_include_directories(mapextractor
+ PUBLIC
+ ${PUBLIC_INCLUDES}
+ PRIVATE
+ ${CMAKE_CURRENT_BINARY_DIR})
+
+set_target_properties(mapextractor
+ PROPERTIES
+ FOLDER
+ "tools")
if( UNIX )
install(TARGETS mapextractor DESTINATION bin)
diff --git a/src/tools/mmaps_generator/CMakeLists.txt b/src/tools/mmaps_generator/CMakeLists.txt
index 4eb416a106b..64c82101f61 100644
--- a/src/tools/mmaps_generator/CMakeLists.txt
+++ b/src/tools/mmaps_generator/CMakeLists.txt
@@ -8,51 +8,33 @@
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-file(GLOB_RECURSE mmap_gen_sources *.cpp *.h)
+CollectSourceFiles(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ PRIVATE_SOURCES)
-set(mmap_gen_Includes
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}/dep/libmpq
- ${CMAKE_SOURCE_DIR}/dep/zlib
- ${CMAKE_SOURCE_DIR}/dep/bzip2
- ${CMAKE_SOURCE_DIR}/dep/g3dlite/include
- ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast
- ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast/Include
- ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour
- ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour/Include
- ${CMAKE_SOURCE_DIR}/src/server/shared
- ${CMAKE_SOURCE_DIR}/src/server/game/Conditions
- ${CMAKE_SOURCE_DIR}/src/common
- ${CMAKE_SOURCE_DIR}/src/common/Collision
- ${CMAKE_SOURCE_DIR}/src/common/Collision/Management
- ${CMAKE_SOURCE_DIR}/src/common/Collision/Maps
- ${CMAKE_SOURCE_DIR}/src/common/Collision/Models
- ${CMAKE_SOURCE_DIR}/src/common/Debugging
- ${CMAKE_SOURCE_DIR}/src/common/Threading
- ${CMAKE_SOURCE_DIR}/src/common/Utilities
-)
+add_executable(mmaps_generator ${PRIVATE_SOURCES})
-if( WIN32 )
- set(mmap_gen_Includes
- ${mmap_gen_Includes}
- ${CMAKE_SOURCE_DIR}/dep/libmpq/win
- )
-endif()
+target_link_libraries(mmaps_generator
+ PUBLIC
+ common
+ Recast
+ Detour
+ mpq)
-include_directories(${mmap_gen_Includes})
+CollectIncludeDirectories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ PUBLIC_INCLUDES)
-add_executable(mmaps_generator ${mmap_gen_sources})
+target_include_directories(mmaps_generator
+ PUBLIC
+ ${PUBLIC_INCLUDES}
+ PRIVATE
+ ${CMAKE_CURRENT_BINARY_DIR})
-target_link_libraries(mmaps_generator
- common
- g3dlib
- Recast
- Detour
- ${BZIP2_LIBRARIES}
- ${ZLIB_LIBRARIES}
- ${CMAKE_THREAD_LIBS_INIT}
- ${Boost_LIBRARIES}
-)
+set_target_properties(mmaps_generator
+ PROPERTIES
+ FOLDER
+ "tools")
if( UNIX )
install(TARGETS mmaps_generator DESTINATION bin)
diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp
index 3a63f9718db..80b7b266f27 100644
--- a/src/tools/mmaps_generator/MapBuilder.cpp
+++ b/src/tools/mmaps_generator/MapBuilder.cpp
@@ -699,7 +699,7 @@ namespace MMAP
iv.polyMesh = rcAllocPolyMesh();
if (!iv.polyMesh)
{
- printf("%s alloc iv.polyMesh FIALED!\n", tileString);
+ printf("%s alloc iv.polyMesh FAILED!\n", tileString);
delete[] pmmerge;
delete[] dmmerge;
delete[] tiles;
@@ -710,7 +710,7 @@ namespace MMAP
iv.polyMeshDetail = rcAllocPolyMeshDetail();
if (!iv.polyMeshDetail)
{
- printf("%s alloc m_dmesh FIALED!\n", tileString);
+ printf("%s alloc m_dmesh FAILED!\n", tileString);
delete[] pmmerge;
delete[] dmmerge;
delete[] tiles;
diff --git a/src/tools/vmap4_assembler/CMakeLists.txt b/src/tools/vmap4_assembler/CMakeLists.txt
index c33b2996685..58cb066f75b 100644
--- a/src/tools/vmap4_assembler/CMakeLists.txt
+++ b/src/tools/vmap4_assembler/CMakeLists.txt
@@ -9,17 +9,6 @@
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-include_directories(
- ${CMAKE_SOURCE_DIR}/dep/g3dlite/include
- ${CMAKE_SOURCE_DIR}/src/server/shared
- ${CMAKE_SOURCE_DIR}/src/server/shared/Debugging
- ${CMAKE_SOURCE_DIR}/src/common
- ${CMAKE_SOURCE_DIR}/src/common/Collision
- ${CMAKE_SOURCE_DIR}/src/common/Collision/Maps
- ${CMAKE_SOURCE_DIR}/src/common/Collision/Models
- ${ZLIB_INCLUDE_DIR}
-)
-
add_executable(vmap4assembler VMapAssembler.cpp)
if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
@@ -28,9 +17,12 @@ endif()
target_link_libraries(vmap4assembler
common
- g3dlib
- ${ZLIB_LIBRARIES}
-)
+ zlib)
+
+set_target_properties(vmap4assembler
+ PROPERTIES
+ FOLDER
+ "tools")
if( UNIX )
install(TARGETS vmap4assembler DESTINATION bin)
diff --git a/src/tools/vmap4_extractor/CMakeLists.txt b/src/tools/vmap4_extractor/CMakeLists.txt
index 55e66b32ea8..f13aaec15b2 100644
--- a/src/tools/vmap4_extractor/CMakeLists.txt
+++ b/src/tools/vmap4_extractor/CMakeLists.txt
@@ -9,28 +9,30 @@
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-file(GLOB_RECURSE sources *.cpp *.h)
+CollectSourceFiles(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ PRIVATE_SOURCES)
-set(include_Dirs
- ${CMAKE_SOURCE_DIR}/dep/libmpq
-)
+add_executable(vmap4extractor ${PRIVATE_SOURCES})
-if( WIN32 )
- set(include_Dirs
- ${include_Dirs}
- ${CMAKE_SOURCE_DIR}/dep/libmpq/win
- )
-endif()
+target_link_libraries(vmap4extractor
+ PUBLIC
+ mpq)
-include_directories(${include_Dirs})
+CollectIncludeDirectories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ PUBLIC_INCLUDES)
-add_executable(vmap4extractor ${sources})
+target_include_directories(vmap4extractor
+ PUBLIC
+ ${PUBLIC_INCLUDES}
+ PRIVATE
+ ${CMAKE_CURRENT_BINARY_DIR})
-target_link_libraries(vmap4extractor
- mpq
- ${BZIP2_LIBRARIES}
- ${ZLIB_LIBRARIES}
-)
+set_target_properties(vmap4extractor
+ PROPERTIES
+ FOLDER
+ "tools")
if( UNIX )
install(TARGETS vmap4extractor DESTINATION bin)