Move core/realm files to new subdirectory
--HG-- branch : trunk rename : src/framework/CMakeLists.txt => src/server/framework/CMakeLists.txt rename : src/framework/Dynamic/FactoryHolder.h => src/server/framework/Dynamic/FactoryHolder.h rename : src/framework/Dynamic/ObjectRegistry.h => src/server/framework/Dynamic/ObjectRegistry.h rename : src/framework/GameSystem/Grid.h => src/server/framework/GameSystem/Grid.h rename : src/framework/GameSystem/GridLoader.h => src/server/framework/GameSystem/GridLoader.h rename : src/framework/GameSystem/GridRefManager.h => src/server/framework/GameSystem/GridRefManager.h rename : src/framework/GameSystem/GridReference.h => src/server/framework/GameSystem/GridReference.h rename : src/framework/GameSystem/NGrid.h => src/server/framework/GameSystem/NGrid.h rename : src/framework/GameSystem/TypeContainer.h => src/server/framework/GameSystem/TypeContainer.h rename : src/framework/GameSystem/TypeContainerFunctions.h => src/server/framework/GameSystem/TypeContainerFunctions.h rename : src/framework/GameSystem/TypeContainerFunctionsPtr.h => src/server/framework/GameSystem/TypeContainerFunctionsPtr.h rename : src/framework/GameSystem/TypeContainerVisitor.h => src/server/framework/GameSystem/TypeContainerVisitor.h rename : src/framework/Network/SocketDefines.h => src/server/framework/Network/SocketDefines.h rename : src/framework/Platform/CompilerDefs.h => src/server/framework/Platform/CompilerDefs.h rename : src/framework/Platform/Define.h => src/server/framework/Platform/Define.h rename : src/framework/Policies/CreationPolicy.h => src/server/framework/Policies/CreationPolicy.h rename : src/framework/Policies/ObjectLifeTime.cpp => src/server/framework/Policies/ObjectLifeTime.cpp rename : src/framework/Policies/ObjectLifeTime.h => src/server/framework/Policies/ObjectLifeTime.h rename : src/framework/Policies/Singleton.h => src/server/framework/Policies/Singleton.h rename : src/framework/Policies/SingletonImp.h => src/server/framework/Policies/SingletonImp.h rename : src/framework/Policies/ThreadingModel.h => src/server/framework/Policies/ThreadingModel.h rename : src/framework/Utilities/ByteConverter.h => src/server/framework/Utilities/ByteConverter.h rename : src/framework/Utilities/Callback.h => src/server/framework/Utilities/Callback.h rename : src/framework/Utilities/CountedReference/Reference.h => src/server/framework/Utilities/CountedReference/Reference.h rename : src/framework/Utilities/CountedReference/ReferenceHolder.h => src/server/framework/Utilities/CountedReference/ReferenceHolder.h rename : src/framework/Utilities/CountedReference/ReferenceImpl.h => src/server/framework/Utilities/CountedReference/ReferenceImpl.h rename : src/framework/Utilities/EventProcessor.cpp => src/server/framework/Utilities/EventProcessor.cpp rename : src/framework/Utilities/EventProcessor.h => src/server/framework/Utilities/EventProcessor.h rename : src/framework/Utilities/LinkedList.h => src/server/framework/Utilities/LinkedList.h rename : src/framework/Utilities/LinkedReference/RefManager.h => src/server/framework/Utilities/LinkedReference/RefManager.h rename : src/framework/Utilities/LinkedReference/Reference.h => src/server/framework/Utilities/LinkedReference/Reference.h rename : src/framework/Utilities/TypeList.h => src/server/framework/Utilities/TypeList.h rename : src/framework/Utilities/UnorderedMap.h => src/server/framework/Utilities/UnorderedMap.h rename : src/game/AccountMgr.cpp => src/server/game/AccountMgr.cpp rename : src/game/AccountMgr.h => src/server/game/AccountMgr.h rename : src/game/AchievementMgr.cpp => src/server/game/AchievementMgr.cpp rename : src/game/AchievementMgr.h => src/server/game/AchievementMgr.h rename : src/game/AddonHandler.cpp => src/server/game/AddonHandler.cpp rename : src/game/AddonHandler.h => src/server/game/AddonHandler.h rename : src/game/AddonMgr.cpp => src/server/game/AddonMgr.cpp rename : src/game/AddonMgr.h => src/server/game/AddonMgr.h rename : src/game/ArenaTeam.cpp => src/server/game/ArenaTeam.cpp rename : src/game/ArenaTeam.h => src/server/game/ArenaTeam.h rename : src/game/ArenaTeamHandler.cpp => src/server/game/ArenaTeamHandler.cpp rename : src/game/AuctionHouseBot.cpp => src/server/game/AuctionHouseBot.cpp rename : src/game/AuctionHouseBot.h => src/server/game/AuctionHouseBot.h rename : src/game/AuctionHouseHandler.cpp => src/server/game/AuctionHouseHandler.cpp rename : src/game/AuctionHouseMgr.cpp => src/server/game/AuctionHouseMgr.cpp rename : src/game/AuctionHouseMgr.h => src/server/game/AuctionHouseMgr.h rename : src/game/Bag.cpp => src/server/game/Bag.cpp rename : src/game/Bag.h => src/server/game/Bag.h rename : src/game/BattleGround.cpp => src/server/game/BattleGround.cpp rename : src/game/BattleGround.h => src/server/game/BattleGround.h rename : src/game/BattleGroundAA.cpp => src/server/game/BattleGroundAA.cpp rename : src/game/BattleGroundAA.h => src/server/game/BattleGroundAA.h rename : src/game/BattleGroundAB.cpp => src/server/game/BattleGroundAB.cpp rename : src/game/BattleGroundAB.h => src/server/game/BattleGroundAB.h rename : src/game/BattleGroundAV.cpp => src/server/game/BattleGroundAV.cpp rename : src/game/BattleGroundAV.h => src/server/game/BattleGroundAV.h rename : src/game/BattleGroundBE.cpp => src/server/game/BattleGroundBE.cpp rename : src/game/BattleGroundBE.h => src/server/game/BattleGroundBE.h rename : src/game/BattleGroundDS.cpp => src/server/game/BattleGroundDS.cpp rename : src/game/BattleGroundDS.h => src/server/game/BattleGroundDS.h rename : src/game/BattleGroundEY.cpp => src/server/game/BattleGroundEY.cpp rename : src/game/BattleGroundEY.h => src/server/game/BattleGroundEY.h rename : src/game/BattleGroundHandler.cpp => src/server/game/BattleGroundHandler.cpp rename : src/game/BattleGroundIC.cpp => src/server/game/BattleGroundIC.cpp rename : src/game/BattleGroundIC.h => src/server/game/BattleGroundIC.h rename : src/game/BattleGroundMgr.cpp => src/server/game/BattleGroundMgr.cpp rename : src/game/BattleGroundMgr.h => src/server/game/BattleGroundMgr.h rename : src/game/BattleGroundNA.cpp => src/server/game/BattleGroundNA.cpp rename : src/game/BattleGroundNA.h => src/server/game/BattleGroundNA.h rename : src/game/BattleGroundRB.cpp => src/server/game/BattleGroundRB.cpp rename : src/game/BattleGroundRB.h => src/server/game/BattleGroundRB.h rename : src/game/BattleGroundRL.cpp => src/server/game/BattleGroundRL.cpp rename : src/game/BattleGroundRL.h => src/server/game/BattleGroundRL.h rename : src/game/BattleGroundRV.cpp => src/server/game/BattleGroundRV.cpp rename : src/game/BattleGroundRV.h => src/server/game/BattleGroundRV.h rename : src/game/BattleGroundSA.cpp => src/server/game/BattleGroundSA.cpp rename : src/game/BattleGroundSA.h => src/server/game/BattleGroundSA.h rename : src/game/BattleGroundWS.cpp => src/server/game/BattleGroundWS.cpp rename : src/game/BattleGroundWS.h => src/server/game/BattleGroundWS.h rename : src/game/CMakeLists.txt => src/server/game/CMakeLists.txt rename : src/game/Calendar.cpp => src/server/game/Calendar.cpp rename : src/game/Calendar.h => src/server/game/Calendar.h rename : src/game/CalendarHandler.cpp => src/server/game/CalendarHandler.cpp rename : src/game/Cell.h => src/server/game/Cell.h rename : src/game/CellImpl.h => src/server/game/CellImpl.h rename : src/game/Channel.cpp => src/server/game/Channel.cpp rename : src/game/Channel.h => src/server/game/Channel.h rename : src/game/ChannelHandler.cpp => src/server/game/ChannelHandler.cpp rename : src/game/ChannelMgr.cpp => src/server/game/ChannelMgr.cpp rename : src/game/ChannelMgr.h => src/server/game/ChannelMgr.h rename : src/game/CharacterHandler.cpp => src/server/game/CharacterHandler.cpp rename : src/game/Chat.cpp => src/server/game/Chat.cpp rename : src/game/Chat.h => src/server/game/Chat.h rename : src/game/ChatHandler.cpp => src/server/game/ChatHandler.cpp rename : src/game/CombatAI.cpp => src/server/game/CombatAI.cpp rename : src/game/CombatAI.h => src/server/game/CombatAI.h rename : src/game/CombatHandler.cpp => src/server/game/CombatHandler.cpp rename : src/game/ConditionMgr.cpp => src/server/game/ConditionMgr.cpp rename : src/game/ConditionMgr.h => src/server/game/ConditionMgr.h rename : src/game/ConfusedMovementGenerator.cpp => src/server/game/ConfusedMovementGenerator.cpp rename : src/game/ConfusedMovementGenerator.h => src/server/game/ConfusedMovementGenerator.h rename : src/game/Corpse.cpp => src/server/game/Corpse.cpp rename : src/game/Corpse.h => src/server/game/Corpse.h rename : src/game/Creature.cpp => src/server/game/Creature.cpp rename : src/game/Creature.h => src/server/game/Creature.h rename : src/game/CreatureAI.cpp => src/server/game/CreatureAI.cpp rename : src/game/CreatureAI.h => src/server/game/CreatureAI.h rename : src/game/CreatureAIFactory.h => src/server/game/CreatureAIFactory.h rename : src/game/CreatureAIImpl.h => src/server/game/CreatureAIImpl.h rename : src/game/CreatureAIRegistry.cpp => src/server/game/CreatureAIRegistry.cpp rename : src/game/CreatureAIRegistry.h => src/server/game/CreatureAIRegistry.h rename : src/game/CreatureAISelector.cpp => src/server/game/CreatureAISelector.cpp rename : src/game/CreatureAISelector.h => src/server/game/CreatureAISelector.h rename : src/game/CreatureEventAI.cpp => src/server/game/CreatureEventAI.cpp rename : src/game/CreatureEventAI.h => src/server/game/CreatureEventAI.h rename : src/game/CreatureEventAIMgr.cpp => src/server/game/CreatureEventAIMgr.cpp rename : src/game/CreatureEventAIMgr.h => src/server/game/CreatureEventAIMgr.h rename : src/game/CreatureGroups.cpp => src/server/game/CreatureGroups.cpp rename : src/game/CreatureGroups.h => src/server/game/CreatureGroups.h rename : src/game/DBCEnums.h => src/server/game/DBCEnums.h rename : src/game/DBCStores.cpp => src/server/game/DBCStores.cpp rename : src/game/DBCStores.h => src/server/game/DBCStores.h rename : src/game/DBCStructure.h => src/server/game/DBCStructure.h rename : src/game/DBCfmt.h => src/server/game/DBCfmt.h rename : src/game/Debugcmds.cpp => src/server/game/Debugcmds.cpp rename : src/game/DestinationHolder.cpp => src/server/game/DestinationHolder.cpp rename : src/game/DestinationHolder.h => src/server/game/DestinationHolder.h rename : src/game/DestinationHolderImp.h => src/server/game/DestinationHolderImp.h rename : src/game/DuelHandler.cpp => src/server/game/DuelHandler.cpp rename : src/game/DynamicObject.cpp => src/server/game/DynamicObject.cpp rename : src/game/DynamicObject.h => src/server/game/DynamicObject.h rename : src/game/FleeingMovementGenerator.cpp => src/server/game/FleeingMovementGenerator.cpp rename : src/game/FleeingMovementGenerator.h => src/server/game/FleeingMovementGenerator.h rename : src/game/FollowerRefManager.h => src/server/game/FollowerRefManager.h rename : src/game/FollowerReference.cpp => src/server/game/FollowerReference.cpp rename : src/game/FollowerReference.h => src/server/game/FollowerReference.h rename : src/game/Formulas.h => src/server/game/Formulas.h rename : src/game/GameEventMgr.cpp => src/server/game/GameEventMgr.cpp rename : src/game/GameEventMgr.h => src/server/game/GameEventMgr.h rename : src/game/GameObject.cpp => src/server/game/GameObject.cpp rename : src/game/GameObject.h => src/server/game/GameObject.h rename : src/game/GlobalEvents.cpp => src/server/game/GlobalEvents.cpp rename : src/game/GlobalEvents.h => src/server/game/GlobalEvents.h rename : src/game/GossipDef.cpp => src/server/game/GossipDef.cpp rename : src/game/GossipDef.h => src/server/game/GossipDef.h rename : src/game/GridDefines.h => src/server/game/GridDefines.h rename : src/game/GridNotifiers.cpp => src/server/game/GridNotifiers.cpp rename : src/game/GridNotifiers.h => src/server/game/GridNotifiers.h rename : src/game/GridNotifiersImpl.h => src/server/game/GridNotifiersImpl.h rename : src/game/GridStates.cpp => src/server/game/GridStates.cpp rename : src/game/GridStates.h => src/server/game/GridStates.h rename : src/game/Group.cpp => src/server/game/Group.cpp rename : src/game/Group.h => src/server/game/Group.h rename : src/game/GroupHandler.cpp => src/server/game/GroupHandler.cpp rename : src/game/GroupRefManager.h => src/server/game/GroupRefManager.h rename : src/game/GroupReference.cpp => src/server/game/GroupReference.cpp rename : src/game/GroupReference.h => src/server/game/GroupReference.h rename : src/game/GuardAI.cpp => src/server/game/GuardAI.cpp rename : src/game/GuardAI.h => src/server/game/GuardAI.h rename : src/game/Guild.cpp => src/server/game/Guild.cpp rename : src/game/Guild.h => src/server/game/Guild.h rename : src/game/GuildHandler.cpp => src/server/game/GuildHandler.cpp rename : src/game/HomeMovementGenerator.cpp => src/server/game/HomeMovementGenerator.cpp rename : src/game/HomeMovementGenerator.h => src/server/game/HomeMovementGenerator.h rename : src/game/HostileRefManager.cpp => src/server/game/HostileRefManager.cpp rename : src/game/HostileRefManager.h => src/server/game/HostileRefManager.h rename : src/game/IdleMovementGenerator.cpp => src/server/game/IdleMovementGenerator.cpp rename : src/game/IdleMovementGenerator.h => src/server/game/IdleMovementGenerator.h rename : src/game/InstanceData.cpp => src/server/game/InstanceData.cpp rename : src/game/InstanceData.h => src/server/game/InstanceData.h rename : src/game/InstanceSaveMgr.cpp => src/server/game/InstanceSaveMgr.cpp rename : src/game/InstanceSaveMgr.h => src/server/game/InstanceSaveMgr.h rename : src/game/Item.cpp => src/server/game/Item.cpp rename : src/game/Item.h => src/server/game/Item.h rename : src/game/ItemEnchantmentMgr.cpp => src/server/game/ItemEnchantmentMgr.cpp rename : src/game/ItemEnchantmentMgr.h => src/server/game/ItemEnchantmentMgr.h rename : src/game/ItemHandler.cpp => src/server/game/ItemHandler.cpp rename : src/game/ItemPrototype.h => src/server/game/ItemPrototype.h rename : src/game/LFG.h => src/server/game/LFG.h rename : src/game/LFGHandler.cpp => src/server/game/LFGHandler.cpp rename : src/game/LFGMgr.cpp => src/server/game/LFGMgr.cpp rename : src/game/LFGMgr.h => src/server/game/LFGMgr.h rename : src/game/Language.h => src/server/game/Language.h rename : src/game/Level0.cpp => src/server/game/Level0.cpp rename : src/game/Level1.cpp => src/server/game/Level1.cpp rename : src/game/Level2.cpp => src/server/game/Level2.cpp rename : src/game/Level3.cpp => src/server/game/Level3.cpp rename : src/game/LootHandler.cpp => src/server/game/LootHandler.cpp rename : src/game/LootMgr.cpp => src/server/game/LootMgr.cpp rename : src/game/LootMgr.h => src/server/game/LootMgr.h rename : src/game/Mail.cpp => src/server/game/Mail.cpp rename : src/game/Mail.h => src/server/game/Mail.h rename : src/game/Map.cpp => src/server/game/Map.cpp rename : src/game/Map.h => src/server/game/Map.h rename : src/game/MapInstanced.cpp => src/server/game/MapInstanced.cpp rename : src/game/MapInstanced.h => src/server/game/MapInstanced.h rename : src/game/MapManager.cpp => src/server/game/MapManager.cpp rename : src/game/MapManager.h => src/server/game/MapManager.h rename : src/game/MapRefManager.h => src/server/game/MapRefManager.h rename : src/game/MapReference.h => src/server/game/MapReference.h rename : src/game/MapUpdater.cpp => src/server/game/MapUpdater.cpp rename : src/game/MapUpdater.h => src/server/game/MapUpdater.h rename : src/game/MiscHandler.cpp => src/server/game/MiscHandler.cpp rename : src/game/MotionMaster.cpp => src/server/game/MotionMaster.cpp rename : src/game/MotionMaster.h => src/server/game/MotionMaster.h rename : src/game/MovementGenerator.cpp => src/server/game/MovementGenerator.cpp rename : src/game/MovementGenerator.h => src/server/game/MovementGenerator.h rename : src/game/MovementGeneratorImpl.h => src/server/game/MovementGeneratorImpl.h rename : src/game/MovementHandler.cpp => src/server/game/MovementHandler.cpp rename : src/game/NPCHandler.cpp => src/server/game/NPCHandler.cpp rename : src/game/NPCHandler.h => src/server/game/NPCHandler.h rename : src/game/Object.cpp => src/server/game/Object.cpp rename : src/game/Object.h => src/server/game/Object.h rename : src/game/ObjectAccessor.cpp => src/server/game/ObjectAccessor.cpp rename : src/game/ObjectAccessor.h => src/server/game/ObjectAccessor.h rename : src/game/ObjectDefines.h => src/server/game/ObjectDefines.h rename : src/game/ObjectGridLoader.cpp => src/server/game/ObjectGridLoader.cpp rename : src/game/ObjectGridLoader.h => src/server/game/ObjectGridLoader.h rename : src/game/ObjectMgr.cpp => src/server/game/ObjectMgr.cpp rename : src/game/ObjectMgr.h => src/server/game/ObjectMgr.h rename : src/game/ObjectPosSelector.cpp => src/server/game/ObjectPosSelector.cpp rename : src/game/ObjectPosSelector.h => src/server/game/ObjectPosSelector.h rename : src/game/Opcodes.cpp => src/server/game/Opcodes.cpp rename : src/game/Opcodes.h => src/server/game/Opcodes.h rename : src/game/OutdoorPvP.cpp => src/server/game/OutdoorPvP.cpp rename : src/game/OutdoorPvP.h => src/server/game/OutdoorPvP.h rename : src/game/OutdoorPvPEP.cpp => src/server/game/OutdoorPvPEP.cpp rename : src/game/OutdoorPvPEP.h => src/server/game/OutdoorPvPEP.h rename : src/game/OutdoorPvPHP.cpp => src/server/game/OutdoorPvPHP.cpp rename : src/game/OutdoorPvPHP.h => src/server/game/OutdoorPvPHP.h rename : src/game/OutdoorPvPImpl.h => src/server/game/OutdoorPvPImpl.h rename : src/game/OutdoorPvPMgr.cpp => src/server/game/OutdoorPvPMgr.cpp rename : src/game/OutdoorPvPMgr.h => src/server/game/OutdoorPvPMgr.h rename : src/game/OutdoorPvPNA.cpp => src/server/game/OutdoorPvPNA.cpp rename : src/game/OutdoorPvPNA.h => src/server/game/OutdoorPvPNA.h rename : src/game/OutdoorPvPSI.cpp => src/server/game/OutdoorPvPSI.cpp rename : src/game/OutdoorPvPSI.h => src/server/game/OutdoorPvPSI.h rename : src/game/OutdoorPvPTF.cpp => src/server/game/OutdoorPvPTF.cpp rename : src/game/OutdoorPvPTF.h => src/server/game/OutdoorPvPTF.h rename : src/game/OutdoorPvPZM.cpp => src/server/game/OutdoorPvPZM.cpp rename : src/game/OutdoorPvPZM.h => src/server/game/OutdoorPvPZM.h rename : src/game/PassiveAI.cpp => src/server/game/PassiveAI.cpp rename : src/game/PassiveAI.h => src/server/game/PassiveAI.h rename : src/game/Path.h => src/server/game/Path.h rename : src/game/Pet.cpp => src/server/game/Pet.cpp rename : src/game/Pet.h => src/server/game/Pet.h rename : src/game/PetAI.cpp => src/server/game/PetAI.cpp rename : src/game/PetAI.h => src/server/game/PetAI.h rename : src/game/PetHandler.cpp => src/server/game/PetHandler.cpp rename : src/game/PetitionsHandler.cpp => src/server/game/PetitionsHandler.cpp rename : src/game/Player.cpp => src/server/game/Player.cpp rename : src/game/Player.h => src/server/game/Player.h rename : src/game/PlayerDump.cpp => src/server/game/PlayerDump.cpp rename : src/game/PlayerDump.h => src/server/game/PlayerDump.h rename : src/game/PointMovementGenerator.cpp => src/server/game/PointMovementGenerator.cpp rename : src/game/PointMovementGenerator.h => src/server/game/PointMovementGenerator.h rename : src/game/PoolHandler.cpp => src/server/game/PoolHandler.cpp rename : src/game/PoolHandler.h => src/server/game/PoolHandler.h rename : src/game/QueryHandler.cpp => src/server/game/QueryHandler.cpp rename : src/game/QuestDef.cpp => src/server/game/QuestDef.cpp rename : src/game/QuestDef.h => src/server/game/QuestDef.h rename : src/game/QuestHandler.cpp => src/server/game/QuestHandler.cpp rename : src/game/RandomMovementGenerator.cpp => src/server/game/RandomMovementGenerator.cpp rename : src/game/RandomMovementGenerator.h => src/server/game/RandomMovementGenerator.h rename : src/game/ReactorAI.cpp => src/server/game/ReactorAI.cpp rename : src/game/ReactorAI.h => src/server/game/ReactorAI.h rename : src/game/ReputationMgr.cpp => src/server/game/ReputationMgr.cpp rename : src/game/ReputationMgr.h => src/server/game/ReputationMgr.h rename : src/game/ScriptLoader.cpp => src/server/game/ScriptLoader.cpp rename : src/game/ScriptLoader.h => src/server/game/ScriptLoader.h rename : src/game/ScriptMgr.cpp => src/server/game/ScriptMgr.cpp rename : src/game/ScriptMgr.h => src/server/game/ScriptMgr.h rename : src/game/ScriptSystem.cpp => src/server/game/ScriptSystem.cpp rename : src/game/ScriptSystem.h => src/server/game/ScriptSystem.h rename : src/game/ScriptedCreature.cpp => src/server/game/ScriptedCreature.cpp rename : src/game/ScriptedCreature.h => src/server/game/ScriptedCreature.h rename : src/game/ScriptedEscortAI.cpp => src/server/game/ScriptedEscortAI.cpp rename : src/game/ScriptedEscortAI.h => src/server/game/ScriptedEscortAI.h rename : src/game/ScriptedFollowerAI.cpp => src/server/game/ScriptedFollowerAI.cpp rename : src/game/ScriptedFollowerAI.h => src/server/game/ScriptedFollowerAI.h rename : src/game/ScriptedGossip.h => src/server/game/ScriptedGossip.h rename : src/game/ScriptedGuardAI.cpp => src/server/game/ScriptedGuardAI.cpp rename : src/game/ScriptedGuardAI.h => src/server/game/ScriptedGuardAI.h rename : src/game/ScriptedInstance.h => src/server/game/ScriptedInstance.h rename : src/game/ScriptedPch.cpp => src/server/game/ScriptedPch.cpp rename : src/game/ScriptedPch.h => src/server/game/ScriptedPch.h rename : src/game/ScriptedSimpleAI.cpp => src/server/game/ScriptedSimpleAI.cpp rename : src/game/ScriptedSimpleAI.h => src/server/game/ScriptedSimpleAI.h rename : src/game/ScriptedSmartAI.cpp => src/server/game/ScriptedSmartAI.cpp rename : src/game/ScriptedSmartAI.h => src/server/game/ScriptedSmartAI.h rename : src/game/SharedDefines.h => src/server/game/SharedDefines.h rename : src/game/SkillDiscovery.cpp => src/server/game/SkillDiscovery.cpp rename : src/game/SkillDiscovery.h => src/server/game/SkillDiscovery.h rename : src/game/SkillExtraItems.cpp => src/server/game/SkillExtraItems.cpp rename : src/game/SkillExtraItems.h => src/server/game/SkillExtraItems.h rename : src/game/SkillHandler.cpp => src/server/game/SkillHandler.cpp rename : src/game/SocialMgr.cpp => src/server/game/SocialMgr.cpp rename : src/game/SocialMgr.h => src/server/game/SocialMgr.h rename : src/game/Spell.cpp => src/server/game/Spell.cpp rename : src/game/Spell.h => src/server/game/Spell.h rename : src/game/SpellAuraDefines.h => src/server/game/SpellAuraDefines.h rename : src/game/SpellAuraEffects.cpp => src/server/game/SpellAuraEffects.cpp rename : src/game/SpellAuraEffects.h => src/server/game/SpellAuraEffects.h rename : src/game/SpellAuras.cpp => src/server/game/SpellAuras.cpp rename : src/game/SpellAuras.h => src/server/game/SpellAuras.h rename : src/game/SpellEffects.cpp => src/server/game/SpellEffects.cpp rename : src/game/SpellHandler.cpp => src/server/game/SpellHandler.cpp rename : src/game/SpellMgr.cpp => src/server/game/SpellMgr.cpp rename : src/game/SpellMgr.h => src/server/game/SpellMgr.h rename : src/game/StatSystem.cpp => src/server/game/StatSystem.cpp rename : src/game/TargetedMovementGenerator.cpp => src/server/game/TargetedMovementGenerator.cpp rename : src/game/TargetedMovementGenerator.h => src/server/game/TargetedMovementGenerator.h rename : src/game/TaxiHandler.cpp => src/server/game/TaxiHandler.cpp rename : src/game/TemporarySummon.cpp => src/server/game/TemporarySummon.cpp rename : src/game/TemporarySummon.h => src/server/game/TemporarySummon.h rename : src/game/ThreatManager.cpp => src/server/game/ThreatManager.cpp rename : src/game/ThreatManager.h => src/server/game/ThreatManager.h rename : src/game/TicketHandler.cpp => src/server/game/TicketHandler.cpp rename : src/game/TimeMgr.cpp => src/server/game/TimeMgr.cpp rename : src/game/TimeMgr.h => src/server/game/TimeMgr.h rename : src/game/Tools.cpp => src/server/game/Tools.cpp rename : src/game/Tools.h => src/server/game/Tools.h rename : src/game/Totem.cpp => src/server/game/Totem.cpp rename : src/game/Totem.h => src/server/game/Totem.h rename : src/game/TotemAI.cpp => src/server/game/TotemAI.cpp rename : src/game/TotemAI.h => src/server/game/TotemAI.h rename : src/game/TradeHandler.cpp => src/server/game/TradeHandler.cpp rename : src/game/Transports.cpp => src/server/game/Transports.cpp rename : src/game/Transports.h => src/server/game/Transports.h rename : src/game/Traveller.h => src/server/game/Traveller.h rename : src/game/Unit.cpp => src/server/game/Unit.cpp rename : src/game/Unit.h => src/server/game/Unit.h rename : src/game/UnitAI.cpp => src/server/game/UnitAI.cpp rename : src/game/UnitAI.h => src/server/game/UnitAI.h rename : src/game/UnitEvents.h => src/server/game/UnitEvents.h rename : src/game/UpdateData.cpp => src/server/game/UpdateData.cpp rename : src/game/UpdateData.h => src/server/game/UpdateData.h rename : src/game/UpdateFields.h => src/server/game/UpdateFields.h rename : src/game/UpdateMask.h => src/server/game/UpdateMask.h rename : src/game/Vehicle.cpp => src/server/game/Vehicle.cpp rename : src/game/Vehicle.h => src/server/game/Vehicle.h rename : src/game/VoiceChatHandler.cpp => src/server/game/VoiceChatHandler.cpp rename : src/game/WaypointManager.cpp => src/server/game/WaypointManager.cpp rename : src/game/WaypointManager.h => src/server/game/WaypointManager.h rename : src/game/WaypointMovementGenerator.cpp => src/server/game/WaypointMovementGenerator.cpp rename : src/game/WaypointMovementGenerator.h => src/server/game/WaypointMovementGenerator.h rename : src/game/Weather.cpp => src/server/game/Weather.cpp rename : src/game/Weather.h => src/server/game/Weather.h rename : src/game/World.cpp => src/server/game/World.cpp rename : src/game/World.h => src/server/game/World.h rename : src/game/WorldLog.cpp => src/server/game/WorldLog.cpp rename : src/game/WorldLog.h => src/server/game/WorldLog.h rename : src/game/WorldSession.cpp => src/server/game/WorldSession.cpp rename : src/game/WorldSession.h => src/server/game/WorldSession.h rename : src/game/WorldSocket.cpp => src/server/game/WorldSocket.cpp rename : src/game/WorldSocket.h => src/server/game/WorldSocket.h rename : src/game/WorldSocketMgr.cpp => src/server/game/WorldSocketMgr.cpp rename : src/game/WorldSocketMgr.h => src/server/game/WorldSocketMgr.h rename : src/game/ZoneScript.h => src/server/game/ZoneScript.h rename : src/game/pchdef.cpp => src/server/game/pchdef.cpp rename : src/game/pchdef.h => src/server/game/pchdef.h rename : src/game/pchlinux.cpp => src/server/game/pchlinux.cpp rename : src/game/pchlinux.h => src/server/game/pchlinux.h rename : src/scripts/CMakeLists.txt => src/server/scripts/CMakeLists.txt rename : src/scripts/custom/custom_example.cpp => src/server/scripts/custom/custom_example.cpp rename : src/scripts/custom/custom_gossip_codebox.cpp => src/server/scripts/custom/custom_gossip_codebox.cpp rename : src/scripts/custom/npc_acherus_taxi.cpp => src/server/scripts/custom/npc_acherus_taxi.cpp rename : src/scripts/custom/npc_wyrmresttempel_taxi.cpp => src/server/scripts/custom/npc_wyrmresttempel_taxi.cpp rename : src/scripts/custom/on_events.cpp => src/server/scripts/custom/on_events.cpp rename : src/scripts/custom/test.cpp => src/server/scripts/custom/test.cpp rename : src/scripts/eastern_kingdoms/alterac_mountains.cpp => src/server/scripts/eastern_kingdoms/alterac_mountains.cpp rename : src/scripts/eastern_kingdoms/alterac_valley/alterac_valley.cpp => src/server/scripts/eastern_kingdoms/alterac_valley/alterac_valley.cpp rename : src/scripts/eastern_kingdoms/alterac_valley/boss_balinda.cpp => src/server/scripts/eastern_kingdoms/alterac_valley/boss_balinda.cpp rename : src/scripts/eastern_kingdoms/alterac_valley/boss_drekthar.cpp => src/server/scripts/eastern_kingdoms/alterac_valley/boss_drekthar.cpp rename : src/scripts/eastern_kingdoms/alterac_valley/boss_galvangar.cpp => src/server/scripts/eastern_kingdoms/alterac_valley/boss_galvangar.cpp rename : src/scripts/eastern_kingdoms/alterac_valley/boss_vanndar.cpp => src/server/scripts/eastern_kingdoms/alterac_valley/boss_vanndar.cpp rename : src/scripts/eastern_kingdoms/arathi_highlands.cpp => src/server/scripts/eastern_kingdoms/arathi_highlands.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.h => src/server/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.h rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_ambassador_flamelash.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_ambassador_flamelash.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_anubshiah.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_anubshiah.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_emperor_dagran_thaurissan.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_emperor_dagran_thaurissan.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_general_angerforge.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_general_angerforge.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_gorosh_the_dervish.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_gorosh_the_dervish.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_grizzle.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_grizzle.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_high_interrogator_gerstahn.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_high_interrogator_gerstahn.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_magmus.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_magmus.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_moira_bronzebeard.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_moira_bronzebeard.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_tomb_of_seven.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_tomb_of_seven.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/instance_blackrock_depths.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/instance_blackrock_depths.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/blackrock_spire.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/blackrock_spire.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/blackrock_spire.h => src/server/scripts/eastern_kingdoms/blackrock_spire/blackrock_spire.h rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_drakkisath.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_drakkisath.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_gyth.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_gyth.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_halycon.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_halycon.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_highlord_omokk.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_highlord_omokk.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_mother_smolderweb.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_mother_smolderweb.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_overlord_wyrmthalak.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_overlord_wyrmthalak.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_pyroguard_emberseer.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_pyroguard_emberseer.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_quartermaster_zigris.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_quartermaster_zigris.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_rend_blackhand.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_rend_blackhand.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_shadow_hunter_voshgajin.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_shadow_hunter_voshgajin.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_the_beast.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_the_beast.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_warmaster_voone.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_warmaster_voone.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/instance_blackrock_spire.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/instance_blackrock_spire.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/boss_broodlord_lashlayer.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/boss_broodlord_lashlayer.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/boss_chromaggus.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/boss_chromaggus.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/boss_ebonroc.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/boss_ebonroc.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/boss_firemaw.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/boss_firemaw.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/boss_flamegor.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/boss_flamegor.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/boss_nefarian.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/boss_nefarian.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/boss_razorgore.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/boss_razorgore.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/boss_vaelastrasz.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/boss_vaelastrasz.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/boss_victor_nefarius.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/boss_victor_nefarius.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/instance_blackwing_lair.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/instance_blackwing_lair.cpp rename : src/scripts/eastern_kingdoms/blasted_lands.cpp => src/server/scripts/eastern_kingdoms/blasted_lands.cpp rename : src/scripts/eastern_kingdoms/boss_kruul.cpp => src/server/scripts/eastern_kingdoms/boss_kruul.cpp rename : src/scripts/eastern_kingdoms/burning_steppes.cpp => src/server/scripts/eastern_kingdoms/burning_steppes.cpp rename : src/scripts/eastern_kingdoms/deadmines/boss_mr_smite.cpp => src/server/scripts/eastern_kingdoms/deadmines/boss_mr_smite.cpp rename : src/scripts/eastern_kingdoms/deadmines/deadmines.cpp => src/server/scripts/eastern_kingdoms/deadmines/deadmines.cpp rename : src/scripts/eastern_kingdoms/deadmines/deadmines.h => src/server/scripts/eastern_kingdoms/deadmines/deadmines.h rename : src/scripts/eastern_kingdoms/deadmines/instance_deadmines.cpp => src/server/scripts/eastern_kingdoms/deadmines/instance_deadmines.cpp rename : src/scripts/eastern_kingdoms/dun_morogh.cpp => src/server/scripts/eastern_kingdoms/dun_morogh.cpp rename : src/scripts/eastern_kingdoms/duskwood.cpp => src/server/scripts/eastern_kingdoms/duskwood.cpp rename : src/scripts/eastern_kingdoms/eastern_plaguelands.cpp => src/server/scripts/eastern_kingdoms/eastern_plaguelands.cpp rename : src/scripts/eastern_kingdoms/elwynn_forest.cpp => src/server/scripts/eastern_kingdoms/elwynn_forest.cpp rename : src/scripts/eastern_kingdoms/eversong_woods.cpp => src/server/scripts/eastern_kingdoms/eversong_woods.cpp rename : src/scripts/eastern_kingdoms/ghostlands.cpp => src/server/scripts/eastern_kingdoms/ghostlands.cpp rename : src/scripts/eastern_kingdoms/gnomeregan/gnomeregan.cpp => src/server/scripts/eastern_kingdoms/gnomeregan/gnomeregan.cpp rename : src/scripts/eastern_kingdoms/gnomeregan/gnomeregan.h => src/server/scripts/eastern_kingdoms/gnomeregan/gnomeregan.h rename : src/scripts/eastern_kingdoms/gnomeregan/instance_gnomeregan.cpp => src/server/scripts/eastern_kingdoms/gnomeregan/instance_gnomeregan.cpp rename : src/scripts/eastern_kingdoms/hinterlands.cpp => src/server/scripts/eastern_kingdoms/hinterlands.cpp rename : src/scripts/eastern_kingdoms/ironforge.cpp => src/server/scripts/eastern_kingdoms/ironforge.cpp rename : src/scripts/eastern_kingdoms/isle_of_queldanas.cpp => src/server/scripts/eastern_kingdoms/isle_of_queldanas.cpp rename : src/scripts/eastern_kingdoms/karazhan/boss_curator.cpp => src/server/scripts/eastern_kingdoms/karazhan/boss_curator.cpp rename : src/scripts/eastern_kingdoms/karazhan/boss_maiden_of_virtue.cpp => src/server/scripts/eastern_kingdoms/karazhan/boss_maiden_of_virtue.cpp rename : src/scripts/eastern_kingdoms/karazhan/boss_midnight.cpp => src/server/scripts/eastern_kingdoms/karazhan/boss_midnight.cpp rename : src/scripts/eastern_kingdoms/karazhan/boss_moroes.cpp => src/server/scripts/eastern_kingdoms/karazhan/boss_moroes.cpp rename : src/scripts/eastern_kingdoms/karazhan/boss_netherspite.cpp => src/server/scripts/eastern_kingdoms/karazhan/boss_netherspite.cpp rename : src/scripts/eastern_kingdoms/karazhan/boss_nightbane.cpp => src/server/scripts/eastern_kingdoms/karazhan/boss_nightbane.cpp rename : src/scripts/eastern_kingdoms/karazhan/boss_prince_malchezaar.cpp => src/server/scripts/eastern_kingdoms/karazhan/boss_prince_malchezaar.cpp rename : src/scripts/eastern_kingdoms/karazhan/boss_shade_of_aran.cpp => src/server/scripts/eastern_kingdoms/karazhan/boss_shade_of_aran.cpp rename : src/scripts/eastern_kingdoms/karazhan/boss_terestian_illhoof.cpp => src/server/scripts/eastern_kingdoms/karazhan/boss_terestian_illhoof.cpp rename : src/scripts/eastern_kingdoms/karazhan/bosses_opera.cpp => src/server/scripts/eastern_kingdoms/karazhan/bosses_opera.cpp rename : src/scripts/eastern_kingdoms/karazhan/instance_karazhan.cpp => src/server/scripts/eastern_kingdoms/karazhan/instance_karazhan.cpp rename : src/scripts/eastern_kingdoms/karazhan/karazhan.cpp => src/server/scripts/eastern_kingdoms/karazhan/karazhan.cpp rename : src/scripts/eastern_kingdoms/karazhan/karazhan.h => src/server/scripts/eastern_kingdoms/karazhan/karazhan.h rename : src/scripts/eastern_kingdoms/loch_modan.cpp => src/server/scripts/eastern_kingdoms/loch_modan.cpp rename : src/scripts/eastern_kingdoms/magisters_terrace/boss_felblood_kaelthas.cpp => src/server/scripts/eastern_kingdoms/magisters_terrace/boss_felblood_kaelthas.cpp rename : src/scripts/eastern_kingdoms/magisters_terrace/boss_priestess_delrissa.cpp => src/server/scripts/eastern_kingdoms/magisters_terrace/boss_priestess_delrissa.cpp rename : src/scripts/eastern_kingdoms/magisters_terrace/boss_selin_fireheart.cpp => src/server/scripts/eastern_kingdoms/magisters_terrace/boss_selin_fireheart.cpp rename : src/scripts/eastern_kingdoms/magisters_terrace/boss_vexallus.cpp => src/server/scripts/eastern_kingdoms/magisters_terrace/boss_vexallus.cpp rename : src/scripts/eastern_kingdoms/magisters_terrace/instance_magisters_terrace.cpp => src/server/scripts/eastern_kingdoms/magisters_terrace/instance_magisters_terrace.cpp rename : src/scripts/eastern_kingdoms/magisters_terrace/magisters_terrace.cpp => src/server/scripts/eastern_kingdoms/magisters_terrace/magisters_terrace.cpp rename : src/scripts/eastern_kingdoms/magisters_terrace/magisters_terrace.h => src/server/scripts/eastern_kingdoms/magisters_terrace/magisters_terrace.h rename : src/scripts/eastern_kingdoms/molten_core/boss_baron_geddon.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_baron_geddon.cpp rename : src/scripts/eastern_kingdoms/molten_core/boss_garr.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_garr.cpp rename : src/scripts/eastern_kingdoms/molten_core/boss_gehennas.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_gehennas.cpp rename : src/scripts/eastern_kingdoms/molten_core/boss_golemagg.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_golemagg.cpp rename : src/scripts/eastern_kingdoms/molten_core/boss_lucifron.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_lucifron.cpp rename : src/scripts/eastern_kingdoms/molten_core/boss_magmadar.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_magmadar.cpp rename : src/scripts/eastern_kingdoms/molten_core/boss_majordomo_executus.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_majordomo_executus.cpp rename : src/scripts/eastern_kingdoms/molten_core/boss_ragnaros.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_ragnaros.cpp rename : src/scripts/eastern_kingdoms/molten_core/boss_shazzrah.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_shazzrah.cpp rename : src/scripts/eastern_kingdoms/molten_core/boss_sulfuron_harbinger.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_sulfuron_harbinger.cpp rename : src/scripts/eastern_kingdoms/molten_core/instance_molten_core.cpp => src/server/scripts/eastern_kingdoms/molten_core/instance_molten_core.cpp rename : src/scripts/eastern_kingdoms/molten_core/molten_core.cpp => src/server/scripts/eastern_kingdoms/molten_core/molten_core.cpp rename : src/scripts/eastern_kingdoms/molten_core/molten_core.h => src/server/scripts/eastern_kingdoms/molten_core/molten_core.h rename : src/scripts/eastern_kingdoms/redridge_mountains.cpp => src/server/scripts/eastern_kingdoms/redridge_mountains.cpp rename : src/scripts/eastern_kingdoms/scarlet_enclave/chapter1.cpp => src/server/scripts/eastern_kingdoms/scarlet_enclave/chapter1.cpp rename : src/scripts/eastern_kingdoms/scarlet_enclave/chapter2.cpp => src/server/scripts/eastern_kingdoms/scarlet_enclave/chapter2.cpp rename : src/scripts/eastern_kingdoms/scarlet_enclave/chapter5.cpp => src/server/scripts/eastern_kingdoms/scarlet_enclave/chapter5.cpp rename : src/scripts/eastern_kingdoms/scarlet_enclave/the_scarlet_enclave.cpp => src/server/scripts/eastern_kingdoms/scarlet_enclave/the_scarlet_enclave.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_arcanist_doan.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_arcanist_doan.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_azshir_the_sleepless.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_azshir_the_sleepless.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_bloodmage_thalnos.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_bloodmage_thalnos.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_headless_horseman.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_headless_horseman.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_herod.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_herod.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_high_inquisitor_fairbanks.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_high_inquisitor_fairbanks.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_houndmaster_loksey.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_houndmaster_loksey.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_interrogator_vishas.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_interrogator_vishas.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_mograine_and_whitemane.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_mograine_and_whitemane.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_scorn.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_scorn.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/instance_scarlet_monastery.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/instance_scarlet_monastery.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/scarlet_monastery.h => src/server/scripts/eastern_kingdoms/scarlet_monastery/scarlet_monastery.h rename : src/scripts/eastern_kingdoms/scholomance/boss_darkmaster_gandling.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_darkmaster_gandling.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_death_knight_darkreaver.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_death_knight_darkreaver.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_doctor_theolen_krastinov.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_doctor_theolen_krastinov.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_illucia_barov.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_illucia_barov.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_instructor_malicia.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_instructor_malicia.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_jandice_barov.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_jandice_barov.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_kormok.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_kormok.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_lord_alexei_barov.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_lord_alexei_barov.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_lorekeeper_polkelt.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_lorekeeper_polkelt.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_ras_frostwhisper.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_ras_frostwhisper.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_the_ravenian.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_the_ravenian.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_vectus.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_vectus.cpp rename : src/scripts/eastern_kingdoms/scholomance/instance_scholomance.cpp => src/server/scripts/eastern_kingdoms/scholomance/instance_scholomance.cpp rename : src/scripts/eastern_kingdoms/scholomance/scholomance.h => src/server/scripts/eastern_kingdoms/scholomance/scholomance.h rename : src/scripts/eastern_kingdoms/searing_gorge.cpp => src/server/scripts/eastern_kingdoms/searing_gorge.cpp rename : src/scripts/eastern_kingdoms/shadowfang_keep/instance_shadowfang_keep.cpp => src/server/scripts/eastern_kingdoms/shadowfang_keep/instance_shadowfang_keep.cpp rename : src/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.cpp => src/server/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.cpp rename : src/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.h => src/server/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.h rename : src/scripts/eastern_kingdoms/silvermoon_city.cpp => src/server/scripts/eastern_kingdoms/silvermoon_city.cpp rename : src/scripts/eastern_kingdoms/silverpine_forest.cpp => src/server/scripts/eastern_kingdoms/silverpine_forest.cpp rename : src/scripts/eastern_kingdoms/stormwind_city.cpp => src/server/scripts/eastern_kingdoms/stormwind_city.cpp rename : src/scripts/eastern_kingdoms/stranglethorn_vale.cpp => src/server/scripts/eastern_kingdoms/stranglethorn_vale.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_baron_rivendare.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_baron_rivendare.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_baroness_anastari.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_baroness_anastari.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_cannon_master_willey.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_cannon_master_willey.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_dathrohan_balnazzar.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_dathrohan_balnazzar.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_magistrate_barthilas.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_magistrate_barthilas.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_maleki_the_pallid.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_maleki_the_pallid.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_nerubenkan.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_nerubenkan.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_order_of_silver_hand.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_order_of_silver_hand.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_postmaster_malown.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_postmaster_malown.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_ramstein_the_gorger.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_ramstein_the_gorger.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_timmy_the_cruel.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_timmy_the_cruel.cpp rename : src/scripts/eastern_kingdoms/stratholme/instance_stratholme.cpp => src/server/scripts/eastern_kingdoms/stratholme/instance_stratholme.cpp rename : src/scripts/eastern_kingdoms/stratholme/stratholme.cpp => src/server/scripts/eastern_kingdoms/stratholme/stratholme.cpp rename : src/scripts/eastern_kingdoms/stratholme/stratholme.h => src/server/scripts/eastern_kingdoms/stratholme/stratholme.h rename : src/scripts/eastern_kingdoms/sunken_temple/instance_sunken_temple.cpp => src/server/scripts/eastern_kingdoms/sunken_temple/instance_sunken_temple.cpp rename : src/scripts/eastern_kingdoms/sunken_temple/sunken_temple.cpp => src/server/scripts/eastern_kingdoms/sunken_temple/sunken_temple.cpp rename : src/scripts/eastern_kingdoms/sunken_temple/sunken_temple.h => src/server/scripts/eastern_kingdoms/sunken_temple/sunken_temple.h rename : src/scripts/eastern_kingdoms/sunwell_plateau/boss_brutallus.cpp => src/server/scripts/eastern_kingdoms/sunwell_plateau/boss_brutallus.cpp rename : src/scripts/eastern_kingdoms/sunwell_plateau/boss_eredar_twins.cpp => src/server/scripts/eastern_kingdoms/sunwell_plateau/boss_eredar_twins.cpp rename : src/scripts/eastern_kingdoms/sunwell_plateau/boss_felmyst.cpp => src/server/scripts/eastern_kingdoms/sunwell_plateau/boss_felmyst.cpp rename : src/scripts/eastern_kingdoms/sunwell_plateau/boss_kalecgos.cpp => src/server/scripts/eastern_kingdoms/sunwell_plateau/boss_kalecgos.cpp rename : src/scripts/eastern_kingdoms/sunwell_plateau/boss_kiljaeden.cpp => src/server/scripts/eastern_kingdoms/sunwell_plateau/boss_kiljaeden.cpp rename : src/scripts/eastern_kingdoms/sunwell_plateau/boss_muru.cpp => src/server/scripts/eastern_kingdoms/sunwell_plateau/boss_muru.cpp rename : src/scripts/eastern_kingdoms/sunwell_plateau/instance_sunwell_plateau.cpp => src/server/scripts/eastern_kingdoms/sunwell_plateau/instance_sunwell_plateau.cpp rename : src/scripts/eastern_kingdoms/sunwell_plateau/sunwell_plateau.cpp => src/server/scripts/eastern_kingdoms/sunwell_plateau/sunwell_plateau.cpp rename : src/scripts/eastern_kingdoms/sunwell_plateau/sunwell_plateau.h => src/server/scripts/eastern_kingdoms/sunwell_plateau/sunwell_plateau.h rename : src/scripts/eastern_kingdoms/tirisfal_glades.cpp => src/server/scripts/eastern_kingdoms/tirisfal_glades.cpp rename : src/scripts/eastern_kingdoms/uldaman/boss_archaedas.cpp => src/server/scripts/eastern_kingdoms/uldaman/boss_archaedas.cpp rename : src/scripts/eastern_kingdoms/uldaman/boss_ironaya.cpp => src/server/scripts/eastern_kingdoms/uldaman/boss_ironaya.cpp rename : src/scripts/eastern_kingdoms/uldaman/instance_uldaman.cpp => src/server/scripts/eastern_kingdoms/uldaman/instance_uldaman.cpp rename : src/scripts/eastern_kingdoms/uldaman/uldaman.cpp => src/server/scripts/eastern_kingdoms/uldaman/uldaman.cpp rename : src/scripts/eastern_kingdoms/undercity.cpp => src/server/scripts/eastern_kingdoms/undercity.cpp rename : src/scripts/eastern_kingdoms/western_plaguelands.cpp => src/server/scripts/eastern_kingdoms/western_plaguelands.cpp rename : src/scripts/eastern_kingdoms/westfall.cpp => src/server/scripts/eastern_kingdoms/westfall.cpp rename : src/scripts/eastern_kingdoms/wetlands.cpp => src/server/scripts/eastern_kingdoms/wetlands.cpp rename : src/scripts/eastern_kingdoms/zulaman/boss_akilzon.cpp => src/server/scripts/eastern_kingdoms/zulaman/boss_akilzon.cpp rename : src/scripts/eastern_kingdoms/zulaman/boss_halazzi.cpp => src/server/scripts/eastern_kingdoms/zulaman/boss_halazzi.cpp rename : src/scripts/eastern_kingdoms/zulaman/boss_hexlord.cpp => src/server/scripts/eastern_kingdoms/zulaman/boss_hexlord.cpp rename : src/scripts/eastern_kingdoms/zulaman/boss_janalai.cpp => src/server/scripts/eastern_kingdoms/zulaman/boss_janalai.cpp rename : src/scripts/eastern_kingdoms/zulaman/boss_nalorakk.cpp => src/server/scripts/eastern_kingdoms/zulaman/boss_nalorakk.cpp rename : src/scripts/eastern_kingdoms/zulaman/boss_zuljin.cpp => src/server/scripts/eastern_kingdoms/zulaman/boss_zuljin.cpp rename : src/scripts/eastern_kingdoms/zulaman/instance_zulaman.cpp => src/server/scripts/eastern_kingdoms/zulaman/instance_zulaman.cpp rename : src/scripts/eastern_kingdoms/zulaman/zulaman.cpp => src/server/scripts/eastern_kingdoms/zulaman/zulaman.cpp rename : src/scripts/eastern_kingdoms/zulaman/zulaman.h => src/server/scripts/eastern_kingdoms/zulaman/zulaman.h rename : src/scripts/eastern_kingdoms/zulgurub/boss_arlokk.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_arlokk.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_gahzranka.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_gahzranka.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_grilek.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_grilek.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_hakkar.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_hakkar.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_hazzarah.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_hazzarah.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_jeklik.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_jeklik.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_jindo.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_jindo.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_mandokir.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_mandokir.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_marli.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_marli.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_renataki.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_renataki.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_thekal.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_thekal.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_venoxis.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_venoxis.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_wushoolay.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_wushoolay.cpp rename : src/scripts/eastern_kingdoms/zulgurub/instance_zulgurub.cpp => src/server/scripts/eastern_kingdoms/zulgurub/instance_zulgurub.cpp rename : src/scripts/eastern_kingdoms/zulgurub/zulgurub.h => src/server/scripts/eastern_kingdoms/zulgurub/zulgurub.h rename : src/scripts/examples/example_creature.cpp => src/server/scripts/examples/example_creature.cpp rename : src/scripts/examples/example_escort.cpp => src/server/scripts/examples/example_escort.cpp rename : src/scripts/examples/example_gossip_codebox.cpp => src/server/scripts/examples/example_gossip_codebox.cpp rename : src/scripts/examples/example_misc.cpp => src/server/scripts/examples/example_misc.cpp rename : src/scripts/kalimdor/ashenvale.cpp => src/server/scripts/kalimdor/ashenvale.cpp rename : src/scripts/kalimdor/azshara.cpp => src/server/scripts/kalimdor/azshara.cpp rename : src/scripts/kalimdor/azuremyst_isle.cpp => src/server/scripts/kalimdor/azuremyst_isle.cpp rename : src/scripts/kalimdor/blackfathom_depths/blackfathom_deeps.cpp => src/server/scripts/kalimdor/blackfathom_depths/blackfathom_deeps.cpp rename : src/scripts/kalimdor/blackfathom_depths/blackfathom_deeps.h => src/server/scripts/kalimdor/blackfathom_depths/blackfathom_deeps.h rename : src/scripts/kalimdor/blackfathom_depths/boss_aku_mai.cpp => src/server/scripts/kalimdor/blackfathom_depths/boss_aku_mai.cpp rename : src/scripts/kalimdor/blackfathom_depths/boss_gelihast.cpp => src/server/scripts/kalimdor/blackfathom_depths/boss_gelihast.cpp rename : src/scripts/kalimdor/blackfathom_depths/boss_kelris.cpp => src/server/scripts/kalimdor/blackfathom_depths/boss_kelris.cpp rename : src/scripts/kalimdor/blackfathom_depths/instance_blackfathom_deeps.cpp => src/server/scripts/kalimdor/blackfathom_depths/instance_blackfathom_deeps.cpp rename : src/scripts/kalimdor/bloodmyst_isle.cpp => src/server/scripts/kalimdor/bloodmyst_isle.cpp rename : src/scripts/kalimdor/boss_azuregos.cpp => src/server/scripts/kalimdor/boss_azuregos.cpp rename : src/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_epoch.cpp => src/server/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_epoch.cpp rename : src/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_infinite.cpp => src/server/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_infinite.cpp rename : src/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_mal_ganis.cpp => src/server/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_mal_ganis.cpp rename : src/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_meathook.cpp => src/server/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_meathook.cpp rename : src/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_salramm.cpp => src/server/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_salramm.cpp rename : src/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.cpp => src/server/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.cpp rename : src/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.h => src/server/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.h rename : src/scripts/kalimdor/caverns_of_time/culling_of_stratholme/instance_culling_of_stratholme.cpp => src/server/scripts/kalimdor/caverns_of_time/culling_of_stratholme/instance_culling_of_stratholme.cpp rename : src/scripts/kalimdor/caverns_of_time/dark_portal/boss_aeonus.cpp => src/server/scripts/kalimdor/caverns_of_time/dark_portal/boss_aeonus.cpp rename : src/scripts/kalimdor/caverns_of_time/dark_portal/boss_chrono_lord_deja.cpp => src/server/scripts/kalimdor/caverns_of_time/dark_portal/boss_chrono_lord_deja.cpp rename : src/scripts/kalimdor/caverns_of_time/dark_portal/boss_temporus.cpp => src/server/scripts/kalimdor/caverns_of_time/dark_portal/boss_temporus.cpp rename : src/scripts/kalimdor/caverns_of_time/dark_portal/dark_portal.cpp => src/server/scripts/kalimdor/caverns_of_time/dark_portal/dark_portal.cpp rename : src/scripts/kalimdor/caverns_of_time/dark_portal/dark_portal.h => src/server/scripts/kalimdor/caverns_of_time/dark_portal/dark_portal.h rename : src/scripts/kalimdor/caverns_of_time/dark_portal/instance_dark_portal.cpp => src/server/scripts/kalimdor/caverns_of_time/dark_portal/instance_dark_portal.cpp rename : src/scripts/kalimdor/caverns_of_time/hyjal/boss_anetheron.cpp => src/server/scripts/kalimdor/caverns_of_time/hyjal/boss_anetheron.cpp rename : src/scripts/kalimdor/caverns_of_time/hyjal/boss_archimonde.cpp => src/server/scripts/kalimdor/caverns_of_time/hyjal/boss_archimonde.cpp rename : src/scripts/kalimdor/caverns_of_time/hyjal/boss_azgalor.cpp => src/server/scripts/kalimdor/caverns_of_time/hyjal/boss_azgalor.cpp rename : src/scripts/kalimdor/caverns_of_time/hyjal/boss_kazrogal.cpp => src/server/scripts/kalimdor/caverns_of_time/hyjal/boss_kazrogal.cpp rename : src/scripts/kalimdor/caverns_of_time/hyjal/boss_rage_winterchill.cpp => src/server/scripts/kalimdor/caverns_of_time/hyjal/boss_rage_winterchill.cpp rename : src/scripts/kalimdor/caverns_of_time/hyjal/hyjal.cpp => src/server/scripts/kalimdor/caverns_of_time/hyjal/hyjal.cpp rename : src/scripts/kalimdor/caverns_of_time/hyjal/hyjal.h => src/server/scripts/kalimdor/caverns_of_time/hyjal/hyjal.h rename : src/scripts/kalimdor/caverns_of_time/hyjal/hyjalAI.cpp => src/server/scripts/kalimdor/caverns_of_time/hyjal/hyjalAI.cpp rename : src/scripts/kalimdor/caverns_of_time/hyjal/hyjalAI.h => src/server/scripts/kalimdor/caverns_of_time/hyjal/hyjalAI.h rename : src/scripts/kalimdor/caverns_of_time/hyjal/hyjal_trash.cpp => src/server/scripts/kalimdor/caverns_of_time/hyjal/hyjal_trash.cpp rename : src/scripts/kalimdor/caverns_of_time/hyjal/hyjal_trash.h => src/server/scripts/kalimdor/caverns_of_time/hyjal/hyjal_trash.h rename : src/scripts/kalimdor/caverns_of_time/hyjal/instance_hyjal.cpp => src/server/scripts/kalimdor/caverns_of_time/hyjal/instance_hyjal.cpp rename : src/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_captain_skarloc.cpp => src/server/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_captain_skarloc.cpp rename : src/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_epoch_hunter.cpp => src/server/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_epoch_hunter.cpp rename : src/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_leutenant_drake.cpp => src/server/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_leutenant_drake.cpp rename : src/scripts/kalimdor/caverns_of_time/old_hillsbrad/instance_old_hillsbrad.cpp => src/server/scripts/kalimdor/caverns_of_time/old_hillsbrad/instance_old_hillsbrad.cpp rename : src/scripts/kalimdor/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp => src/server/scripts/kalimdor/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp rename : src/scripts/kalimdor/caverns_of_time/old_hillsbrad/old_hillsbrad.h => src/server/scripts/kalimdor/caverns_of_time/old_hillsbrad/old_hillsbrad.h rename : src/scripts/kalimdor/darkshore.cpp => src/server/scripts/kalimdor/darkshore.cpp rename : src/scripts/kalimdor/desolace.cpp => src/server/scripts/kalimdor/desolace.cpp rename : src/scripts/kalimdor/durotar.cpp => src/server/scripts/kalimdor/durotar.cpp rename : src/scripts/kalimdor/dustwallow_marsh.cpp => src/server/scripts/kalimdor/dustwallow_marsh.cpp rename : src/scripts/kalimdor/felwood.cpp => src/server/scripts/kalimdor/felwood.cpp rename : src/scripts/kalimdor/feralas.cpp => src/server/scripts/kalimdor/feralas.cpp rename : src/scripts/kalimdor/maraudon/boss_celebras_the_cursed.cpp => src/server/scripts/kalimdor/maraudon/boss_celebras_the_cursed.cpp rename : src/scripts/kalimdor/maraudon/boss_landslide.cpp => src/server/scripts/kalimdor/maraudon/boss_landslide.cpp rename : src/scripts/kalimdor/maraudon/boss_noxxion.cpp => src/server/scripts/kalimdor/maraudon/boss_noxxion.cpp rename : src/scripts/kalimdor/maraudon/boss_princess_theradras.cpp => src/server/scripts/kalimdor/maraudon/boss_princess_theradras.cpp rename : src/scripts/kalimdor/moonglade.cpp => src/server/scripts/kalimdor/moonglade.cpp rename : src/scripts/kalimdor/mulgore.cpp => src/server/scripts/kalimdor/mulgore.cpp rename : src/scripts/kalimdor/onyxias_lair/boss_onyxia.cpp => src/server/scripts/kalimdor/onyxias_lair/boss_onyxia.cpp rename : src/scripts/kalimdor/onyxias_lair/instance_onyxias_lair.cpp => src/server/scripts/kalimdor/onyxias_lair/instance_onyxias_lair.cpp rename : src/scripts/kalimdor/onyxias_lair/onyxias_lair.h => src/server/scripts/kalimdor/onyxias_lair/onyxias_lair.h rename : src/scripts/kalimdor/orgrimmar.cpp => src/server/scripts/kalimdor/orgrimmar.cpp rename : src/scripts/kalimdor/razorfen_downs/boss_amnennar_the_coldbringer.cpp => src/server/scripts/kalimdor/razorfen_downs/boss_amnennar_the_coldbringer.cpp rename : src/scripts/kalimdor/razorfen_downs/instance_razorfen_downs.cpp => src/server/scripts/kalimdor/razorfen_downs/instance_razorfen_downs.cpp rename : src/scripts/kalimdor/razorfen_downs/razorfen_downs.cpp => src/server/scripts/kalimdor/razorfen_downs/razorfen_downs.cpp rename : src/scripts/kalimdor/razorfen_downs/razorfen_downs.h => src/server/scripts/kalimdor/razorfen_downs/razorfen_downs.h rename : src/scripts/kalimdor/razorfen_kraul/instance_razorfen_kraul.cpp => src/server/scripts/kalimdor/razorfen_kraul/instance_razorfen_kraul.cpp rename : src/scripts/kalimdor/razorfen_kraul/razorfen_kraul.cpp => src/server/scripts/kalimdor/razorfen_kraul/razorfen_kraul.cpp rename : src/scripts/kalimdor/razorfen_kraul/razorfen_kraul.h => src/server/scripts/kalimdor/razorfen_kraul/razorfen_kraul.h rename : src/scripts/kalimdor/ruins_of_ahnqiraj/boss_ayamiss.cpp => src/server/scripts/kalimdor/ruins_of_ahnqiraj/boss_ayamiss.cpp rename : src/scripts/kalimdor/ruins_of_ahnqiraj/boss_buru.cpp => src/server/scripts/kalimdor/ruins_of_ahnqiraj/boss_buru.cpp rename : src/scripts/kalimdor/ruins_of_ahnqiraj/boss_kurinnaxx.cpp => src/server/scripts/kalimdor/ruins_of_ahnqiraj/boss_kurinnaxx.cpp rename : src/scripts/kalimdor/ruins_of_ahnqiraj/boss_moam.cpp => src/server/scripts/kalimdor/ruins_of_ahnqiraj/boss_moam.cpp rename : src/scripts/kalimdor/ruins_of_ahnqiraj/boss_ossirian.cpp => src/server/scripts/kalimdor/ruins_of_ahnqiraj/boss_ossirian.cpp rename : src/scripts/kalimdor/ruins_of_ahnqiraj/boss_rajaxx.cpp => src/server/scripts/kalimdor/ruins_of_ahnqiraj/boss_rajaxx.cpp rename : src/scripts/kalimdor/ruins_of_ahnqiraj/instance_ruins_of_ahnqiraj.cpp => src/server/scripts/kalimdor/ruins_of_ahnqiraj/instance_ruins_of_ahnqiraj.cpp rename : src/scripts/kalimdor/ruins_of_ahnqiraj/ruins_of_ahnqiraj.h => src/server/scripts/kalimdor/ruins_of_ahnqiraj/ruins_of_ahnqiraj.h rename : src/scripts/kalimdor/silithus.cpp => src/server/scripts/kalimdor/silithus.cpp rename : src/scripts/kalimdor/stonetalon_mountains.cpp => src/server/scripts/kalimdor/stonetalon_mountains.cpp rename : src/scripts/kalimdor/tanaris.cpp => src/server/scripts/kalimdor/tanaris.cpp rename : src/scripts/kalimdor/teldrassil.cpp => src/server/scripts/kalimdor/teldrassil.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/boss_bug_trio.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/boss_bug_trio.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/boss_cthun.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/boss_cthun.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/boss_fankriss.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/boss_fankriss.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/boss_huhuran.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/boss_huhuran.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/boss_ouro.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/boss_ouro.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/boss_sartura.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/boss_sartura.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/boss_skeram.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/boss_skeram.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/boss_twinemperors.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/boss_twinemperors.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/boss_viscidus.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/boss_viscidus.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/instance_temple_of_ahnqiraj.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/instance_temple_of_ahnqiraj.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/temple_of_ahnqiraj.h => src/server/scripts/kalimdor/temple_of_ahnqiraj/temple_of_ahnqiraj.h rename : src/scripts/kalimdor/the_barrens.cpp => src/server/scripts/kalimdor/the_barrens.cpp rename : src/scripts/kalimdor/thousand_needles.cpp => src/server/scripts/kalimdor/thousand_needles.cpp rename : src/scripts/kalimdor/thunder_bluff.cpp => src/server/scripts/kalimdor/thunder_bluff.cpp rename : src/scripts/kalimdor/ungoro_crater.cpp => src/server/scripts/kalimdor/ungoro_crater.cpp rename : src/scripts/kalimdor/wailing_caverns/instance_wailing_caverns.cpp => src/server/scripts/kalimdor/wailing_caverns/instance_wailing_caverns.cpp rename : src/scripts/kalimdor/wailing_caverns/wailing_caverns.cpp => src/server/scripts/kalimdor/wailing_caverns/wailing_caverns.cpp rename : src/scripts/kalimdor/wailing_caverns/wailing_caverns.h => src/server/scripts/kalimdor/wailing_caverns/wailing_caverns.h rename : src/scripts/kalimdor/winterspring.cpp => src/server/scripts/kalimdor/winterspring.cpp rename : src/scripts/kalimdor/zulfarrak/instance_zulfarrak.cpp => src/server/scripts/kalimdor/zulfarrak/instance_zulfarrak.cpp rename : src/scripts/kalimdor/zulfarrak/zulfarrak.cpp => src/server/scripts/kalimdor/zulfarrak/zulfarrak.cpp rename : src/scripts/northrend/azjol_nerub/ahnkahet/ahnkahet.h => src/server/scripts/northrend/azjol_nerub/ahnkahet/ahnkahet.h rename : src/scripts/northrend/azjol_nerub/ahnkahet/boss_amanitar.cpp => src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_amanitar.cpp rename : src/scripts/northrend/azjol_nerub/ahnkahet/boss_elder_nadox.cpp => src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_elder_nadox.cpp rename : src/scripts/northrend/azjol_nerub/ahnkahet/boss_herald_volazj.cpp => src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_herald_volazj.cpp rename : src/scripts/northrend/azjol_nerub/ahnkahet/boss_jedoga_shadowseeker.cpp => src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_jedoga_shadowseeker.cpp rename : src/scripts/northrend/azjol_nerub/ahnkahet/boss_prince_taldaram.cpp => src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_prince_taldaram.cpp rename : src/scripts/northrend/azjol_nerub/ahnkahet/instance_ahnkahet.cpp => src/server/scripts/northrend/azjol_nerub/ahnkahet/instance_ahnkahet.cpp rename : src/scripts/northrend/azjol_nerub/azjol_nerub/azjol_nerub.h => src/server/scripts/northrend/azjol_nerub/azjol_nerub/azjol_nerub.h rename : src/scripts/northrend/azjol_nerub/azjol_nerub/boss_anubarak.cpp => src/server/scripts/northrend/azjol_nerub/azjol_nerub/boss_anubarak.cpp rename : src/scripts/northrend/azjol_nerub/azjol_nerub/boss_hadronox.cpp => src/server/scripts/northrend/azjol_nerub/azjol_nerub/boss_hadronox.cpp rename : src/scripts/northrend/azjol_nerub/azjol_nerub/boss_krikthir_the_gatewatcher.cpp => src/server/scripts/northrend/azjol_nerub/azjol_nerub/boss_krikthir_the_gatewatcher.cpp rename : src/scripts/northrend/azjol_nerub/azjol_nerub/instance_azjol_nerub.cpp => src/server/scripts/northrend/azjol_nerub/azjol_nerub/instance_azjol_nerub.cpp rename : src/scripts/northrend/borean_tundra.cpp => src/server/scripts/northrend/borean_tundra.cpp rename : src/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_argent_challenge.cpp => src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_argent_challenge.cpp rename : src/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_black_knight.cpp => src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_black_knight.cpp rename : src/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_grand_champions.cpp => src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_grand_champions.cpp rename : src/scripts/northrend/crusaders_coliseum/trial_of_the_champion/instance_trial_of_the_champion.cpp => src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/instance_trial_of_the_champion.cpp rename : src/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.cpp => src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.cpp rename : src/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.h => src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.h rename : src/scripts/northrend/crystalsong_forest.cpp => src/server/scripts/northrend/crystalsong_forest.cpp rename : src/scripts/northrend/dalaran.cpp => src/server/scripts/northrend/dalaran.cpp rename : src/scripts/northrend/dragonblight.cpp => src/server/scripts/northrend/dragonblight.cpp rename : src/scripts/northrend/draktharon_keep/boss_dred.cpp => src/server/scripts/northrend/draktharon_keep/boss_dred.cpp rename : src/scripts/northrend/draktharon_keep/boss_novos.cpp => src/server/scripts/northrend/draktharon_keep/boss_novos.cpp rename : src/scripts/northrend/draktharon_keep/boss_tharon_ja.cpp => src/server/scripts/northrend/draktharon_keep/boss_tharon_ja.cpp rename : src/scripts/northrend/draktharon_keep/boss_trollgore.cpp => src/server/scripts/northrend/draktharon_keep/boss_trollgore.cpp rename : src/scripts/northrend/draktharon_keep/drak_tharon_keep.h => src/server/scripts/northrend/draktharon_keep/drak_tharon_keep.h rename : src/scripts/northrend/draktharon_keep/instance_drak_tharon_keep.cpp => src/server/scripts/northrend/draktharon_keep/instance_drak_tharon_keep.cpp rename : src/scripts/northrend/frozen_halls/forge_of_souls/boss_bronjahm.cpp => src/server/scripts/northrend/frozen_halls/forge_of_souls/boss_bronjahm.cpp rename : src/scripts/northrend/frozen_halls/forge_of_souls/boss_devourer_of_souls.cpp => src/server/scripts/northrend/frozen_halls/forge_of_souls/boss_devourer_of_souls.cpp rename : src/scripts/northrend/frozen_halls/forge_of_souls/forge_of_souls.cpp => src/server/scripts/northrend/frozen_halls/forge_of_souls/forge_of_souls.cpp rename : src/scripts/northrend/frozen_halls/forge_of_souls/forge_of_souls.h => src/server/scripts/northrend/frozen_halls/forge_of_souls/forge_of_souls.h rename : src/scripts/northrend/frozen_halls/forge_of_souls/instance_forge_of_souls.cpp => src/server/scripts/northrend/frozen_halls/forge_of_souls/instance_forge_of_souls.cpp rename : src/scripts/northrend/frozen_halls/halls_of_reflection/boss_falric.cpp => src/server/scripts/northrend/frozen_halls/halls_of_reflection/boss_falric.cpp rename : src/scripts/northrend/frozen_halls/halls_of_reflection/boss_marwyn.cpp => src/server/scripts/northrend/frozen_halls/halls_of_reflection/boss_marwyn.cpp rename : src/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.cpp => src/server/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.cpp rename : src/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.h => src/server/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.h rename : src/scripts/northrend/frozen_halls/halls_of_reflection/instance_halls_of_reflection.cpp => src/server/scripts/northrend/frozen_halls/halls_of_reflection/instance_halls_of_reflection.cpp rename : src/scripts/northrend/frozen_halls/pit_of_saron/boss_forgemaster_garfrost.cpp => src/server/scripts/northrend/frozen_halls/pit_of_saron/boss_forgemaster_garfrost.cpp rename : src/scripts/northrend/frozen_halls/pit_of_saron/boss_krickandick.cpp => src/server/scripts/northrend/frozen_halls/pit_of_saron/boss_krickandick.cpp rename : src/scripts/northrend/frozen_halls/pit_of_saron/boss_scourgelord_tyrannus.cpp => src/server/scripts/northrend/frozen_halls/pit_of_saron/boss_scourgelord_tyrannus.cpp rename : src/scripts/northrend/frozen_halls/pit_of_saron/instance_pit_of_saron.cpp => src/server/scripts/northrend/frozen_halls/pit_of_saron/instance_pit_of_saron.cpp rename : src/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.cpp => src/server/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.cpp rename : src/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.h => src/server/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.h rename : src/scripts/northrend/grizzly_hills.cpp => src/server/scripts/northrend/grizzly_hills.cpp rename : src/scripts/northrend/gundrak/boss_drakkari_colossus.cpp => src/server/scripts/northrend/gundrak/boss_drakkari_colossus.cpp rename : src/scripts/northrend/gundrak/boss_eck.cpp => src/server/scripts/northrend/gundrak/boss_eck.cpp rename : src/scripts/northrend/gundrak/boss_gal_darah.cpp => src/server/scripts/northrend/gundrak/boss_gal_darah.cpp rename : src/scripts/northrend/gundrak/boss_moorabi.cpp => src/server/scripts/northrend/gundrak/boss_moorabi.cpp rename : src/scripts/northrend/gundrak/boss_slad_ran.cpp => src/server/scripts/northrend/gundrak/boss_slad_ran.cpp rename : src/scripts/northrend/gundrak/gundrak.h => src/server/scripts/northrend/gundrak/gundrak.h rename : src/scripts/northrend/gundrak/instance_gundrak.cpp => src/server/scripts/northrend/gundrak/instance_gundrak.cpp rename : src/scripts/northrend/howling_fjord.cpp => src/server/scripts/northrend/howling_fjord.cpp rename : src/scripts/northrend/icecrown.cpp => src/server/scripts/northrend/icecrown.cpp rename : src/scripts/northrend/naxxramas/boss_anubrekhan.cpp => src/server/scripts/northrend/naxxramas/boss_anubrekhan.cpp rename : src/scripts/northrend/naxxramas/boss_faerlina.cpp => src/server/scripts/northrend/naxxramas/boss_faerlina.cpp rename : src/scripts/northrend/naxxramas/boss_four_horsemen.cpp => src/server/scripts/northrend/naxxramas/boss_four_horsemen.cpp rename : src/scripts/northrend/naxxramas/boss_gluth.cpp => src/server/scripts/northrend/naxxramas/boss_gluth.cpp rename : src/scripts/northrend/naxxramas/boss_gothik.cpp => src/server/scripts/northrend/naxxramas/boss_gothik.cpp rename : src/scripts/northrend/naxxramas/boss_grobbulus.cpp => src/server/scripts/northrend/naxxramas/boss_grobbulus.cpp rename : src/scripts/northrend/naxxramas/boss_heigan.cpp => src/server/scripts/northrend/naxxramas/boss_heigan.cpp rename : src/scripts/northrend/naxxramas/boss_highlord_mograine.cpp => src/server/scripts/northrend/naxxramas/boss_highlord_mograine.cpp rename : src/scripts/northrend/naxxramas/boss_kelthuzad.cpp => src/server/scripts/northrend/naxxramas/boss_kelthuzad.cpp rename : src/scripts/northrend/naxxramas/boss_loatheb.cpp => src/server/scripts/northrend/naxxramas/boss_loatheb.cpp rename : src/scripts/northrend/naxxramas/boss_maexxna.cpp => src/server/scripts/northrend/naxxramas/boss_maexxna.cpp rename : src/scripts/northrend/naxxramas/boss_noth.cpp => src/server/scripts/northrend/naxxramas/boss_noth.cpp rename : src/scripts/northrend/naxxramas/boss_patchwerk.cpp => src/server/scripts/northrend/naxxramas/boss_patchwerk.cpp rename : src/scripts/northrend/naxxramas/boss_razuvious.cpp => src/server/scripts/northrend/naxxramas/boss_razuvious.cpp rename : src/scripts/northrend/naxxramas/boss_sapphiron.cpp => src/server/scripts/northrend/naxxramas/boss_sapphiron.cpp rename : src/scripts/northrend/naxxramas/boss_thaddius.cpp => src/server/scripts/northrend/naxxramas/boss_thaddius.cpp rename : src/scripts/northrend/naxxramas/instance_naxxramas.cpp => src/server/scripts/northrend/naxxramas/instance_naxxramas.cpp rename : src/scripts/northrend/naxxramas/naxxramas.h => src/server/scripts/northrend/naxxramas/naxxramas.h rename : src/scripts/northrend/nexus/eye_of_eternity/boss_malygos.cpp => src/server/scripts/northrend/nexus/eye_of_eternity/boss_malygos.cpp rename : src/scripts/northrend/nexus/eye_of_eternity/eye_of_eternity.h => src/server/scripts/northrend/nexus/eye_of_eternity/eye_of_eternity.h rename : src/scripts/northrend/nexus/eye_of_eternity/instance_eye_of_eternity.cpp => src/server/scripts/northrend/nexus/eye_of_eternity/instance_eye_of_eternity.cpp rename : src/scripts/northrend/nexus/nexus/boss_anomalus.cpp => src/server/scripts/northrend/nexus/nexus/boss_anomalus.cpp rename : src/scripts/northrend/nexus/nexus/boss_keristrasza.cpp => src/server/scripts/northrend/nexus/nexus/boss_keristrasza.cpp rename : src/scripts/northrend/nexus/nexus/boss_magus_telestra.cpp => src/server/scripts/northrend/nexus/nexus/boss_magus_telestra.cpp rename : src/scripts/northrend/nexus/nexus/boss_ormorok.cpp => src/server/scripts/northrend/nexus/nexus/boss_ormorok.cpp rename : src/scripts/northrend/nexus/nexus/commander_kolurg.cpp => src/server/scripts/northrend/nexus/nexus/commander_kolurg.cpp rename : src/scripts/northrend/nexus/nexus/commander_stoutbeard.cpp => src/server/scripts/northrend/nexus/nexus/commander_stoutbeard.cpp rename : src/scripts/northrend/nexus/nexus/instance_nexus.cpp => src/server/scripts/northrend/nexus/nexus/instance_nexus.cpp rename : src/scripts/northrend/nexus/nexus/nexus.h => src/server/scripts/northrend/nexus/nexus/nexus.h rename : src/scripts/northrend/nexus/oculus/boss_drakos.cpp => src/server/scripts/northrend/nexus/oculus/boss_drakos.cpp rename : src/scripts/northrend/nexus/oculus/boss_eregos.cpp => src/server/scripts/northrend/nexus/oculus/boss_eregos.cpp rename : src/scripts/northrend/nexus/oculus/boss_urom.cpp => src/server/scripts/northrend/nexus/oculus/boss_urom.cpp rename : src/scripts/northrend/nexus/oculus/boss_varos.cpp => src/server/scripts/northrend/nexus/oculus/boss_varos.cpp rename : src/scripts/northrend/nexus/oculus/instance_oculus.cpp => src/server/scripts/northrend/nexus/oculus/instance_oculus.cpp rename : src/scripts/northrend/nexus/oculus/oculus.cpp => src/server/scripts/northrend/nexus/oculus/oculus.cpp rename : src/scripts/northrend/nexus/oculus/oculus.h => src/server/scripts/northrend/nexus/oculus/oculus.h rename : src/scripts/northrend/obsidian_sanctum/boss_sartharion.cpp => src/server/scripts/northrend/obsidian_sanctum/boss_sartharion.cpp rename : src/scripts/northrend/obsidian_sanctum/instance_obsidian_sanctum.cpp => src/server/scripts/northrend/obsidian_sanctum/instance_obsidian_sanctum.cpp rename : src/scripts/northrend/obsidian_sanctum/obsidian_sanctum.h => src/server/scripts/northrend/obsidian_sanctum/obsidian_sanctum.h rename : src/scripts/northrend/sholazar_basin.cpp => src/server/scripts/northrend/sholazar_basin.cpp rename : src/scripts/northrend/storm_peaks.cpp => src/server/scripts/northrend/storm_peaks.cpp rename : src/scripts/northrend/ulduar/halls_of_lightning/boss_bjarngrim.cpp => src/server/scripts/northrend/ulduar/halls_of_lightning/boss_bjarngrim.cpp rename : src/scripts/northrend/ulduar/halls_of_lightning/boss_ionar.cpp => src/server/scripts/northrend/ulduar/halls_of_lightning/boss_ionar.cpp rename : src/scripts/northrend/ulduar/halls_of_lightning/boss_loken.cpp => src/server/scripts/northrend/ulduar/halls_of_lightning/boss_loken.cpp rename : src/scripts/northrend/ulduar/halls_of_lightning/boss_volkhan.cpp => src/server/scripts/northrend/ulduar/halls_of_lightning/boss_volkhan.cpp rename : src/scripts/northrend/ulduar/halls_of_lightning/halls_of_lightning.h => src/server/scripts/northrend/ulduar/halls_of_lightning/halls_of_lightning.h rename : src/scripts/northrend/ulduar/halls_of_lightning/instance_halls_of_lightning.cpp => src/server/scripts/northrend/ulduar/halls_of_lightning/instance_halls_of_lightning.cpp rename : src/scripts/northrend/ulduar/halls_of_stone/boss_krystallus.cpp => src/server/scripts/northrend/ulduar/halls_of_stone/boss_krystallus.cpp rename : src/scripts/northrend/ulduar/halls_of_stone/boss_maiden_of_grief.cpp => src/server/scripts/northrend/ulduar/halls_of_stone/boss_maiden_of_grief.cpp rename : src/scripts/northrend/ulduar/halls_of_stone/boss_sjonnir.cpp => src/server/scripts/northrend/ulduar/halls_of_stone/boss_sjonnir.cpp rename : src/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.cpp => src/server/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.cpp rename : src/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.h => src/server/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.h rename : src/scripts/northrend/ulduar/halls_of_stone/instance_halls_of_stone.cpp => src/server/scripts/northrend/ulduar/halls_of_stone/instance_halls_of_stone.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_algalon.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_algalon.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_assembly_of_iron.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_assembly_of_iron.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_auriaya.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_auriaya.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_freya.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_freya.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_general_vezax.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_general_vezax.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_hodir.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_hodir.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_ignis.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_ignis.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_kologarn.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_kologarn.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_mimiron.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_mimiron.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_razorscale.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_razorscale.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_thorim.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_thorim.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_xt002.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_xt002.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_yoggsaron.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_yoggsaron.cpp rename : src/scripts/northrend/ulduar/ulduar/instance_ulduar.cpp => src/server/scripts/northrend/ulduar/ulduar/instance_ulduar.cpp rename : src/scripts/northrend/ulduar/ulduar/ulduar.h => src/server/scripts/northrend/ulduar/ulduar/ulduar.h rename : src/scripts/northrend/ulduar/ulduar/ulduar_teleporter.cpp => src/server/scripts/northrend/ulduar/ulduar/ulduar_teleporter.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_keep/boss_ingvar_the_plunderer.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_keep/boss_ingvar_the_plunderer.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_keep/boss_keleseth.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_keep/boss_keleseth.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_keep/boss_skarvald_dalronn.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_keep/boss_skarvald_dalronn.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.h => src/server/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.h rename : src/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_palehoof.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_palehoof.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_skadi.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_skadi.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_svala.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_svala.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_ymiron.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_ymiron.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_pinnacle/instance_pinnacle.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/instance_pinnacle.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_pinnacle/utgarde_pinnacle.h => src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/utgarde_pinnacle.h rename : src/scripts/northrend/vault_of_archavon/boss_archavon.cpp => src/server/scripts/northrend/vault_of_archavon/boss_archavon.cpp rename : src/scripts/northrend/vault_of_archavon/boss_emalon.cpp => src/server/scripts/northrend/vault_of_archavon/boss_emalon.cpp rename : src/scripts/northrend/vault_of_archavon/boss_koralon.cpp => src/server/scripts/northrend/vault_of_archavon/boss_koralon.cpp rename : src/scripts/northrend/vault_of_archavon/boss_toravon.cpp => src/server/scripts/northrend/vault_of_archavon/boss_toravon.cpp rename : src/scripts/northrend/vault_of_archavon/instance_vault_of_archavon.cpp => src/server/scripts/northrend/vault_of_archavon/instance_vault_of_archavon.cpp rename : src/scripts/northrend/vault_of_archavon/vault_of_archavon.h => src/server/scripts/northrend/vault_of_archavon/vault_of_archavon.h rename : src/scripts/northrend/violet_hold/boss_cyanigosa.cpp => src/server/scripts/northrend/violet_hold/boss_cyanigosa.cpp rename : src/scripts/northrend/violet_hold/boss_erekem.cpp => src/server/scripts/northrend/violet_hold/boss_erekem.cpp rename : src/scripts/northrend/violet_hold/boss_ichoron.cpp => src/server/scripts/northrend/violet_hold/boss_ichoron.cpp rename : src/scripts/northrend/violet_hold/boss_lavanthor.cpp => src/server/scripts/northrend/violet_hold/boss_lavanthor.cpp rename : src/scripts/northrend/violet_hold/boss_moragg.cpp => src/server/scripts/northrend/violet_hold/boss_moragg.cpp rename : src/scripts/northrend/violet_hold/boss_xevozz.cpp => src/server/scripts/northrend/violet_hold/boss_xevozz.cpp rename : src/scripts/northrend/violet_hold/boss_zuramat.cpp => src/server/scripts/northrend/violet_hold/boss_zuramat.cpp rename : src/scripts/northrend/violet_hold/instance_violet_hold.cpp => src/server/scripts/northrend/violet_hold/instance_violet_hold.cpp rename : src/scripts/northrend/violet_hold/violet_hold.cpp => src/server/scripts/northrend/violet_hold/violet_hold.cpp rename : src/scripts/northrend/violet_hold/violet_hold.h => src/server/scripts/northrend/violet_hold/violet_hold.h rename : src/scripts/northrend/zuldrak.cpp => src/server/scripts/northrend/zuldrak.cpp rename : src/scripts/outland/auchindoun/auchenai_crypts/boss_exarch_maladaar.cpp => src/server/scripts/outland/auchindoun/auchenai_crypts/boss_exarch_maladaar.cpp rename : src/scripts/outland/auchindoun/auchenai_crypts/boss_shirrak_the_dead_watcher.cpp => src/server/scripts/outland/auchindoun/auchenai_crypts/boss_shirrak_the_dead_watcher.cpp rename : src/scripts/outland/auchindoun/mana_tombs/boss_nexusprince_shaffar.cpp => src/server/scripts/outland/auchindoun/mana_tombs/boss_nexusprince_shaffar.cpp rename : src/scripts/outland/auchindoun/mana_tombs/boss_pandemonius.cpp => src/server/scripts/outland/auchindoun/mana_tombs/boss_pandemonius.cpp rename : src/scripts/outland/auchindoun/sethekk_halls/boss_darkweaver_syth.cpp => src/server/scripts/outland/auchindoun/sethekk_halls/boss_darkweaver_syth.cpp rename : src/scripts/outland/auchindoun/sethekk_halls/boss_tailonking_ikiss.cpp => src/server/scripts/outland/auchindoun/sethekk_halls/boss_tailonking_ikiss.cpp rename : src/scripts/outland/auchindoun/sethekk_halls/instance_sethekk_halls.cpp => src/server/scripts/outland/auchindoun/sethekk_halls/instance_sethekk_halls.cpp rename : src/scripts/outland/auchindoun/sethekk_halls/sethekk_halls.h => src/server/scripts/outland/auchindoun/sethekk_halls/sethekk_halls.h rename : src/scripts/outland/auchindoun/shadow_labyrinth/boss_ambassador_hellmaw.cpp => src/server/scripts/outland/auchindoun/shadow_labyrinth/boss_ambassador_hellmaw.cpp rename : src/scripts/outland/auchindoun/shadow_labyrinth/boss_blackheart_the_inciter.cpp => src/server/scripts/outland/auchindoun/shadow_labyrinth/boss_blackheart_the_inciter.cpp rename : src/scripts/outland/auchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp => src/server/scripts/outland/auchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp rename : src/scripts/outland/auchindoun/shadow_labyrinth/boss_murmur.cpp => src/server/scripts/outland/auchindoun/shadow_labyrinth/boss_murmur.cpp rename : src/scripts/outland/auchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp => src/server/scripts/outland/auchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp rename : src/scripts/outland/auchindoun/shadow_labyrinth/shadow_labyrinth.h => src/server/scripts/outland/auchindoun/shadow_labyrinth/shadow_labyrinth.h rename : src/scripts/outland/black_temple/black_temple.cpp => src/server/scripts/outland/black_temple/black_temple.cpp rename : src/scripts/outland/black_temple/black_temple.h => src/server/scripts/outland/black_temple/black_temple.h rename : src/scripts/outland/black_temple/boss_bloodboil.cpp => src/server/scripts/outland/black_temple/boss_bloodboil.cpp rename : src/scripts/outland/black_temple/boss_illidan.cpp => src/server/scripts/outland/black_temple/boss_illidan.cpp rename : src/scripts/outland/black_temple/boss_mother_shahraz.cpp => src/server/scripts/outland/black_temple/boss_mother_shahraz.cpp rename : src/scripts/outland/black_temple/boss_reliquary_of_souls.cpp => src/server/scripts/outland/black_temple/boss_reliquary_of_souls.cpp rename : src/scripts/outland/black_temple/boss_shade_of_akama.cpp => src/server/scripts/outland/black_temple/boss_shade_of_akama.cpp rename : src/scripts/outland/black_temple/boss_supremus.cpp => src/server/scripts/outland/black_temple/boss_supremus.cpp rename : src/scripts/outland/black_temple/boss_teron_gorefiend.cpp => src/server/scripts/outland/black_temple/boss_teron_gorefiend.cpp rename : src/scripts/outland/black_temple/boss_warlord_najentus.cpp => src/server/scripts/outland/black_temple/boss_warlord_najentus.cpp rename : src/scripts/outland/black_temple/illidari_council.cpp => src/server/scripts/outland/black_temple/illidari_council.cpp rename : src/scripts/outland/black_temple/instance_black_temple.cpp => src/server/scripts/outland/black_temple/instance_black_temple.cpp rename : src/scripts/outland/blades_edge_mountains.cpp => src/server/scripts/outland/blades_edge_mountains.cpp rename : src/scripts/outland/boss_doomlord_kazzak.cpp => src/server/scripts/outland/boss_doomlord_kazzak.cpp rename : src/scripts/outland/boss_doomwalker.cpp => src/server/scripts/outland/boss_doomwalker.cpp rename : src/scripts/outland/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp => src/server/scripts/outland/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp rename : src/scripts/outland/coilfang_resevoir/serpent_shrine/boss_hydross_the_unstable.cpp => src/server/scripts/outland/coilfang_resevoir/serpent_shrine/boss_hydross_the_unstable.cpp rename : src/scripts/outland/coilfang_resevoir/serpent_shrine/boss_lady_vashj.cpp => src/server/scripts/outland/coilfang_resevoir/serpent_shrine/boss_lady_vashj.cpp rename : src/scripts/outland/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp => src/server/scripts/outland/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp rename : src/scripts/outland/coilfang_resevoir/serpent_shrine/boss_lurker_below.cpp => src/server/scripts/outland/coilfang_resevoir/serpent_shrine/boss_lurker_below.cpp rename : src/scripts/outland/coilfang_resevoir/serpent_shrine/boss_morogrim_tidewalker.cpp => src/server/scripts/outland/coilfang_resevoir/serpent_shrine/boss_morogrim_tidewalker.cpp rename : src/scripts/outland/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp => src/server/scripts/outland/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp rename : src/scripts/outland/coilfang_resevoir/serpent_shrine/serpent_shrine.h => src/server/scripts/outland/coilfang_resevoir/serpent_shrine/serpent_shrine.h rename : src/scripts/outland/coilfang_resevoir/steam_vault/boss_hydromancer_thespia.cpp => src/server/scripts/outland/coilfang_resevoir/steam_vault/boss_hydromancer_thespia.cpp rename : src/scripts/outland/coilfang_resevoir/steam_vault/boss_mekgineer_steamrigger.cpp => src/server/scripts/outland/coilfang_resevoir/steam_vault/boss_mekgineer_steamrigger.cpp rename : src/scripts/outland/coilfang_resevoir/steam_vault/boss_warlord_kalithresh.cpp => src/server/scripts/outland/coilfang_resevoir/steam_vault/boss_warlord_kalithresh.cpp rename : src/scripts/outland/coilfang_resevoir/steam_vault/instance_steam_vault.cpp => src/server/scripts/outland/coilfang_resevoir/steam_vault/instance_steam_vault.cpp rename : src/scripts/outland/coilfang_resevoir/steam_vault/steam_vault.h => src/server/scripts/outland/coilfang_resevoir/steam_vault/steam_vault.h rename : src/scripts/outland/coilfang_resevoir/underbog/boss_hungarfen.cpp => src/server/scripts/outland/coilfang_resevoir/underbog/boss_hungarfen.cpp rename : src/scripts/outland/coilfang_resevoir/underbog/boss_the_black_stalker.cpp => src/server/scripts/outland/coilfang_resevoir/underbog/boss_the_black_stalker.cpp rename : src/scripts/outland/gruuls_lair/boss_gruul.cpp => src/server/scripts/outland/gruuls_lair/boss_gruul.cpp rename : src/scripts/outland/gruuls_lair/boss_high_king_maulgar.cpp => src/server/scripts/outland/gruuls_lair/boss_high_king_maulgar.cpp rename : src/scripts/outland/gruuls_lair/gruuls_lair.h => src/server/scripts/outland/gruuls_lair/gruuls_lair.h rename : src/scripts/outland/gruuls_lair/instance_gruuls_lair.cpp => src/server/scripts/outland/gruuls_lair/instance_gruuls_lair.cpp rename : src/scripts/outland/hellfire_citadel/blood_furnace/blood_furnace.h => src/server/scripts/outland/hellfire_citadel/blood_furnace/blood_furnace.h rename : src/scripts/outland/hellfire_citadel/blood_furnace/boss_broggok.cpp => src/server/scripts/outland/hellfire_citadel/blood_furnace/boss_broggok.cpp rename : src/scripts/outland/hellfire_citadel/blood_furnace/boss_kelidan_the_breaker.cpp => src/server/scripts/outland/hellfire_citadel/blood_furnace/boss_kelidan_the_breaker.cpp rename : src/scripts/outland/hellfire_citadel/blood_furnace/boss_the_maker.cpp => src/server/scripts/outland/hellfire_citadel/blood_furnace/boss_the_maker.cpp rename : src/scripts/outland/hellfire_citadel/blood_furnace/instance_blood_furnace.cpp => src/server/scripts/outland/hellfire_citadel/blood_furnace/instance_blood_furnace.cpp rename : src/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_omor_the_unscarred.cpp => src/server/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_omor_the_unscarred.cpp rename : src/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_vazruden_the_herald.cpp => src/server/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_vazruden_the_herald.cpp rename : src/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_watchkeeper_gargolmar.cpp => src/server/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_watchkeeper_gargolmar.cpp rename : src/scripts/outland/hellfire_citadel/hellfire_ramparts/hellfire_ramparts.h => src/server/scripts/outland/hellfire_citadel/hellfire_ramparts/hellfire_ramparts.h rename : src/scripts/outland/hellfire_citadel/hellfire_ramparts/instance_hellfire_ramparts.cpp => src/server/scripts/outland/hellfire_citadel/hellfire_ramparts/instance_hellfire_ramparts.cpp rename : src/scripts/outland/hellfire_citadel/magtheridons_lair/boss_magtheridon.cpp => src/server/scripts/outland/hellfire_citadel/magtheridons_lair/boss_magtheridon.cpp rename : src/scripts/outland/hellfire_citadel/magtheridons_lair/instance_magtheridons_lair.cpp => src/server/scripts/outland/hellfire_citadel/magtheridons_lair/instance_magtheridons_lair.cpp rename : src/scripts/outland/hellfire_citadel/magtheridons_lair/magtheridons_lair.h => src/server/scripts/outland/hellfire_citadel/magtheridons_lair/magtheridons_lair.h rename : src/scripts/outland/hellfire_citadel/shattered_halls/boss_nethekurse.cpp => src/server/scripts/outland/hellfire_citadel/shattered_halls/boss_nethekurse.cpp rename : src/scripts/outland/hellfire_citadel/shattered_halls/boss_warbringer_omrogg.cpp => src/server/scripts/outland/hellfire_citadel/shattered_halls/boss_warbringer_omrogg.cpp rename : src/scripts/outland/hellfire_citadel/shattered_halls/boss_warchief_kargath_bladefist.cpp => src/server/scripts/outland/hellfire_citadel/shattered_halls/boss_warchief_kargath_bladefist.cpp rename : src/scripts/outland/hellfire_citadel/shattered_halls/instance_shattered_halls.cpp => src/server/scripts/outland/hellfire_citadel/shattered_halls/instance_shattered_halls.cpp rename : src/scripts/outland/hellfire_citadel/shattered_halls/shattered_halls.h => src/server/scripts/outland/hellfire_citadel/shattered_halls/shattered_halls.h rename : src/scripts/outland/hellfire_peninsula.cpp => src/server/scripts/outland/hellfire_peninsula.cpp rename : src/scripts/outland/nagrand.cpp => src/server/scripts/outland/nagrand.cpp rename : src/scripts/outland/netherstorm.cpp => src/server/scripts/outland/netherstorm.cpp rename : src/scripts/outland/shadowmoon_valley.cpp => src/server/scripts/outland/shadowmoon_valley.cpp rename : src/scripts/outland/shattrath_city.cpp => src/server/scripts/outland/shattrath_city.cpp rename : src/scripts/outland/tempest_keep/arcatraz/arcatraz.cpp => src/server/scripts/outland/tempest_keep/arcatraz/arcatraz.cpp rename : src/scripts/outland/tempest_keep/arcatraz/arcatraz.h => src/server/scripts/outland/tempest_keep/arcatraz/arcatraz.h rename : src/scripts/outland/tempest_keep/arcatraz/boss_harbinger_skyriss.cpp => src/server/scripts/outland/tempest_keep/arcatraz/boss_harbinger_skyriss.cpp rename : src/scripts/outland/tempest_keep/arcatraz/instance_arcatraz.cpp => src/server/scripts/outland/tempest_keep/arcatraz/instance_arcatraz.cpp rename : src/scripts/outland/tempest_keep/botanica/boss_high_botanist_freywinn.cpp => src/server/scripts/outland/tempest_keep/botanica/boss_high_botanist_freywinn.cpp rename : src/scripts/outland/tempest_keep/botanica/boss_laj.cpp => src/server/scripts/outland/tempest_keep/botanica/boss_laj.cpp rename : src/scripts/outland/tempest_keep/botanica/boss_warp_splinter.cpp => src/server/scripts/outland/tempest_keep/botanica/boss_warp_splinter.cpp rename : src/scripts/outland/tempest_keep/the_eye/boss_alar.cpp => src/server/scripts/outland/tempest_keep/the_eye/boss_alar.cpp rename : src/scripts/outland/tempest_keep/the_eye/boss_astromancer.cpp => src/server/scripts/outland/tempest_keep/the_eye/boss_astromancer.cpp rename : src/scripts/outland/tempest_keep/the_eye/boss_kaelthas.cpp => src/server/scripts/outland/tempest_keep/the_eye/boss_kaelthas.cpp rename : src/scripts/outland/tempest_keep/the_eye/boss_void_reaver.cpp => src/server/scripts/outland/tempest_keep/the_eye/boss_void_reaver.cpp rename : src/scripts/outland/tempest_keep/the_eye/instance_the_eye.cpp => src/server/scripts/outland/tempest_keep/the_eye/instance_the_eye.cpp rename : src/scripts/outland/tempest_keep/the_eye/the_eye.cpp => src/server/scripts/outland/tempest_keep/the_eye/the_eye.cpp rename : src/scripts/outland/tempest_keep/the_eye/the_eye.h => src/server/scripts/outland/tempest_keep/the_eye/the_eye.h rename : src/scripts/outland/tempest_keep/the_mechanar/boss_gatewatcher_gyrokill.cpp => src/server/scripts/outland/tempest_keep/the_mechanar/boss_gatewatcher_gyrokill.cpp rename : src/scripts/outland/tempest_keep/the_mechanar/boss_gatewatcher_ironhand.cpp => src/server/scripts/outland/tempest_keep/the_mechanar/boss_gatewatcher_ironhand.cpp rename : src/scripts/outland/tempest_keep/the_mechanar/boss_nethermancer_sepethrea.cpp => src/server/scripts/outland/tempest_keep/the_mechanar/boss_nethermancer_sepethrea.cpp rename : src/scripts/outland/tempest_keep/the_mechanar/boss_pathaleon_the_calculator.cpp => src/server/scripts/outland/tempest_keep/the_mechanar/boss_pathaleon_the_calculator.cpp rename : src/scripts/outland/tempest_keep/the_mechanar/instance_mechanar.cpp => src/server/scripts/outland/tempest_keep/the_mechanar/instance_mechanar.cpp rename : src/scripts/outland/tempest_keep/the_mechanar/mechanar.h => src/server/scripts/outland/tempest_keep/the_mechanar/mechanar.h rename : src/scripts/outland/terokkar_forest.cpp => src/server/scripts/outland/terokkar_forest.cpp rename : src/scripts/outland/zangarmarsh.cpp => src/server/scripts/outland/zangarmarsh.cpp rename : src/scripts/world/areatrigger_scripts.cpp => src/server/scripts/world/areatrigger_scripts.cpp rename : src/scripts/world/boss_emeriss.cpp => src/server/scripts/world/boss_emeriss.cpp rename : src/scripts/world/boss_lethon.cpp => src/server/scripts/world/boss_lethon.cpp rename : src/scripts/world/boss_taerar.cpp => src/server/scripts/world/boss_taerar.cpp rename : src/scripts/world/boss_ysondre.cpp => src/server/scripts/world/boss_ysondre.cpp rename : src/scripts/world/go_scripts.cpp => src/server/scripts/world/go_scripts.cpp rename : src/scripts/world/guards.cpp => src/server/scripts/world/guards.cpp rename : src/scripts/world/item_scripts.cpp => src/server/scripts/world/item_scripts.cpp rename : src/scripts/world/mob_generic_creature.cpp => src/server/scripts/world/mob_generic_creature.cpp rename : src/scripts/world/npc_innkeeper.cpp => src/server/scripts/world/npc_innkeeper.cpp rename : src/scripts/world/npc_professions.cpp => src/server/scripts/world/npc_professions.cpp rename : src/scripts/world/npc_taxi.cpp => src/server/scripts/world/npc_taxi.cpp rename : src/scripts/world/npcs_special.cpp => src/server/scripts/world/npcs_special.cpp rename : src/shared/Auth/AuthCrypt.cpp => src/server/shared/Auth/AuthCrypt.cpp rename : src/shared/Auth/AuthCrypt.h => src/server/shared/Auth/AuthCrypt.h rename : src/shared/Auth/BigNumber.cpp => src/server/shared/Auth/BigNumber.cpp rename : src/shared/Auth/BigNumber.h => src/server/shared/Auth/BigNumber.h rename : src/shared/Auth/CMakeLists.txt => src/server/shared/Auth/CMakeLists.txt rename : src/shared/Auth/Hmac.cpp => src/server/shared/Auth/Hmac.cpp rename : src/shared/Auth/Hmac.h => src/server/shared/Auth/Hmac.h rename : src/shared/Auth/SARC4.cpp => src/server/shared/Auth/SARC4.cpp rename : src/shared/Auth/SARC4.h => src/server/shared/Auth/SARC4.h rename : src/shared/Auth/Sha1.cpp => src/server/shared/Auth/Sha1.cpp rename : src/shared/Auth/Sha1.h => src/server/shared/Auth/Sha1.h rename : src/shared/Auth/md5.c => src/server/shared/Auth/md5.c rename : src/shared/Auth/md5.h => src/server/shared/Auth/md5.h rename : src/shared/ByteBuffer.h => src/server/shared/ByteBuffer.h rename : src/shared/CMakeLists.txt => src/server/shared/CMakeLists.txt rename : src/shared/Common.cpp => src/server/shared/Common.cpp rename : src/shared/Common.h => src/server/shared/Common.h rename : src/shared/Config/CMakeLists.txt => src/server/shared/Config/CMakeLists.txt rename : src/shared/Config/Config.cpp => src/server/shared/Config/Config.cpp rename : src/shared/Config/Config.h => src/server/shared/Config/Config.h rename : src/shared/Config/ConfigEnv.h => src/server/shared/Config/ConfigEnv.h rename : src/shared/Config/ConfigLibrary.vcproj => src/server/shared/Config/ConfigLibrary.vcproj rename : src/shared/Config/dotconfpp/dotconfpp.cpp => src/server/shared/Config/dotconfpp/dotconfpp.cpp rename : src/shared/Config/dotconfpp/dotconfpp.h => src/server/shared/Config/dotconfpp/dotconfpp.h rename : src/shared/Config/dotconfpp/mempool.cpp => src/server/shared/Config/dotconfpp/mempool.cpp rename : src/shared/Config/dotconfpp/mempool.h => src/server/shared/Config/dotconfpp/mempool.h rename : src/shared/Database/CMakeLists.txt => src/server/shared/Database/CMakeLists.txt rename : src/shared/Database/DBCFileLoader.cpp => src/server/shared/Database/DBCFileLoader.cpp rename : src/shared/Database/DBCFileLoader.h => src/server/shared/Database/DBCFileLoader.h rename : src/shared/Database/DBCStore.h => src/server/shared/Database/DBCStore.h rename : src/shared/Database/Database.cpp => src/server/shared/Database/Database.cpp rename : src/shared/Database/Database.h => src/server/shared/Database/Database.h rename : src/shared/Database/DatabaseEnv.h => src/server/shared/Database/DatabaseEnv.h rename : src/shared/Database/DatabaseImpl.h => src/server/shared/Database/DatabaseImpl.h rename : src/shared/Database/Field.cpp => src/server/shared/Database/Field.cpp rename : src/shared/Database/Field.h => src/server/shared/Database/Field.h rename : src/shared/Database/QueryResult.cpp => src/server/shared/Database/QueryResult.cpp rename : src/shared/Database/QueryResult.h => src/server/shared/Database/QueryResult.h rename : src/shared/Database/SQLStorage.cpp => src/server/shared/Database/SQLStorage.cpp rename : src/shared/Database/SQLStorage.h => src/server/shared/Database/SQLStorage.h rename : src/shared/Database/SQLStorageImpl.h => src/server/shared/Database/SQLStorageImpl.h rename : src/shared/Database/SqlDelayThread.cpp => src/server/shared/Database/SqlDelayThread.cpp rename : src/shared/Database/SqlDelayThread.h => src/server/shared/Database/SqlDelayThread.h rename : src/shared/Database/SqlOperations.cpp => src/server/shared/Database/SqlOperations.cpp rename : src/shared/Database/SqlOperations.h => src/server/shared/Database/SqlOperations.h rename : src/shared/DelayExecutor.cpp => src/server/shared/DelayExecutor.cpp rename : src/shared/DelayExecutor.h => src/server/shared/DelayExecutor.h rename : src/shared/Errors.h => src/server/shared/Errors.h rename : src/shared/LockedQueue.h => src/server/shared/LockedQueue.h rename : src/shared/Log.cpp => src/server/shared/Log.cpp rename : src/shared/Log.h => src/server/shared/Log.h rename : src/shared/MemoryLeaks.cpp => src/server/shared/MemoryLeaks.cpp rename : src/shared/MemoryLeaks.h => src/server/shared/MemoryLeaks.h rename : src/shared/PacketLog.cpp => src/server/shared/PacketLog.cpp rename : src/shared/PacketLog.h => src/server/shared/PacketLog.h rename : src/shared/ProgressBar.cpp => src/server/shared/ProgressBar.cpp rename : src/shared/ProgressBar.h => src/server/shared/ProgressBar.h rename : src/shared/ServiceWin32.cpp => src/server/shared/ServiceWin32.cpp rename : src/shared/ServiceWin32.h => src/server/shared/ServiceWin32.h rename : src/shared/SignalHandler.h => src/server/shared/SignalHandler.h rename : src/shared/SystemConfig.h => src/server/shared/SystemConfig.h rename : src/shared/Threading.cpp => src/server/shared/Threading.cpp rename : src/shared/Threading.h => src/server/shared/Threading.h rename : src/shared/Timer.h => src/server/shared/Timer.h rename : src/shared/Util.cpp => src/server/shared/Util.cpp rename : src/shared/Util.h => src/server/shared/Util.h rename : src/shared/WheatyExceptionReport.cpp => src/server/shared/WheatyExceptionReport.cpp rename : src/shared/WheatyExceptionReport.h => src/server/shared/WheatyExceptionReport.h rename : src/shared/WorldPacket.h => src/server/shared/WorldPacket.h rename : src/shared/vmap/BIH.cpp => src/server/shared/vmap/BIH.cpp rename : src/shared/vmap/BIH.h => src/server/shared/vmap/BIH.h rename : src/shared/vmap/CMakeLists.txt => src/server/shared/vmap/CMakeLists.txt rename : src/shared/vmap/IVMapManager.h => src/server/shared/vmap/IVMapManager.h rename : src/shared/vmap/MapTree.cpp => src/server/shared/vmap/MapTree.cpp rename : src/shared/vmap/MapTree.h => src/server/shared/vmap/MapTree.h rename : src/shared/vmap/ModelInstance.cpp => src/server/shared/vmap/ModelInstance.cpp rename : src/shared/vmap/ModelInstance.h => src/server/shared/vmap/ModelInstance.h rename : src/shared/vmap/TileAssembler.cpp => src/server/shared/vmap/TileAssembler.cpp rename : src/shared/vmap/TileAssembler.h => src/server/shared/vmap/TileAssembler.h rename : src/shared/vmap/VMapDefinitions.h => src/server/shared/vmap/VMapDefinitions.h rename : src/shared/vmap/VMapFactory.cpp => src/server/shared/vmap/VMapFactory.cpp rename : src/shared/vmap/VMapFactory.h => src/server/shared/vmap/VMapFactory.h rename : src/shared/vmap/VMapManager2.cpp => src/server/shared/vmap/VMapManager2.cpp rename : src/shared/vmap/VMapManager2.h => src/server/shared/vmap/VMapManager2.h rename : src/shared/vmap/VMapTools.h => src/server/shared/vmap/VMapTools.h rename : src/shared/vmap/WorldModel.cpp => src/server/shared/vmap/WorldModel.cpp rename : src/shared/vmap/WorldModel.h => src/server/shared/vmap/WorldModel.h rename : src/trinitycore/CMakeLists.txt => src/server/trinitycore/CMakeLists.txt rename : src/trinitycore/CliRunnable.cpp => src/server/trinitycore/CliRunnable.cpp rename : src/trinitycore/CliRunnable.h => src/server/trinitycore/CliRunnable.h rename : src/trinitycore/Main.cpp => src/server/trinitycore/Main.cpp rename : src/trinitycore/Master.cpp => src/server/trinitycore/Master.cpp rename : src/trinitycore/Master.h => src/server/trinitycore/Master.h rename : src/trinitycore/RASocket.cpp => src/server/trinitycore/RASocket.cpp rename : src/trinitycore/RASocket.h => src/server/trinitycore/RASocket.h rename : src/trinitycore/TrinityCore.ico => src/server/trinitycore/TrinityCore.ico rename : src/trinitycore/TrinityCore.rc => src/server/trinitycore/TrinityCore.rc rename : src/trinitycore/WorldRunnable.cpp => src/server/trinitycore/WorldRunnable.cpp rename : src/trinitycore/WorldRunnable.h => src/server/trinitycore/WorldRunnable.h rename : src/trinitycore/resource.h => src/server/trinitycore/resource.h rename : src/trinitycore/trinitycore.conf.dist => src/server/trinitycore/trinitycore.conf.dist rename : src/trinityrealm/AuthCodes.cpp => src/server/trinityrealm/AuthCodes.cpp rename : src/trinityrealm/AuthCodes.h => src/server/trinityrealm/AuthCodes.h rename : src/trinityrealm/AuthSocket.cpp => src/server/trinityrealm/AuthSocket.cpp rename : src/trinityrealm/AuthSocket.h => src/server/trinityrealm/AuthSocket.h rename : src/trinityrealm/CMakeLists.txt => src/server/trinityrealm/CMakeLists.txt rename : src/trinityrealm/Main.cpp => src/server/trinityrealm/Main.cpp rename : src/trinityrealm/RealmAcceptor.h => src/server/trinityrealm/RealmAcceptor.h rename : src/trinityrealm/RealmList.cpp => src/server/trinityrealm/RealmList.cpp rename : src/trinityrealm/RealmList.h => src/server/trinityrealm/RealmList.h rename : src/trinityrealm/RealmSocket.cpp => src/server/trinityrealm/RealmSocket.cpp rename : src/trinityrealm/RealmSocket.h => src/server/trinityrealm/RealmSocket.h rename : src/trinityrealm/TrinityRealm.ico => src/server/trinityrealm/TrinityRealm.ico rename : src/trinityrealm/TrinityRealm.rc => src/server/trinityrealm/TrinityRealm.rc rename : src/trinityrealm/resource.h => src/server/trinityrealm/resource.h rename : src/trinityrealm/trinityrealm.conf.dist => src/server/trinityrealm/trinityrealm.conf.dist
This commit is contained in:
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "Policies/SingletonImp.h"
|
||||
|
||||
#include "AccountMgr.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Player.h"
|
||||
#include "Util.h"
|
||||
#include "Auth/Sha1.h"
|
||||
|
||||
extern DatabaseType LoginDatabase;
|
||||
|
||||
INSTANTIATE_SINGLETON_1(AccountMgr);
|
||||
|
||||
AccountMgr::AccountMgr()
|
||||
{}
|
||||
|
||||
AccountMgr::~AccountMgr()
|
||||
{}
|
||||
|
||||
AccountOpResult AccountMgr::CreateAccount(std::string username, std::string password)
|
||||
{
|
||||
if (utf8length(username) > MAX_ACCOUNT_STR)
|
||||
return AOR_NAME_TOO_LONG; // username's too long
|
||||
|
||||
normalizeString(username);
|
||||
normalizeString(password);
|
||||
|
||||
if (GetId(username))
|
||||
{
|
||||
return AOR_NAME_ALREDY_EXIST; // username does already exist
|
||||
}
|
||||
|
||||
if (!LoginDatabase.PExecute("INSERT INTO account(username,sha_pass_hash,joindate) VALUES('%s','%s',NOW())", username.c_str(), CalculateShaPassHash(username, password).c_str()))
|
||||
return AOR_DB_INTERNAL_ERROR; // unexpected error
|
||||
LoginDatabase.Execute("INSERT INTO realmcharacters (realmid, acctid, numchars) SELECT realmlist.id, account.id, 0 FROM realmlist,account LEFT JOIN realmcharacters ON acctid=account.id WHERE acctid IS NULL");
|
||||
|
||||
return AOR_OK; // everything's fine
|
||||
}
|
||||
|
||||
AccountOpResult AccountMgr::DeleteAccount(uint32 accid)
|
||||
{
|
||||
QueryResult_AutoPtr result = LoginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accid);
|
||||
if (!result)
|
||||
return AOR_NAME_NOT_EXIST; // account doesn't exist
|
||||
|
||||
result = CharacterDatabase.PQuery("SELECT guid FROM characters WHERE account='%d'",accid);
|
||||
if (result)
|
||||
{
|
||||
do
|
||||
{
|
||||
Field *fields = result->Fetch();
|
||||
uint32 guidlo = fields[0].GetUInt32();
|
||||
uint64 guid = MAKE_NEW_GUID(guidlo, 0, HIGHGUID_PLAYER);
|
||||
|
||||
// kick if player currently
|
||||
if (Player* p = ObjectAccessor::GetObjectInWorld(guid, (Player*)NULL))
|
||||
{
|
||||
WorldSession* s = p->GetSession();
|
||||
s->KickPlayer(); // mark session to remove at next session list update
|
||||
s->LogoutPlayer(false); // logout player without waiting next session list update
|
||||
}
|
||||
|
||||
Player::DeleteFromDB(guid, accid, false); // no need to update realm characters
|
||||
} while (result->NextRow());
|
||||
}
|
||||
|
||||
// table realm specific but common for all characters of account for realm
|
||||
CharacterDatabase.PExecute("DELETE FROM character_tutorial WHERE account = '%u'",accid);
|
||||
CharacterDatabase.PExecute("DELETE FROM account_data WHERE account = '%u'",accid);
|
||||
|
||||
LoginDatabase.BeginTransaction();
|
||||
|
||||
bool res =
|
||||
LoginDatabase.PExecute("DELETE FROM account WHERE id='%d'", accid) &&
|
||||
LoginDatabase.PExecute("DELETE FROM account_access WHERE id ='%d'", accid) &&
|
||||
LoginDatabase.PExecute("DELETE FROM realmcharacters WHERE acctid='%d'", accid);
|
||||
|
||||
LoginDatabase.CommitTransaction();
|
||||
|
||||
if (!res)
|
||||
return AOR_DB_INTERNAL_ERROR; // unexpected error;
|
||||
|
||||
return AOR_OK;
|
||||
}
|
||||
|
||||
AccountOpResult AccountMgr::ChangeUsername(uint32 accid, std::string new_uname, std::string new_passwd)
|
||||
{
|
||||
QueryResult_AutoPtr result = LoginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accid);
|
||||
if (!result)
|
||||
return AOR_NAME_NOT_EXIST; // account doesn't exist
|
||||
|
||||
if (utf8length(new_uname) > MAX_ACCOUNT_STR)
|
||||
return AOR_NAME_TOO_LONG;
|
||||
|
||||
if (utf8length(new_passwd) > MAX_ACCOUNT_STR)
|
||||
return AOR_PASS_TOO_LONG;
|
||||
|
||||
normalizeString(new_uname);
|
||||
normalizeString(new_passwd);
|
||||
|
||||
std::string safe_new_uname = new_uname;
|
||||
LoginDatabase.escape_string(safe_new_uname);
|
||||
|
||||
if (!LoginDatabase.PExecute("UPDATE account SET v='0',s='0',username='%s',sha_pass_hash='%s' WHERE id='%d'", safe_new_uname.c_str(),
|
||||
CalculateShaPassHash(new_uname, new_passwd).c_str(), accid))
|
||||
return AOR_DB_INTERNAL_ERROR; // unexpected error
|
||||
|
||||
return AOR_OK;
|
||||
}
|
||||
|
||||
AccountOpResult AccountMgr::ChangePassword(uint32 accid, std::string new_passwd)
|
||||
{
|
||||
std::string username;
|
||||
|
||||
if (!GetName(accid, username))
|
||||
return AOR_NAME_NOT_EXIST; // account doesn't exist
|
||||
|
||||
if (utf8length(new_passwd) > MAX_ACCOUNT_STR)
|
||||
return AOR_PASS_TOO_LONG;
|
||||
|
||||
normalizeString(username);
|
||||
normalizeString(new_passwd);
|
||||
|
||||
// also reset s and v to force update at next realmd login
|
||||
if (!LoginDatabase.PExecute("UPDATE account SET v='0', s='0', sha_pass_hash='%s' WHERE id='%d'",
|
||||
CalculateShaPassHash(username, new_passwd).c_str(), accid))
|
||||
return AOR_DB_INTERNAL_ERROR; // unexpected error
|
||||
|
||||
return AOR_OK;
|
||||
}
|
||||
|
||||
uint32 AccountMgr::GetId(std::string username)
|
||||
{
|
||||
LoginDatabase.escape_string(username);
|
||||
QueryResult_AutoPtr result = LoginDatabase.PQuery("SELECT id FROM account WHERE username = '%s'", username.c_str());
|
||||
if (!result)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
uint32 id = (*result)[0].GetUInt32();
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 AccountMgr::GetSecurity(uint32 acc_id)
|
||||
{
|
||||
QueryResult_AutoPtr result = LoginDatabase.PQuery("SELECT gmlevel FROM account_access WHERE id = '%u'", acc_id);
|
||||
if (result)
|
||||
{
|
||||
uint32 sec = (*result)[0].GetUInt32();
|
||||
return sec;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 AccountMgr::GetSecurity(uint32 acc_id, int32 realm_id)
|
||||
{
|
||||
QueryResult_AutoPtr result = (realm_id == -1)
|
||||
? LoginDatabase.PQuery("SELECT gmlevel FROM account_access WHERE id = '%u' AND RealmID = '%d'", acc_id, realm_id)
|
||||
: LoginDatabase.PQuery("SELECT gmlevel FROM account_access WHERE id = '%u' AND (RealmID = '%d' OR RealmID = '-1')", acc_id, realm_id);
|
||||
if (result)
|
||||
{
|
||||
uint32 sec = (*result)[0].GetUInt32();
|
||||
return sec;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool AccountMgr::GetName(uint32 acc_id, std::string &name)
|
||||
{
|
||||
QueryResult_AutoPtr result = LoginDatabase.PQuery("SELECT username FROM account WHERE id = '%u'", acc_id);
|
||||
if (result)
|
||||
{
|
||||
name = (*result)[0].GetCppString();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AccountMgr::CheckPassword(uint32 accid, std::string passwd)
|
||||
{
|
||||
std::string username;
|
||||
if (!GetName(accid, username))
|
||||
return false;
|
||||
|
||||
normalizeString(username);
|
||||
normalizeString(passwd);
|
||||
|
||||
QueryResult_AutoPtr result = LoginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d' AND sha_pass_hash='%s'", accid, CalculateShaPassHash(username, passwd).c_str());
|
||||
if (result)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AccountMgr::normalizeString(std::string& utf8str)
|
||||
{
|
||||
wchar_t wstr_buf[MAX_ACCOUNT_STR+1];
|
||||
|
||||
size_t wstr_len = MAX_ACCOUNT_STR;
|
||||
if (!Utf8toWStr(utf8str,wstr_buf,wstr_len))
|
||||
return false;
|
||||
|
||||
std::transform(&wstr_buf[0], wstr_buf+wstr_len, &wstr_buf[0], wcharToUpperOnlyLatin);
|
||||
|
||||
return WStrToUtf8(wstr_buf,wstr_len,utf8str);
|
||||
}
|
||||
|
||||
std::string AccountMgr::CalculateShaPassHash(std::string& name, std::string& password)
|
||||
{
|
||||
Sha1Hash sha;
|
||||
sha.Initialize();
|
||||
sha.UpdateData(name);
|
||||
sha.UpdateData(":");
|
||||
sha.UpdateData(password);
|
||||
sha.Finalize();
|
||||
|
||||
std::string encoded;
|
||||
hexEncodeByteArray(sha.GetDigest(), sha.GetLength(), encoded);
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _ACCMGR_H
|
||||
#define _ACCMGR_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "Common.h"
|
||||
#include "Policies/Singleton.h"
|
||||
|
||||
enum AccountOpResult
|
||||
{
|
||||
AOR_OK,
|
||||
AOR_NAME_TOO_LONG,
|
||||
AOR_PASS_TOO_LONG,
|
||||
AOR_NAME_ALREDY_EXIST,
|
||||
AOR_NAME_NOT_EXIST,
|
||||
AOR_DB_INTERNAL_ERROR
|
||||
};
|
||||
|
||||
#define MAX_ACCOUNT_STR 16
|
||||
|
||||
class AccountMgr
|
||||
{
|
||||
public:
|
||||
AccountMgr();
|
||||
~AccountMgr();
|
||||
|
||||
AccountOpResult CreateAccount(std::string username, std::string password);
|
||||
AccountOpResult DeleteAccount(uint32 accid);
|
||||
AccountOpResult ChangeUsername(uint32 accid, std::string new_uname, std::string new_passwd);
|
||||
AccountOpResult ChangePassword(uint32 accid, std::string new_passwd);
|
||||
bool CheckPassword(uint32 accid, std::string passwd);
|
||||
|
||||
uint32 GetId(std::string username);
|
||||
uint32 GetSecurity(uint32 acc_id);
|
||||
uint32 GetSecurity(uint32 acc_id, int32 realm_id);
|
||||
bool GetName(uint32 acc_id, std::string &name);
|
||||
std::string CalculateShaPassHash(std::string& name, std::string& password);
|
||||
|
||||
static bool normalizeString(std::string& utf8str);
|
||||
};
|
||||
|
||||
#define accmgr Trinity::Singleton<AccountMgr>::Instance()
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,346 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __TRINITY_ACHIEVEMENTMGR_H
|
||||
#define __TRINITY_ACHIEVEMENTMGR_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "Common.h"
|
||||
#include "Policies/Singleton.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "DBCEnums.h"
|
||||
#include "DBCStores.h"
|
||||
|
||||
typedef std::list<AchievementCriteriaEntry const*> AchievementCriteriaEntryList;
|
||||
typedef std::list<AchievementEntry const*> AchievementEntryList;
|
||||
|
||||
typedef std::map<uint32,AchievementCriteriaEntryList> AchievementCriteriaListByAchievement;
|
||||
typedef std::map<uint32,AchievementEntryList> AchievementListByReferencedId;
|
||||
|
||||
struct CriteriaProgress
|
||||
{
|
||||
uint32 counter;
|
||||
time_t date;
|
||||
bool changed;
|
||||
};
|
||||
|
||||
enum AchievementCriteriaDataType
|
||||
{ // value1 value2 comment
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE = 0, // 0 0
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_CREATURE = 1, // creature_id 0
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE = 2, // class_id race_id
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_LESS_HEALTH= 3, // health_percent 0
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD = 4, // own_team 0 not corpse (not released body), own_team == false if enemy team expected
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA = 5, // spell_id effect_idx
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA = 6, // area id 0
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA = 7, // spell_id effect_idx
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_VALUE = 8, // minvalue value provided with achievement update must be not less that limit
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_LEVEL = 9, // minlevel minlevel of target
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_GENDER = 10,// gender 0=male; 1=female
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_DISABLED = 11,// used to prevent achievement creteria complete if not all requirement implemented and listed in table
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY = 12,// difficulty normal/heroic difficulty for current event map
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT = 13,// count "with less than %u people in the zone"
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM = 14,// team HORDE(67), ALLIANCE(469)
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_DRUNK = 15,// drunken_state 0 (enum DrunkenState) of player
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY = 16,// holiday_id 0 event in holiday time
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE = 17,// min_score max_score player's team win bg and opposition team have team score in range
|
||||
ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT = 18,// 0 0 maker instance script call for check current criteria requirements fit
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM = 19,// item_level item_quality for equipped item in slot to check item level and quality
|
||||
};
|
||||
|
||||
#define MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE 20 // maximum value in AchievementCriteriaDataType enum
|
||||
|
||||
class Player;
|
||||
class Unit;
|
||||
|
||||
struct AchievementCriteriaData
|
||||
{
|
||||
AchievementCriteriaDataType dataType;
|
||||
union
|
||||
{
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE = 0 (no data)
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_CREATURE = 1
|
||||
struct
|
||||
{
|
||||
uint32 id;
|
||||
} creature;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE = 2
|
||||
struct
|
||||
{
|
||||
uint32 class_id;
|
||||
uint32 race_id;
|
||||
} classRace;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_LESS_HEALTH = 3
|
||||
struct
|
||||
{
|
||||
uint32 percent;
|
||||
} health;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD = 4
|
||||
struct
|
||||
{
|
||||
uint32 own_team_flag;
|
||||
} player_dead;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA = 5
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA = 7
|
||||
struct
|
||||
{
|
||||
uint32 spell_id;
|
||||
uint32 effect_idx;
|
||||
} aura;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA = 6
|
||||
struct
|
||||
{
|
||||
uint32 id;
|
||||
} area;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_VALUE = 8
|
||||
struct
|
||||
{
|
||||
uint32 minvalue;
|
||||
} value;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_LEVEL = 9
|
||||
struct
|
||||
{
|
||||
uint32 minlevel;
|
||||
} level;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_GENDER = 10
|
||||
struct
|
||||
{
|
||||
uint32 gender;
|
||||
} gender;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_DISABLED = 11 (no data)
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY = 12
|
||||
struct
|
||||
{
|
||||
uint32 difficulty;
|
||||
} difficulty;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT = 13
|
||||
struct
|
||||
{
|
||||
uint32 maxcount;
|
||||
} map_players;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM = 14
|
||||
struct
|
||||
{
|
||||
uint32 team;
|
||||
} team;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_S_DRUNK = 15
|
||||
struct
|
||||
{
|
||||
uint32 state;
|
||||
} drunk;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY = 16
|
||||
struct
|
||||
{
|
||||
uint32 id;
|
||||
} holiday;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE= 17
|
||||
struct
|
||||
{
|
||||
uint32 min_score;
|
||||
uint32 max_score;
|
||||
} bg_loss_team_score;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT = 18 (no data)
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM = 19
|
||||
struct
|
||||
{
|
||||
uint32 item_level;
|
||||
uint32 item_quality;
|
||||
} equipped_item;
|
||||
// ...
|
||||
struct
|
||||
{
|
||||
uint32 value1;
|
||||
uint32 value2;
|
||||
} raw;
|
||||
};
|
||||
|
||||
AchievementCriteriaData() : dataType(ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE)
|
||||
{
|
||||
raw.value1 = 0;
|
||||
raw.value2 = 0;
|
||||
}
|
||||
|
||||
AchievementCriteriaData(uint32 _dataType, uint32 _value1, uint32 _value2) : dataType(AchievementCriteriaDataType(_dataType))
|
||||
{
|
||||
raw.value1 = _value1;
|
||||
raw.value2 = _value2;
|
||||
}
|
||||
|
||||
bool IsValid(AchievementCriteriaEntry const* criteria);
|
||||
bool Meets(uint32 criteria_id, Player const* source, Unit const* target, uint32 miscvalue1 = 0) const;
|
||||
};
|
||||
|
||||
struct AchievementCriteriaDataSet
|
||||
{
|
||||
AchievementCriteriaDataSet() : criteria_id(0) {}
|
||||
typedef std::vector<AchievementCriteriaData> Storage;
|
||||
void Add(AchievementCriteriaData const& data) { storage.push_back(data); }
|
||||
bool Meets(Player const* source, Unit const* target, uint32 miscvalue = 0) const;
|
||||
void SetCriteriaId(uint32 id) {criteria_id = id;}
|
||||
private:
|
||||
uint32 criteria_id;
|
||||
Storage storage;
|
||||
};
|
||||
|
||||
typedef std::map<uint32,AchievementCriteriaDataSet> AchievementCriteriaDataMap;
|
||||
|
||||
struct AchievementReward
|
||||
{
|
||||
uint32 titleId[2];
|
||||
uint32 itemId;
|
||||
uint32 sender;
|
||||
std::string subject;
|
||||
std::string text;
|
||||
};
|
||||
|
||||
typedef std::map<uint32,AchievementReward> AchievementRewards;
|
||||
|
||||
struct AchievementRewardLocale
|
||||
{
|
||||
std::vector<std::string> subject;
|
||||
std::vector<std::string> text;
|
||||
};
|
||||
|
||||
typedef std::map<uint32,AchievementRewardLocale> AchievementRewardLocales;
|
||||
|
||||
struct CompletedAchievementData
|
||||
{
|
||||
time_t date;
|
||||
bool changed;
|
||||
};
|
||||
|
||||
typedef UNORDERED_MAP<uint32, CriteriaProgress> CriteriaProgressMap;
|
||||
typedef UNORDERED_MAP<uint32, CompletedAchievementData> CompletedAchievementMap;
|
||||
|
||||
class Unit;
|
||||
class Player;
|
||||
class WorldPacket;
|
||||
|
||||
class AchievementMgr
|
||||
{
|
||||
public:
|
||||
AchievementMgr(Player* pl);
|
||||
~AchievementMgr();
|
||||
|
||||
void Reset();
|
||||
static void DeleteFromDB(uint32 lowguid);
|
||||
void LoadFromDB(QueryResult_AutoPtr achievementResult, QueryResult_AutoPtr criteriaResult);
|
||||
void SaveToDB();
|
||||
void ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1=0, uint32 miscvalue2=0);
|
||||
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1=0, uint32 miscvalue2=0, Unit *unit=NULL, uint32 time=0);
|
||||
void CompletedAchievement(AchievementEntry const* entry);
|
||||
void CheckAllAchievementCriteria();
|
||||
void SendAllAchievementData();
|
||||
void SendRespondInspectAchievements(Player* player);
|
||||
bool HasAchieved(AchievementEntry const* achievement) const;
|
||||
Player* GetPlayer() { return m_player; }
|
||||
void UpdateTimedAchievements(uint32 timeDiff);
|
||||
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry);
|
||||
void RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry); // used for quest and scripted timed achievements
|
||||
|
||||
private:
|
||||
enum ProgressType { PROGRESS_SET, PROGRESS_ACCUMULATE, PROGRESS_HIGHEST };
|
||||
void SendAchievementEarned(AchievementEntry const* achievement);
|
||||
void SendCriteriaUpdate(AchievementCriteriaEntry const* entry, CriteriaProgress const* progress, uint32 timeElapsed, bool timedCompleted);
|
||||
void SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, ProgressType ptype = PROGRESS_SET);
|
||||
void CompletedCriteriaFor(AchievementEntry const* achievement);
|
||||
bool IsCompletedCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement);
|
||||
bool IsCompletedAchievement(AchievementEntry const* entry);
|
||||
void CompleteAchievementsWithRefs(AchievementEntry const* entry);
|
||||
void BuildAllDataPacket(WorldPacket *data);
|
||||
|
||||
Player* m_player;
|
||||
CriteriaProgressMap m_criteriaProgress;
|
||||
CompletedAchievementMap m_completedAchievements;
|
||||
typedef std::map<uint32, uint32> TimedAchievementMap;
|
||||
TimedAchievementMap m_timedAchievements; // Criteria id/time left in MS
|
||||
};
|
||||
|
||||
class AchievementGlobalMgr
|
||||
{
|
||||
public:
|
||||
AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type);
|
||||
AchievementCriteriaEntryList const& GetTimedAchievementCriteriaByType(AchievementCriteriaTimedTypes type);
|
||||
AchievementCriteriaEntryList const* GetAchievementCriteriaByAchievement(uint32 id)
|
||||
{
|
||||
AchievementCriteriaListByAchievement::const_iterator itr = m_AchievementCriteriaListByAchievement.find(id);
|
||||
return itr != m_AchievementCriteriaListByAchievement.end() ? &itr->second : NULL;
|
||||
}
|
||||
|
||||
AchievementEntryList const* GetAchievementByReferencedId(uint32 id) const
|
||||
{
|
||||
AchievementListByReferencedId::const_iterator itr = m_AchievementListByReferencedId.find(id);
|
||||
return itr != m_AchievementListByReferencedId.end() ? &itr->second : NULL;
|
||||
}
|
||||
|
||||
AchievementReward const* GetAchievementReward(AchievementEntry const* achievement) const
|
||||
{
|
||||
AchievementRewards::const_iterator iter = m_achievementRewards.find(achievement->ID);
|
||||
return iter != m_achievementRewards.end() ? &iter->second : NULL;
|
||||
}
|
||||
|
||||
AchievementRewardLocale const* GetAchievementRewardLocale(AchievementEntry const* achievement) const
|
||||
{
|
||||
AchievementRewardLocales::const_iterator iter = m_achievementRewardLocales.find(achievement->ID);
|
||||
return iter != m_achievementRewardLocales.end() ? &iter->second : NULL;
|
||||
}
|
||||
|
||||
AchievementCriteriaDataSet const* GetCriteriaDataSet(AchievementCriteriaEntry const *achievementCriteria)
|
||||
{
|
||||
AchievementCriteriaDataMap::const_iterator iter = m_criteriaDataMap.find(achievementCriteria->ID);
|
||||
return iter != m_criteriaDataMap.end() ? &iter->second : NULL;
|
||||
}
|
||||
|
||||
bool IsRealmCompleted(AchievementEntry const* achievement) const
|
||||
{
|
||||
return m_allCompletedAchievements.find(achievement->ID) != m_allCompletedAchievements.end();
|
||||
}
|
||||
|
||||
void SetRealmCompleted(AchievementEntry const* achievement)
|
||||
{
|
||||
m_allCompletedAchievements.insert(achievement->ID);
|
||||
}
|
||||
|
||||
void LoadAchievementCriteriaList();
|
||||
void LoadAchievementCriteriaData();
|
||||
void LoadAchievementReferenceList();
|
||||
void LoadCompletedAchievements();
|
||||
void LoadRewards();
|
||||
void LoadRewardLocales();
|
||||
private:
|
||||
AchievementCriteriaDataMap m_criteriaDataMap;
|
||||
|
||||
// store achievement criterias by type to speed up lookup
|
||||
AchievementCriteriaEntryList m_AchievementCriteriasByType[ACHIEVEMENT_CRITERIA_TYPE_TOTAL];
|
||||
AchievementCriteriaEntryList m_AchievementCriteriasByTimedType[ACHIEVEMENT_TIMED_TYPE_MAX];
|
||||
// store achievement criterias by achievement to speed up lookup
|
||||
AchievementCriteriaListByAchievement m_AchievementCriteriaListByAchievement;
|
||||
// store achievements by referenced achievement id to speed up lookup
|
||||
AchievementListByReferencedId m_AchievementListByReferencedId;
|
||||
|
||||
typedef std::set<uint32> AllCompletedAchievements;
|
||||
AllCompletedAchievements m_allCompletedAchievements;
|
||||
|
||||
AchievementRewards m_achievementRewards;
|
||||
AchievementRewardLocales m_achievementRewardLocales;
|
||||
};
|
||||
|
||||
#define achievementmgr Trinity::Singleton<AchievementGlobalMgr>::Instance()
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "zlib/zlib.h"
|
||||
|
||||
#include "AddonHandler.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "Policies/SingletonImp.h"
|
||||
#include "Opcodes.h"
|
||||
|
||||
#include "Log.h"
|
||||
|
||||
INSTANTIATE_SINGLETON_1( AddonHandler );
|
||||
|
||||
AddonHandler::AddonHandler()
|
||||
{
|
||||
}
|
||||
|
||||
AddonHandler::~AddonHandler()
|
||||
{
|
||||
}
|
||||
|
||||
bool AddonHandler::BuildAddonPacket(WorldPacket *Source, WorldPacket *Target)
|
||||
{
|
||||
ByteBuffer AddOnPacked;
|
||||
uLongf AddonRealSize;
|
||||
uint32 CurrentPosition;
|
||||
uint32 TempValue;
|
||||
|
||||
unsigned char tdata[256] =
|
||||
{
|
||||
0xC3, 0x5B, 0x50, 0x84, 0xB9, 0x3E, 0x32, 0x42, 0x8C, 0xD0, 0xC7, 0x48, 0xFA, 0x0E, 0x5D, 0x54,
|
||||
0x5A, 0xA3, 0x0E, 0x14, 0xBA, 0x9E, 0x0D, 0xB9, 0x5D, 0x8B, 0xEE, 0xB6, 0x84, 0x93, 0x45, 0x75,
|
||||
0xFF, 0x31, 0xFE, 0x2F, 0x64, 0x3F, 0x3D, 0x6D, 0x07, 0xD9, 0x44, 0x9B, 0x40, 0x85, 0x59, 0x34,
|
||||
0x4E, 0x10, 0xE1, 0xE7, 0x43, 0x69, 0xEF, 0x7C, 0x16, 0xFC, 0xB4, 0xED, 0x1B, 0x95, 0x28, 0xA8,
|
||||
0x23, 0x76, 0x51, 0x31, 0x57, 0x30, 0x2B, 0x79, 0x08, 0x50, 0x10, 0x1C, 0x4A, 0x1A, 0x2C, 0xC8,
|
||||
0x8B, 0x8F, 0x05, 0x2D, 0x22, 0x3D, 0xDB, 0x5A, 0x24, 0x7A, 0x0F, 0x13, 0x50, 0x37, 0x8F, 0x5A,
|
||||
0xCC, 0x9E, 0x04, 0x44, 0x0E, 0x87, 0x01, 0xD4, 0xA3, 0x15, 0x94, 0x16, 0x34, 0xC6, 0xC2, 0xC3,
|
||||
0xFB, 0x49, 0xFE, 0xE1, 0xF9, 0xDA, 0x8C, 0x50, 0x3C, 0xBE, 0x2C, 0xBB, 0x57, 0xED, 0x46, 0xB9,
|
||||
0xAD, 0x8B, 0xC6, 0xDF, 0x0E, 0xD6, 0x0F, 0xBE, 0x80, 0xB3, 0x8B, 0x1E, 0x77, 0xCF, 0xAD, 0x22,
|
||||
0xCF, 0xB7, 0x4B, 0xCF, 0xFB, 0xF0, 0x6B, 0x11, 0x45, 0x2D, 0x7A, 0x81, 0x18, 0xF2, 0x92, 0x7E,
|
||||
0x98, 0x56, 0x5D, 0x5E, 0x69, 0x72, 0x0A, 0x0D, 0x03, 0x0A, 0x85, 0xA2, 0x85, 0x9C, 0xCB, 0xFB,
|
||||
0x56, 0x6E, 0x8F, 0x44, 0xBB, 0x8F, 0x02, 0x22, 0x68, 0x63, 0x97, 0xBC, 0x85, 0xBA, 0xA8, 0xF7,
|
||||
0xB5, 0x40, 0x68, 0x3C, 0x77, 0x86, 0x6F, 0x4B, 0xD7, 0x88, 0xCA, 0x8A, 0xD7, 0xCE, 0x36, 0xF0,
|
||||
0x45, 0x6E, 0xD5, 0x64, 0x79, 0x0F, 0x17, 0xFC, 0x64, 0xDD, 0x10, 0x6F, 0xF3, 0xF5, 0xE0, 0xA6,
|
||||
0xC3, 0xFB, 0x1B, 0x8C, 0x29, 0xEF, 0x8E, 0xE5, 0x34, 0xCB, 0xD1, 0x2A, 0xCE, 0x79, 0xC3, 0x9A,
|
||||
0x0D, 0x36, 0xEA, 0x01, 0xE0, 0xAA, 0x91, 0x20, 0x54, 0xF0, 0x72, 0xD8, 0x1E, 0xC7, 0x89, 0xD2
|
||||
};
|
||||
|
||||
// broken addon packet, can't be received from real client
|
||||
if (Source->rpos() + 4 > Source->size())
|
||||
return false;
|
||||
|
||||
*Source >> TempValue; // get real size of the packed structure
|
||||
|
||||
// empty addon packet, nothing process, can't be received from real client
|
||||
if(!TempValue)
|
||||
return false;
|
||||
|
||||
AddonRealSize = TempValue; // temp value because ZLIB only excepts uLongf
|
||||
|
||||
CurrentPosition = Source->rpos(); // get the position of the pointer in the structure
|
||||
|
||||
AddOnPacked.resize(AddonRealSize); // resize target for zlib action
|
||||
|
||||
if (!uncompress(const_cast<uint8*>(AddOnPacked.contents()), &AddonRealSize, const_cast<uint8*>((*Source).contents() + CurrentPosition), (*Source).size() - CurrentPosition)!= Z_OK)
|
||||
{
|
||||
Target->Initialize(SMSG_ADDON_INFO);
|
||||
|
||||
uint32 addonsCount;
|
||||
AddOnPacked >> addonsCount; // addons count?
|
||||
|
||||
for(uint32 i = 0; i < addonsCount; ++i)
|
||||
{
|
||||
std::string addonName;
|
||||
uint8 enabled;
|
||||
uint32 crc, unk2;
|
||||
|
||||
// check next addon data format correctness
|
||||
if(AddOnPacked.rpos()+1 > AddOnPacked.size())
|
||||
return false;
|
||||
|
||||
AddOnPacked >> addonName;
|
||||
|
||||
// recheck next addon data format correctness
|
||||
if(AddOnPacked.rpos()+1+4+4 > AddOnPacked.size())
|
||||
return false;
|
||||
|
||||
AddOnPacked >> enabled >> crc >> unk2;
|
||||
|
||||
sLog.outDebug("ADDON: Name: %s, Enabled: 0x%x, CRC: 0x%x, Unknown2: 0x%x", addonName.c_str(), enabled, crc, unk2);
|
||||
|
||||
uint8 state = (enabled ? 2 : 1);
|
||||
*Target << uint8(state);
|
||||
|
||||
uint8 unk1 = (enabled ? 1 : 0);
|
||||
*Target << uint8(unk1);
|
||||
if (unk1)
|
||||
{
|
||||
uint8 unk2 = (crc != 0x4c1c776d); // If addon is Standard addon CRC
|
||||
*Target << uint8(unk2);
|
||||
if (unk2)
|
||||
Target->append(tdata, sizeof(tdata));
|
||||
|
||||
*Target << uint32(0);
|
||||
}
|
||||
|
||||
uint8 unk3 = (enabled ? 0 : 1);
|
||||
*Target << uint8(unk3);
|
||||
if (unk3)
|
||||
{
|
||||
// String, 256 (null terminated?)
|
||||
*Target << uint8(0);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 unk4;
|
||||
AddOnPacked >> unk4;
|
||||
|
||||
uint32 count = 0;
|
||||
*Target << uint32(count);
|
||||
/*for(uint32 i = 0; i < count; ++i)
|
||||
{
|
||||
uint32
|
||||
string (16 bytes)
|
||||
string (16 bytes)
|
||||
uint32
|
||||
}*/
|
||||
|
||||
if(AddOnPacked.rpos() != AddOnPacked.size())
|
||||
sLog.outDebug("packet under read!");
|
||||
}
|
||||
else
|
||||
{
|
||||
sLog.outError("Addon packet uncompress error :(");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Code use in 1.10.2 when client not ignore ban state sended for addons. Saved for reference if client switch to use server ban state information
|
||||
void AddonHandler::BuildAddonPacket(WorldPacket* Source, WorldPacket* Target, uint32 Packetoffset)
|
||||
{
|
||||
ByteBuffer AddOnPacked;
|
||||
uLongf AddonRealSize;
|
||||
uint32 CurrentPosition;
|
||||
uint32 TempValue;
|
||||
|
||||
*Source >> TempValue; //get real size of the packed structure
|
||||
|
||||
AddonRealSize = TempValue; //temp value becouse ZLIB only excepts uLongf
|
||||
|
||||
CurrentPosition = Source->rpos(); //get the position of the pointer in the structure
|
||||
|
||||
AddOnPacked.resize(AddonRealSize); //resize target for zlib action
|
||||
|
||||
if (!uncompress((uint8*)AddOnPacked.contents(), &AddonRealSize, (uint8*)(*Source).contents() + CurrentPosition, (*Source).size() - CurrentPosition)!= Z_OK)
|
||||
{
|
||||
bool* AddonAllowed = new bool; //handle addon check and enable-ing
|
||||
|
||||
uint32 Unknown1;
|
||||
uint8 Unknown0;
|
||||
|
||||
AddOnPacked >> Unknown0;
|
||||
AddOnPacked >> Unknown1;
|
||||
|
||||
Target->Initialize(SMSG_ADDON_INFO);
|
||||
|
||||
uint32 i = 5; //offset for addon extraction
|
||||
while(i != AddOnPacked.size())
|
||||
{
|
||||
std::string AddonNames;
|
||||
AddOns* Addonstr = new AddOns;
|
||||
uint8 unk6;
|
||||
uint64 CRCCHECK;
|
||||
AddOnPacked >> AddonNames >> CRCCHECK >> unk6;
|
||||
|
||||
//sLog.outDebug("ADDON: Name:%s CRC:%x Unknown:%x",AddonNames.c_str(), CRCCHECK,unk6);
|
||||
|
||||
Addonstr->Name = AddonNames;
|
||||
Addonstr->CRC = CRCCHECK;
|
||||
|
||||
//if not allowed but unknown added to list
|
||||
if (GetAddonStatus(Addonstr, AddonAllowed)) // If addon is new
|
||||
{
|
||||
Addonstr->Enabled = m_Addon_Default; // by default new addons are set from Config file
|
||||
*AddonAllowed = m_Addon_Default; // Set addon allowed on default value
|
||||
_AddAddon(Addonstr);
|
||||
sLog.outDetail("Found new Addon, Name:%s CRC:%x Unknown:%x",AddonNames.c_str(), CRCCHECK, unk6);
|
||||
}
|
||||
|
||||
if (CRCCHECK == 0x4C1C776D01LL) //If addon is Standard addon CRC
|
||||
{
|
||||
//value's standard Addons
|
||||
*Target << uint8(0) << uint8(2) << uint8(1) << uint8(0) << uint32(0);
|
||||
}
|
||||
else if (*AddonAllowed) //if addon is Custom addons
|
||||
//value's enable addon
|
||||
*Target << uint8(0x00) << uint8(0x01) << uint8(0x00) << uint8(0x01);
|
||||
else
|
||||
//value's disable addom
|
||||
*Target << uint8(0x00) << uint8(0x0) << uint8(0x00) << uint8(0x0);
|
||||
|
||||
i += AddonNames.size() + 10;
|
||||
}
|
||||
*Target << uint8(0x0);
|
||||
|
||||
//delete mem allocation
|
||||
delete AddonAllowed;
|
||||
}
|
||||
else
|
||||
{
|
||||
//handle uncompress error
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __ADDONHANDLER_H
|
||||
#define __ADDONHANDLER_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "Config/ConfigEnv.h"
|
||||
#include "Policies/Singleton.h"
|
||||
|
||||
#include "WorldPacket.h"
|
||||
|
||||
class AddonHandler
|
||||
{
|
||||
public:
|
||||
/* Construction */
|
||||
AddonHandler();
|
||||
~AddonHandler();
|
||||
//built addon packet
|
||||
bool BuildAddonPacket(WorldPacket* Source, WorldPacket* Target);
|
||||
};
|
||||
#define sAddOnHandler Trinity::Singleton<AddonHandler>::Instance()
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "Policies/SingletonImp.h"
|
||||
|
||||
#include "AddonMgr.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Player.h"
|
||||
#include "Util.h"
|
||||
#include "Auth/Sha1.h"
|
||||
#include "ProgressBar.h"
|
||||
|
||||
extern DatabaseType LoginDatabase;
|
||||
|
||||
INSTANTIATE_SINGLETON_1(AddonMgr);
|
||||
|
||||
AddonMgr::AddonMgr()
|
||||
{
|
||||
}
|
||||
|
||||
AddonMgr::~AddonMgr()
|
||||
{
|
||||
}
|
||||
|
||||
void AddonMgr::LoadFromDB()
|
||||
{
|
||||
QueryResult_AutoPtr result = CharacterDatabase.Query("SELECT name, crc FROM addons");
|
||||
if (!result)
|
||||
{
|
||||
sLog.outErrorDb("The table `addons` is empty");
|
||||
return;
|
||||
}
|
||||
|
||||
barGoLink bar(result->GetRowCount());
|
||||
uint32 count = 0;
|
||||
Field *fields;
|
||||
|
||||
do
|
||||
{
|
||||
fields = result->Fetch();
|
||||
bar.step();
|
||||
count++;
|
||||
|
||||
std::string name = fields[0].GetCppString();
|
||||
uint32 crc = fields[1].GetUInt32();
|
||||
|
||||
SavedAddon addon(name, crc);
|
||||
m_knownAddons.push_back(addon);
|
||||
} while (result->NextRow());
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded %u known addons", count);
|
||||
}
|
||||
|
||||
void AddonMgr::SaveAddon(AddonInfo const& addon)
|
||||
{
|
||||
std::string name = addon.Name;
|
||||
CharacterDatabase.escape_string(name);
|
||||
CharacterDatabase.PExecute("INSERT INTO addons (name, crc) VALUES ('%s', %u)", name.c_str(), addon.CRC);
|
||||
|
||||
SavedAddon newAddon(addon.Name, addon.CRC);
|
||||
m_knownAddons.push_back(newAddon);
|
||||
}
|
||||
|
||||
SavedAddon const* AddonMgr::GetAddonInfo(const std::string& name) const
|
||||
{
|
||||
for (SavedAddonsList::const_iterator it = m_knownAddons.begin(); it != m_knownAddons.end(); ++it)
|
||||
{
|
||||
SavedAddon const& addon = (*it);
|
||||
if (addon.Name == name)
|
||||
return &addon;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _ADDONMGR_H
|
||||
#define _ADDONMGR_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "Policies/Singleton.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
class WorldSession;
|
||||
|
||||
struct AddonInfo
|
||||
{
|
||||
AddonInfo(const std::string& name, uint8 enabled, uint32 crc, uint8 state, bool crcOrPubKey)
|
||||
{
|
||||
Name = name;
|
||||
Enabled = enabled;
|
||||
CRC = crc;
|
||||
State = state;
|
||||
UsePublicKeyOrCRC = crcOrPubKey;
|
||||
}
|
||||
|
||||
std::string Name;
|
||||
uint8 Enabled;
|
||||
uint32 CRC;
|
||||
uint8 State;
|
||||
bool UsePublicKeyOrCRC;
|
||||
};
|
||||
|
||||
struct SavedAddon
|
||||
{
|
||||
SavedAddon(const std::string& name, uint32 crc)
|
||||
{
|
||||
Name = name;
|
||||
CRC = crc;
|
||||
}
|
||||
|
||||
std::string Name;
|
||||
uint32 CRC;
|
||||
};
|
||||
|
||||
// List of client addons (for WorldSession).
|
||||
typedef std::list<AddonInfo> AddonsList;
|
||||
|
||||
// List of saved addons (in DB).
|
||||
typedef std::list<SavedAddon> SavedAddonsList;
|
||||
|
||||
#define STANDARD_ADDON_CRC 0x4c1c776d
|
||||
|
||||
class AddonMgr
|
||||
{
|
||||
public:
|
||||
|
||||
AddonMgr();
|
||||
~AddonMgr();
|
||||
|
||||
void LoadFromDB();
|
||||
void SaveAddon(AddonInfo const& addon);
|
||||
|
||||
SavedAddon const* GetAddonInfo(const std::string& name) const;
|
||||
|
||||
private:
|
||||
|
||||
SavedAddonsList m_knownAddons; // Known addons.
|
||||
};
|
||||
|
||||
#define sAddonMgr Trinity::Singleton<AddonMgr>::Instance()
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,764 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "ObjectMgr.h"
|
||||
#include "WorldPacket.h"
|
||||
|
||||
#include "ArenaTeam.h"
|
||||
#include "World.h"
|
||||
|
||||
void ArenaTeamMember::ModifyPersonalRating(Player* plr, int32 mod, uint32 slot)
|
||||
{
|
||||
if (int32(personal_rating) + mod < 0)
|
||||
personal_rating = 0;
|
||||
else
|
||||
personal_rating += mod;
|
||||
if (plr)
|
||||
plr->SetArenaTeamInfoField(slot, ARENA_TEAM_PERSONAL_RATING, personal_rating);
|
||||
}
|
||||
|
||||
ArenaTeam::ArenaTeam()
|
||||
{
|
||||
m_TeamId = 0;
|
||||
m_Type = 0;
|
||||
m_Name = "";
|
||||
m_CaptainGuid = 0;
|
||||
m_BackgroundColor = 0; // background
|
||||
m_EmblemStyle = 0; // icon
|
||||
m_EmblemColor = 0; // icon color
|
||||
m_BorderStyle = 0; // border
|
||||
m_BorderColor = 0; // border color
|
||||
m_stats.games_week = 0;
|
||||
m_stats.games_season = 0;
|
||||
m_stats.rank = 0;
|
||||
if (sWorld.getConfig(CONFIG_ARENA_START_RATING) >= 0)
|
||||
m_stats.rating = sWorld.getConfig(CONFIG_ARENA_START_RATING);
|
||||
else if (sWorld.getConfig(CONFIG_ARENA_SEASON_ID) >= 6)
|
||||
m_stats.rating = 0;
|
||||
else
|
||||
m_stats.rating = 1500;
|
||||
m_stats.wins_week = 0;
|
||||
m_stats.wins_season = 0;
|
||||
}
|
||||
|
||||
ArenaTeam::~ArenaTeam()
|
||||
{
|
||||
}
|
||||
|
||||
bool ArenaTeam::Create(uint64 captainGuid, uint32 type, std::string ArenaTeamName)
|
||||
{
|
||||
if (!objmgr.GetPlayer(captainGuid)) // player not exist
|
||||
return false;
|
||||
if (objmgr.GetArenaTeamByName(ArenaTeamName)) // arena team with this name already exist
|
||||
return false;
|
||||
|
||||
sLog.outDebug("GUILD: creating arena team %s to leader: %u", ArenaTeamName.c_str(), GUID_LOPART(captainGuid));
|
||||
|
||||
m_CaptainGuid = captainGuid;
|
||||
m_Name = ArenaTeamName;
|
||||
m_Type = type;
|
||||
|
||||
m_TeamId = objmgr.GenerateArenaTeamId();
|
||||
|
||||
// ArenaTeamName already assigned to ArenaTeam::name, use it to encode string for DB
|
||||
CharacterDatabase.escape_string(ArenaTeamName);
|
||||
|
||||
CharacterDatabase.BeginTransaction();
|
||||
// CharacterDatabase.PExecute("DELETE FROM arena_team WHERE arenateamid='%u'", m_TeamId); - MAX(arenateam)+1 not exist
|
||||
CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid='%u'", m_TeamId);
|
||||
CharacterDatabase.PExecute("INSERT INTO arena_team (arenateamid,name,captainguid,type,BackgroundColor,EmblemStyle,EmblemColor,BorderStyle,BorderColor) "
|
||||
"VALUES('%u','%s','%u','%u','%u','%u','%u','%u','%u')",
|
||||
m_TeamId, ArenaTeamName.c_str(), GUID_LOPART(m_CaptainGuid), m_Type, m_BackgroundColor, m_EmblemStyle, m_EmblemColor, m_BorderStyle, m_BorderColor);
|
||||
CharacterDatabase.PExecute("INSERT INTO arena_team_stats (arenateamid, rating, games, wins, played, wins2, rank) VALUES "
|
||||
"('%u', '%u', '%u', '%u', '%u', '%u', '%u')", m_TeamId, m_stats.rating, m_stats.games_week, m_stats.wins_week, m_stats.games_season, m_stats.wins_season, m_stats.rank);
|
||||
|
||||
CharacterDatabase.CommitTransaction();
|
||||
|
||||
AddMember(m_CaptainGuid);
|
||||
sLog.outArena("New ArenaTeam created [Id: %u] [Type: %u] [Captain GUID: %u]", GetId(), GetType(), GetCaptain());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArenaTeam::AddMember(const uint64& PlayerGuid)
|
||||
{
|
||||
std::string plName;
|
||||
uint8 plClass;
|
||||
|
||||
// arena team is full (can't have more than type * 2 players!)
|
||||
if (GetMembersSize() >= GetType() * 2)
|
||||
return false;
|
||||
|
||||
Player *pl = objmgr.GetPlayer(PlayerGuid);
|
||||
if (pl)
|
||||
{
|
||||
if (pl->GetArenaTeamId(GetSlot()))
|
||||
{
|
||||
sLog.outError("Arena::AddMember() : player already in this sized team");
|
||||
return false;
|
||||
}
|
||||
|
||||
plClass = pl->getClass();
|
||||
plName = pl->GetName();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 0 1
|
||||
QueryResult_AutoPtr result = CharacterDatabase.PQuery("SELECT name, class FROM characters WHERE guid='%u'", GUID_LOPART(PlayerGuid));
|
||||
if (!result)
|
||||
return false;
|
||||
|
||||
plName = (*result)[0].GetCppString();
|
||||
plClass = (*result)[1].GetUInt8();
|
||||
|
||||
// check if player already in arenateam of that size
|
||||
if (Player::GetArenaTeamIdFromDB(PlayerGuid, GetType()) != 0)
|
||||
{
|
||||
sLog.outError("Arena::AddMember() : player already in this sized team");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// remove all player signs from another petitions
|
||||
// this will be prevent attempt joining player to many arenateams and corrupt arena team data integrity
|
||||
Player::RemovePetitionsAndSigns(PlayerGuid, GetType());
|
||||
|
||||
ArenaTeamMember newmember;
|
||||
newmember.name = plName;
|
||||
newmember.guid = PlayerGuid;
|
||||
newmember.Class = plClass;
|
||||
newmember.games_season = 0;
|
||||
newmember.games_week = 0;
|
||||
newmember.wins_season = 0;
|
||||
newmember.wins_week = 0;
|
||||
newmember.personal_rating = 0;
|
||||
|
||||
if (sWorld.getConfig(CONFIG_ARENA_START_PERSONAL_RATING) > 0)
|
||||
newmember.personal_rating = sWorld.getConfig(CONFIG_ARENA_START_PERSONAL_RATING);
|
||||
else
|
||||
{
|
||||
if (sWorld.getConfig(CONFIG_ARENA_SEASON_ID) < 6)
|
||||
newmember.personal_rating = 1500;
|
||||
else
|
||||
if (GetRating() >= 1000)
|
||||
newmember.personal_rating = 1000;
|
||||
}
|
||||
|
||||
m_members.push_back(newmember);
|
||||
|
||||
CharacterDatabase.PExecute("INSERT INTO arena_team_member (arenateamid, guid, personal_rating) VALUES ('%u', '%u', '%u')", m_TeamId, GUID_LOPART(newmember.guid), newmember.personal_rating);
|
||||
|
||||
if (pl)
|
||||
{
|
||||
pl->SetInArenaTeam(m_TeamId, GetSlot(), GetType());
|
||||
pl->SetArenaTeamIdInvited(0);
|
||||
pl->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_PERSONAL_RATING, newmember.personal_rating);
|
||||
|
||||
// hide promote/remove buttons
|
||||
if (m_CaptainGuid != PlayerGuid)
|
||||
pl->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_MEMBER, 1);
|
||||
sLog.outArena("Player: %s [GUID: %u] joined arena team type: %u [Id: %u].", pl->GetName(), pl->GetGUIDLow(), GetType(), GetId());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArenaTeam::LoadArenaTeamFromDB(QueryResult_AutoPtr arenaTeamDataResult)
|
||||
{
|
||||
if (!arenaTeamDataResult)
|
||||
return false;
|
||||
|
||||
Field *fields = arenaTeamDataResult->Fetch();
|
||||
|
||||
m_TeamId = fields[0].GetUInt32();
|
||||
m_Name = fields[1].GetCppString();
|
||||
m_CaptainGuid = MAKE_NEW_GUID(fields[2].GetUInt32(), 0, HIGHGUID_PLAYER);
|
||||
m_Type = fields[3].GetUInt32();
|
||||
m_BackgroundColor = fields[4].GetUInt32();
|
||||
m_EmblemStyle = fields[5].GetUInt32();
|
||||
m_EmblemColor = fields[6].GetUInt32();
|
||||
m_BorderStyle = fields[7].GetUInt32();
|
||||
m_BorderColor = fields[8].GetUInt32();
|
||||
//load team stats
|
||||
m_stats.rating = fields[9].GetUInt32();
|
||||
m_stats.games_week = fields[10].GetUInt32();
|
||||
m_stats.wins_week = fields[11].GetUInt32();
|
||||
m_stats.games_season = fields[12].GetUInt32();
|
||||
m_stats.wins_season = fields[13].GetUInt32();
|
||||
m_stats.rank = fields[14].GetUInt32();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArenaTeam::LoadMembersFromDB(QueryResult_AutoPtr arenaTeamMembersResult)
|
||||
{
|
||||
if (!arenaTeamMembersResult)
|
||||
return false;
|
||||
|
||||
bool captainPresentInTeam = false;
|
||||
|
||||
do
|
||||
{
|
||||
Field *fields = arenaTeamMembersResult->Fetch();
|
||||
//prevent crash if db records are broken, when all members in result are already processed and current team hasn't got any members
|
||||
if (!fields)
|
||||
break;
|
||||
uint32 arenaTeamId = fields[0].GetUInt32();
|
||||
if (arenaTeamId < m_TeamId)
|
||||
{
|
||||
//there is in table arena_team_member record which doesn't have arenateamid in arena_team table, report error
|
||||
sLog.outErrorDb("ArenaTeam %u does not exist but it has record in arena_team_member table, deleting it!", arenaTeamId);
|
||||
CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid = '%u'", arenaTeamId);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arenaTeamId > m_TeamId)
|
||||
//we loaded all members for this arena_team already, break cycle
|
||||
break;
|
||||
|
||||
ArenaTeamMember newmember;
|
||||
newmember.guid = MAKE_NEW_GUID(fields[1].GetUInt32(), 0, HIGHGUID_PLAYER);
|
||||
newmember.games_week = fields[2].GetUInt32();
|
||||
newmember.wins_week = fields[3].GetUInt32();
|
||||
newmember.games_season = fields[4].GetUInt32();
|
||||
newmember.wins_season = fields[5].GetUInt32();
|
||||
newmember.personal_rating = fields[6].GetUInt32();
|
||||
newmember.name = fields[7].GetCppString();
|
||||
newmember.Class = fields[8].GetUInt8();
|
||||
|
||||
//check if member exists in characters table
|
||||
if (newmember.name.empty())
|
||||
{
|
||||
sLog.outErrorDb("ArenaTeam %u has member with empty name - probably player %u doesn't exist, deleting him from memberlist!", arenaTeamId, GUID_LOPART(newmember.guid));
|
||||
this->DelMember(newmember.guid);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (newmember.guid == GetCaptain())
|
||||
captainPresentInTeam = true;
|
||||
|
||||
m_members.push_back(newmember);
|
||||
}while (arenaTeamMembersResult->NextRow());
|
||||
|
||||
if (Empty() || !captainPresentInTeam)
|
||||
{
|
||||
// arena team is empty or captain is not in team, delete from db
|
||||
sLog.outErrorDb("ArenaTeam %u does not have any members or its captain is not in team, disbanding it...", m_TeamId);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ArenaTeam::SetCaptain(const uint64& guid)
|
||||
{
|
||||
// disable remove/promote buttons
|
||||
Player *oldcaptain = objmgr.GetPlayer(GetCaptain());
|
||||
if (oldcaptain)
|
||||
oldcaptain->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_MEMBER, 1);
|
||||
|
||||
// set new captain
|
||||
m_CaptainGuid = guid;
|
||||
|
||||
// update database
|
||||
CharacterDatabase.PExecute("UPDATE arena_team SET captainguid = '%u' WHERE arenateamid = '%u'", GUID_LOPART(guid), GetId());
|
||||
|
||||
// enable remove/promote buttons
|
||||
Player *newcaptain = objmgr.GetPlayer(guid);
|
||||
if (newcaptain)
|
||||
{
|
||||
newcaptain->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_MEMBER, 0);
|
||||
sLog.outArena("Player: %s [GUID: %u] promoted player: %s [GUID: %u] to leader of arena team [Id: %u] [Type: %u].", oldcaptain->GetName(), oldcaptain->GetGUIDLow(), newcaptain->GetName(), newcaptain->GetGUIDLow(), GetId(), GetType());
|
||||
}
|
||||
}
|
||||
|
||||
void ArenaTeam::DelMember(uint64 guid)
|
||||
{
|
||||
for (MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
|
||||
if (itr->guid == guid)
|
||||
{
|
||||
m_members.erase(itr);
|
||||
break;
|
||||
}
|
||||
|
||||
if (Player *player = objmgr.GetPlayer(guid))
|
||||
{
|
||||
player->GetSession()->SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, GetName(), "", 0);
|
||||
// delete all info regarding this team
|
||||
for (uint32 i = 0; i < ARENA_TEAM_END; ++i)
|
||||
player->SetArenaTeamInfoField(GetSlot(), ArenaTeamInfoType(i), 0);
|
||||
sLog.outArena("Player: %s [GUID: %u] left arena team type: %u [Id: %u].", player->GetName(), player->GetGUIDLow(), GetType(), GetId());
|
||||
}
|
||||
CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid = '%u' AND guid = '%u'", GetId(), GUID_LOPART(guid));
|
||||
}
|
||||
|
||||
void ArenaTeam::Disband(WorldSession *session)
|
||||
{
|
||||
// event
|
||||
if (session)
|
||||
// probably only 1 string required...
|
||||
BroadcastEvent(ERR_ARENA_TEAM_DISBANDED_S, 0, 2, session->GetPlayerName(), GetName(), "");
|
||||
|
||||
while (!m_members.empty())
|
||||
// Removing from members is done in DelMember.
|
||||
DelMember(m_members.front().guid);
|
||||
|
||||
if (session)
|
||||
if (Player *player = session->GetPlayer())
|
||||
sLog.outArena("Player: %s [GUID: %u] disbanded arena team type: %u [Id: %u].", player->GetName(), player->GetGUIDLow(), GetType(), GetId());
|
||||
|
||||
CharacterDatabase.BeginTransaction();
|
||||
CharacterDatabase.PExecute("DELETE FROM arena_team WHERE arenateamid = '%u'", m_TeamId);
|
||||
CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid = '%u'", m_TeamId); //< this should be alredy done by calling DelMember(memberGuids[j]); for each member
|
||||
CharacterDatabase.PExecute("DELETE FROM arena_team_stats WHERE arenateamid = '%u'", m_TeamId);
|
||||
CharacterDatabase.CommitTransaction();
|
||||
objmgr.RemoveArenaTeam(m_TeamId);
|
||||
}
|
||||
|
||||
void ArenaTeam::Roster(WorldSession *session)
|
||||
{
|
||||
Player *pl = NULL;
|
||||
|
||||
uint8 unk308 = 0;
|
||||
|
||||
WorldPacket data(SMSG_ARENA_TEAM_ROSTER, 100);
|
||||
data << uint32(GetId()); // team id
|
||||
data << uint8(unk308); // 308 unknown value but affect packet structure
|
||||
data << uint32(GetMembersSize()); // members count
|
||||
data << uint32(GetType()); // arena team type?
|
||||
|
||||
for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
|
||||
{
|
||||
pl = objmgr.GetPlayer(itr->guid);
|
||||
|
||||
data << uint64(itr->guid); // guid
|
||||
data << uint8((pl ? 1 : 0)); // online flag
|
||||
data << itr->name; // member name
|
||||
data << uint32((itr->guid == GetCaptain() ? 0 : 1));// captain flag 0 captain 1 member
|
||||
data << uint8((pl ? pl->getLevel() : 0)); // unknown, level?
|
||||
data << uint8(itr->Class); // class
|
||||
data << uint32(itr->games_week); // played this week
|
||||
data << uint32(itr->wins_week); // wins this week
|
||||
data << uint32(itr->games_season); // played this season
|
||||
data << uint32(itr->wins_season); // wins this season
|
||||
data << uint32(itr->personal_rating); // personal rating
|
||||
if (unk308)
|
||||
{
|
||||
data << float(0.0); // 308 unk
|
||||
data << float(0.0); // 308 unk
|
||||
}
|
||||
}
|
||||
|
||||
session->SendPacket(&data);
|
||||
sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_ROSTER");
|
||||
}
|
||||
|
||||
void ArenaTeam::Query(WorldSession *session)
|
||||
{
|
||||
WorldPacket data(SMSG_ARENA_TEAM_QUERY_RESPONSE, 4*7+GetName().size()+1);
|
||||
data << uint32(GetId()); // team id
|
||||
data << GetName(); // team name
|
||||
data << uint32(GetType()); // arena team type (2=2x2, 3=3x3 or 5=5x5)
|
||||
data << uint32(m_BackgroundColor); // background color
|
||||
data << uint32(m_EmblemStyle); // emblem style
|
||||
data << uint32(m_EmblemColor); // emblem color
|
||||
data << uint32(m_BorderStyle); // border style
|
||||
data << uint32(m_BorderColor); // border color
|
||||
session->SendPacket(&data);
|
||||
sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_QUERY_RESPONSE");
|
||||
}
|
||||
|
||||
void ArenaTeam::Stats(WorldSession *session)
|
||||
{
|
||||
WorldPacket data(SMSG_ARENA_TEAM_STATS, 4*7);
|
||||
data << uint32(GetId()); // team id
|
||||
data << uint32(m_stats.rating); // rating
|
||||
data << uint32(m_stats.games_week); // games this week
|
||||
data << uint32(m_stats.wins_week); // wins this week
|
||||
data << uint32(m_stats.games_season); // played this season
|
||||
data << uint32(m_stats.wins_season); // wins this season
|
||||
data << uint32(m_stats.rank); // rank
|
||||
session->SendPacket(&data);
|
||||
}
|
||||
|
||||
void ArenaTeam::NotifyStatsChanged()
|
||||
{
|
||||
// this is called after a rated match ended
|
||||
// updates arena team stats for every member of the team (not only the ones who participated!)
|
||||
for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
|
||||
{
|
||||
Player * plr = objmgr.GetPlayer(itr->guid);
|
||||
if (plr)
|
||||
Stats(plr->GetSession());
|
||||
}
|
||||
}
|
||||
|
||||
void ArenaTeam::InspectStats(WorldSession *session, uint64 guid)
|
||||
{
|
||||
ArenaTeamMember* member = GetMember(guid);
|
||||
if (!member)
|
||||
return;
|
||||
|
||||
WorldPacket data(MSG_INSPECT_ARENA_TEAMS, 8+1+4*6);
|
||||
data << uint64(guid); // player guid
|
||||
data << uint8(GetSlot()); // slot (0...2)
|
||||
data << uint32(GetId()); // arena team id
|
||||
data << uint32(m_stats.rating); // rating
|
||||
data << uint32(m_stats.games_season); // season played
|
||||
data << uint32(m_stats.wins_season); // season wins
|
||||
data << uint32(member->games_season); // played (count of all games, that the inspected member participated...)
|
||||
data << uint32(member->personal_rating); // personal rating
|
||||
session->SendPacket(&data);
|
||||
}
|
||||
|
||||
void ArenaTeam::SetEmblem(uint32 backgroundColor, uint32 emblemStyle, uint32 emblemColor, uint32 borderStyle, uint32 borderColor)
|
||||
{
|
||||
m_BackgroundColor = backgroundColor;
|
||||
m_EmblemStyle = emblemStyle;
|
||||
m_EmblemColor = emblemColor;
|
||||
m_BorderStyle = borderStyle;
|
||||
m_BorderColor = borderColor;
|
||||
|
||||
CharacterDatabase.PExecute("UPDATE arena_team SET BackgroundColor='%u', EmblemStyle='%u', EmblemColor='%u', BorderStyle='%u', BorderColor='%u' WHERE arenateamid='%u'", m_BackgroundColor, m_EmblemStyle, m_EmblemColor, m_BorderStyle, m_BorderColor, m_TeamId);
|
||||
}
|
||||
|
||||
void ArenaTeam::SetStats(uint32 stat_type, uint32 value)
|
||||
{
|
||||
switch(stat_type)
|
||||
{
|
||||
case STAT_TYPE_RATING:
|
||||
m_stats.rating = value;
|
||||
CharacterDatabase.PExecute("UPDATE arena_team_stats SET rating = '%u' WHERE arenateamid = '%u'", value, GetId());
|
||||
break;
|
||||
case STAT_TYPE_GAMES_WEEK:
|
||||
m_stats.games_week = value;
|
||||
CharacterDatabase.PExecute("UPDATE arena_team_stats SET games = '%u' WHERE arenateamid = '%u'", value, GetId());
|
||||
break;
|
||||
case STAT_TYPE_WINS_WEEK:
|
||||
m_stats.wins_week = value;
|
||||
CharacterDatabase.PExecute("UPDATE arena_team_stats SET wins = '%u' WHERE arenateamid = '%u'", value, GetId());
|
||||
break;
|
||||
case STAT_TYPE_GAMES_SEASON:
|
||||
m_stats.games_season = value;
|
||||
CharacterDatabase.PExecute("UPDATE arena_team_stats SET played = '%u' WHERE arenateamid = '%u'", value, GetId());
|
||||
break;
|
||||
case STAT_TYPE_WINS_SEASON:
|
||||
m_stats.wins_season = value;
|
||||
CharacterDatabase.PExecute("UPDATE arena_team_stats SET wins2 = '%u' WHERE arenateamid = '%u'", value, GetId());
|
||||
break;
|
||||
case STAT_TYPE_RANK:
|
||||
m_stats.rank = value;
|
||||
CharacterDatabase.PExecute("UPDATE arena_team_stats SET rank = '%u' WHERE arenateamid = '%u'", value, GetId());
|
||||
break;
|
||||
default:
|
||||
sLog.outDebug("unknown stat type in ArenaTeam::SetStats() %u", stat_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ArenaTeam::BroadcastPacket(WorldPacket *packet)
|
||||
{
|
||||
for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
|
||||
{
|
||||
Player *player = objmgr.GetPlayer(itr->guid);
|
||||
if (player)
|
||||
player->GetSession()->SendPacket(packet);
|
||||
}
|
||||
}
|
||||
|
||||
void ArenaTeam::BroadcastEvent(ArenaTeamEvents event, uint64 guid, uint8 strCount, std::string str1, std::string str2, std::string str3)
|
||||
{
|
||||
WorldPacket data(SMSG_ARENA_TEAM_EVENT, 1+1+1);
|
||||
data << uint8(event);
|
||||
data << uint8(strCount);
|
||||
switch (strCount)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
data << str1;
|
||||
break;
|
||||
case 2:
|
||||
data << str1 << str2;
|
||||
break;
|
||||
case 3:
|
||||
data << str1 << str2 << str3;
|
||||
break;
|
||||
default:
|
||||
sLog.outError("Unhandled strCount %u in ArenaTeam::BroadcastEvent", strCount);
|
||||
return;
|
||||
}
|
||||
|
||||
if (guid)
|
||||
data << uint64(guid);
|
||||
|
||||
BroadcastPacket(&data);
|
||||
|
||||
sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_EVENT");
|
||||
}
|
||||
|
||||
uint8 ArenaTeam::GetSlotByType(uint32 type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case ARENA_TEAM_2v2: return 0;
|
||||
case ARENA_TEAM_3v3: return 1;
|
||||
case ARENA_TEAM_5v5: return 2;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sLog.outError("FATAL: Unknown arena team type %u for some arena team", type);
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
bool ArenaTeam::HaveMember(const uint64& guid) const
|
||||
{
|
||||
for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
|
||||
if (itr->guid == guid)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 ArenaTeam::GetPoints(uint32 MemberRating)
|
||||
{
|
||||
// returns how many points would be awarded with this team type with this rating
|
||||
float points;
|
||||
|
||||
uint32 rating = MemberRating + 150 < m_stats.rating ? MemberRating : m_stats.rating;
|
||||
|
||||
if (rating <= 1500)
|
||||
{
|
||||
if (sWorld.getConfig(CONFIG_ARENA_SEASON_ID) < 6)
|
||||
points = (float)rating * 0.22f + 14.0f;
|
||||
else
|
||||
points = 344;
|
||||
}
|
||||
else
|
||||
points = 1511.26f / (1.0f + 1639.28f * exp(-0.00412f * (float)rating));
|
||||
|
||||
// type penalties for <5v5 teams
|
||||
if (m_Type == ARENA_TEAM_2v2)
|
||||
points *= 0.76f;
|
||||
else if (m_Type == ARENA_TEAM_3v3)
|
||||
points *= 0.88f;
|
||||
|
||||
return (uint32) points;
|
||||
}
|
||||
|
||||
float ArenaTeam::GetChanceAgainst(uint32 own_rating, uint32 enemy_rating)
|
||||
{
|
||||
// returns the chance to win against a team with the given rating, used in the rating adjustment calculation
|
||||
// ELO system
|
||||
|
||||
if (sWorld.getConfig(CONFIG_ARENA_SEASON_ID) >= 6)
|
||||
if (enemy_rating < 1000)
|
||||
enemy_rating = 1000;
|
||||
return 1.0f/(1.0f+exp(log(10.0f)*(float)((float)enemy_rating - (float)own_rating)/400.0f));
|
||||
}
|
||||
|
||||
void ArenaTeam::FinishGame(int32 mod)
|
||||
{
|
||||
if (int32(m_stats.rating) + mod < 0)
|
||||
m_stats.rating = 0;
|
||||
else
|
||||
m_stats.rating += mod;
|
||||
|
||||
m_stats.games_week += 1;
|
||||
m_stats.games_season += 1;
|
||||
// update team's rank
|
||||
m_stats.rank = 1;
|
||||
ObjectMgr::ArenaTeamMap::const_iterator i = objmgr.GetArenaTeamMapBegin();
|
||||
for (; i != objmgr.GetArenaTeamMapEnd(); ++i)
|
||||
{
|
||||
if (i->second->GetType() == m_Type && i->second->GetStats().rating > m_stats.rating)
|
||||
++m_stats.rank;
|
||||
}
|
||||
}
|
||||
|
||||
int32 ArenaTeam::WonAgainst(uint32 againstRating)
|
||||
{
|
||||
// called when the team has won
|
||||
// 'chance' calculation - to beat the opponent
|
||||
float chance = GetChanceAgainst(m_stats.rating, againstRating);
|
||||
float K = (m_stats.rating < 1000) ? 48.0f : 32.0f;
|
||||
// calculate the rating modification (ELO system with k=32 or k=48 if rating<1000)
|
||||
int32 mod = (int32)floor(K* (1.0f - chance));
|
||||
|
||||
// modify the team stats accordingly
|
||||
FinishGame(mod);
|
||||
m_stats.wins_week += 1;
|
||||
m_stats.wins_season += 1;
|
||||
|
||||
// return the rating change, used to display it on the results screen
|
||||
return mod;
|
||||
}
|
||||
|
||||
int32 ArenaTeam::LostAgainst(uint32 againstRating)
|
||||
{
|
||||
// called when the team has lost
|
||||
//'chance' calculation - to loose to the opponent
|
||||
float chance = GetChanceAgainst(m_stats.rating, againstRating);
|
||||
if (m_stats.rating < 1000)
|
||||
{
|
||||
FinishGame(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
float K = 32.0f;
|
||||
int32 mod = (int32)ceil(K * (0.0f - chance));
|
||||
// modify the team stats accordingly
|
||||
FinishGame(mod);
|
||||
|
||||
// return the rating change, used to display it on the results screen
|
||||
return mod;
|
||||
}
|
||||
|
||||
void ArenaTeam::MemberLost(Player * plr, uint32 againstRating)
|
||||
{
|
||||
// called for each participant of a match after losing
|
||||
for (MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
|
||||
{
|
||||
if (itr->guid == plr->GetGUID())
|
||||
{
|
||||
// update personal rating
|
||||
float chance = GetChanceAgainst(itr->personal_rating, againstRating);
|
||||
float K = (itr->personal_rating < 1000) ? 48.0f : 32.0f;
|
||||
// calculate the rating modification (ELO system with k=32 or k=48 if rating<1000)
|
||||
int32 mod = (int32)ceil(K * (0.0f - chance));
|
||||
itr->ModifyPersonalRating(plr, mod, GetSlot());
|
||||
// update personal played stats
|
||||
itr->games_week +=1;
|
||||
itr->games_season +=1;
|
||||
// update the unit fields
|
||||
plr->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_GAMES_WEEK, itr->games_week);
|
||||
plr->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_GAMES_SEASON, itr->games_season);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ArenaTeam::OfflineMemberLost(uint64 guid, uint32 againstRating)
|
||||
{
|
||||
// called for offline player after ending rated arena match!
|
||||
for (MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
|
||||
{
|
||||
if (itr->guid == guid)
|
||||
{
|
||||
// update personal rating
|
||||
float chance = GetChanceAgainst(itr->personal_rating, againstRating);
|
||||
float K = (itr->personal_rating < 1000) ? 48.0f : 32.0f;
|
||||
// calculate the rating modification (ELO system with k=32 or k=48 if rating<1000)
|
||||
int32 mod = (int32)ceil(K * (0.0f - chance));
|
||||
if (int32(itr->personal_rating) + mod < 0)
|
||||
itr->personal_rating = 0;
|
||||
else
|
||||
itr->personal_rating += mod;
|
||||
// update personal played stats
|
||||
itr->games_week +=1;
|
||||
itr->games_season +=1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ArenaTeam::MemberWon(Player * plr, uint32 againstRating)
|
||||
{
|
||||
// called for each participant after winning a match
|
||||
for (MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
|
||||
{
|
||||
if (itr->guid == plr->GetGUID())
|
||||
{
|
||||
// update personal rating
|
||||
float chance = GetChanceAgainst(itr->personal_rating, againstRating);
|
||||
float K = (itr->personal_rating < 1000) ? 48.0f : 32.0f;
|
||||
// calculate the rating modification (ELO system with k=32 or k=48 if rating<1000)
|
||||
int32 mod = (int32)floor(K* (1.0f - chance));
|
||||
itr->ModifyPersonalRating(plr, mod, GetSlot());
|
||||
// update personal stats
|
||||
itr->games_week +=1;
|
||||
itr->games_season +=1;
|
||||
itr->wins_season += 1;
|
||||
itr->wins_week += 1;
|
||||
// update unit fields
|
||||
plr->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_GAMES_WEEK, itr->games_week);
|
||||
plr->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_GAMES_SEASON, itr->games_season);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ArenaTeam::UpdateArenaPointsHelper(std::map<uint32, uint32>& PlayerPoints)
|
||||
{
|
||||
// called after a match has ended and the stats are already modified
|
||||
// helper function for arena point distribution (this way, when distributing, no actual calculation is required, just a few comparisons)
|
||||
// 10 played games per week is a minimum
|
||||
if (m_stats.games_week < 10)
|
||||
return;
|
||||
// to get points, a player has to participate in at least 30% of the matches
|
||||
uint32 min_plays = (uint32) ceil(m_stats.games_week * 0.3);
|
||||
for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
|
||||
{
|
||||
// the player participated in enough games, update his points
|
||||
uint32 points_to_add = 0;
|
||||
if (itr->games_week >= min_plays)
|
||||
points_to_add = GetPoints(itr->personal_rating);
|
||||
// OBSOLETE : CharacterDatabase.PExecute("UPDATE arena_team_member SET points_to_add = '%u' WHERE arenateamid = '%u' AND guid = '%u'", points_to_add, m_TeamId, itr->guid);
|
||||
|
||||
std::map<uint32, uint32>::iterator plr_itr = PlayerPoints.find(GUID_LOPART(itr->guid));
|
||||
if (plr_itr != PlayerPoints.end())
|
||||
{
|
||||
//check if there is already more points
|
||||
if (plr_itr->second < points_to_add)
|
||||
PlayerPoints[GUID_LOPART(itr->guid)] = points_to_add;
|
||||
}
|
||||
else
|
||||
PlayerPoints[GUID_LOPART(itr->guid)] = points_to_add;
|
||||
}
|
||||
}
|
||||
|
||||
void ArenaTeam::SaveToDB()
|
||||
{
|
||||
// save team and member stats to db
|
||||
// called after a match has ended, or when calculating arena_points
|
||||
CharacterDatabase.BeginTransaction();
|
||||
CharacterDatabase.PExecute("UPDATE arena_team_stats SET rating = '%u',games = '%u',played = '%u',rank = '%u',wins = '%u',wins2 = '%u' WHERE arenateamid = '%u'", m_stats.rating, m_stats.games_week, m_stats.games_season, m_stats.rank, m_stats.wins_week, m_stats.wins_season, GetId());
|
||||
for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
|
||||
{
|
||||
CharacterDatabase.PExecute("UPDATE arena_team_member SET played_week = '%u', wons_week = '%u', played_season = '%u', wons_season = '%u', personal_rating = '%u' WHERE arenateamid = '%u' AND guid = '%u'", itr->games_week, itr->wins_week, itr->games_season, itr->wins_season, itr->personal_rating, m_TeamId, GUID_LOPART(itr->guid));
|
||||
}
|
||||
CharacterDatabase.CommitTransaction();
|
||||
}
|
||||
|
||||
void ArenaTeam::FinishWeek()
|
||||
{
|
||||
m_stats.games_week = 0; // played this week
|
||||
m_stats.wins_week = 0; // wins this week
|
||||
for (MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
|
||||
{
|
||||
itr->games_week = 0;
|
||||
itr->wins_week = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool ArenaTeam::IsFighting() const
|
||||
{
|
||||
for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
|
||||
if (Player *p = objmgr.GetPlayer(itr->guid))
|
||||
if (p->GetMap()->IsBattleArena())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef TRINITYCORE_ARENATEAM_H
|
||||
#define TRINITYCORE_ARENATEAM_H
|
||||
|
||||
enum ArenaTeamCommandTypes
|
||||
{
|
||||
ERR_ARENA_TEAM_CREATE_S = 0x00,
|
||||
ERR_ARENA_TEAM_INVITE_SS = 0x01,
|
||||
ERR_ARENA_TEAM_QUIT_S = 0x03,
|
||||
ERR_ARENA_TEAM_FOUNDER_S = 0x0E
|
||||
};
|
||||
|
||||
enum ArenaTeamCommandErrors
|
||||
{
|
||||
ERR_ARENA_TEAM_INTERNAL = 0x01,
|
||||
ERR_ALREADY_IN_ARENA_TEAM = 0x02,
|
||||
ERR_ALREADY_IN_ARENA_TEAM_S = 0x03,
|
||||
ERR_INVITED_TO_ARENA_TEAM = 0x04,
|
||||
ERR_ALREADY_INVITED_TO_ARENA_TEAM_S = 0x05,
|
||||
ERR_ARENA_TEAM_NAME_INVALID = 0x06,
|
||||
ERR_ARENA_TEAM_NAME_EXISTS_S = 0x07,
|
||||
ERR_ARENA_TEAM_LEADER_LEAVE_S = 0x08,
|
||||
ERR_ARENA_TEAM_PERMISSIONS = 0x08,
|
||||
ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM = 0x09,
|
||||
ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM_SS = 0x0A,
|
||||
ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S = 0x0B,
|
||||
ERR_ARENA_TEAM_NOT_ALLIED = 0x0C,
|
||||
ERR_ARENA_TEAM_IGNORING_YOU_S = 0x13,
|
||||
ERR_ARENA_TEAM_TARGET_TOO_LOW_S = 0x15,
|
||||
ERR_ARENA_TEAM_TARGET_TOO_HIGH_S = 0x16,
|
||||
ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S = 0x17,
|
||||
ERR_ARENA_TEAM_NOT_FOUND = 0x1B,
|
||||
ERR_ARENA_TEAMS_LOCKED = 0x1E
|
||||
};
|
||||
|
||||
enum ArenaTeamEvents
|
||||
{
|
||||
ERR_ARENA_TEAM_JOIN_SS = 3, // player name + arena team name
|
||||
ERR_ARENA_TEAM_LEAVE_SS = 4, // player name + arena team name
|
||||
ERR_ARENA_TEAM_REMOVE_SSS = 5, // player name + arena team name + captain name
|
||||
ERR_ARENA_TEAM_LEADER_IS_SS = 6, // player name + arena team name
|
||||
ERR_ARENA_TEAM_LEADER_CHANGED_SSS = 7, // old captain + new captain + arena team name
|
||||
ERR_ARENA_TEAM_DISBANDED_S = 8 // captain name + arena team name
|
||||
};
|
||||
|
||||
/*
|
||||
need info how to send these ones:
|
||||
ERR_ARENA_TEAM_YOU_JOIN_S - client show it automatically when accept invite
|
||||
ERR_ARENA_TEAM_TARGET_TOO_LOW_S
|
||||
ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S
|
||||
ERR_ARENA_TEAM_LEVEL_TOO_LOW_I
|
||||
*/
|
||||
|
||||
enum ArenaTeamStatTypes
|
||||
{
|
||||
STAT_TYPE_RATING = 0,
|
||||
STAT_TYPE_GAMES_WEEK = 1,
|
||||
STAT_TYPE_WINS_WEEK = 2,
|
||||
STAT_TYPE_GAMES_SEASON = 3,
|
||||
STAT_TYPE_WINS_SEASON = 4,
|
||||
STAT_TYPE_RANK = 5
|
||||
};
|
||||
|
||||
enum ArenaTeamTypes
|
||||
{
|
||||
ARENA_TEAM_2v2 = 2,
|
||||
ARENA_TEAM_3v3 = 3,
|
||||
ARENA_TEAM_5v5 = 5
|
||||
};
|
||||
|
||||
struct ArenaTeamMember
|
||||
{
|
||||
uint64 guid;
|
||||
std::string name;
|
||||
uint8 Class;
|
||||
uint32 games_week;
|
||||
uint32 wins_week;
|
||||
uint32 games_season;
|
||||
uint32 wins_season;
|
||||
uint32 personal_rating;
|
||||
|
||||
void ModifyPersonalRating(Player* plr, int32 mod, uint32 slot);
|
||||
};
|
||||
|
||||
struct ArenaTeamStats
|
||||
{
|
||||
uint32 rating;
|
||||
uint32 games_week;
|
||||
uint32 wins_week;
|
||||
uint32 games_season;
|
||||
uint32 wins_season;
|
||||
uint32 rank;
|
||||
};
|
||||
|
||||
#define MAX_ARENA_SLOT 3 // 0..2 slots
|
||||
|
||||
class ArenaTeam
|
||||
{
|
||||
public:
|
||||
ArenaTeam();
|
||||
~ArenaTeam();
|
||||
|
||||
bool Create(uint64 captainGuid, uint32 type, std::string ArenaTeamName);
|
||||
void Disband(WorldSession *session);
|
||||
|
||||
typedef std::list<ArenaTeamMember> MemberList;
|
||||
|
||||
uint32 GetId() const { return m_TeamId; }
|
||||
uint32 GetType() const { return m_Type; }
|
||||
uint8 GetSlot() const { return GetSlotByType(GetType()); }
|
||||
static uint8 GetSlotByType(uint32 type);
|
||||
const uint64& GetCaptain() const { return m_CaptainGuid; }
|
||||
std::string GetName() const { return m_Name; }
|
||||
const ArenaTeamStats& GetStats() const { return m_stats; }
|
||||
void SetStats(uint32 stat_type, uint32 value);
|
||||
uint32 GetRating() const { return m_stats.rating; }
|
||||
|
||||
uint32 GetEmblemStyle() const { return m_EmblemStyle; }
|
||||
uint32 GetEmblemColor() const { return m_EmblemColor; }
|
||||
uint32 GetBorderStyle() const { return m_BorderStyle; }
|
||||
uint32 GetBorderColor() const { return m_BorderColor; }
|
||||
uint32 GetBackgroundColor() const { return m_BackgroundColor; }
|
||||
|
||||
void SetCaptain(const uint64& guid);
|
||||
bool AddMember(const uint64& PlayerGuid);
|
||||
|
||||
// Shouldn't be const uint64& ed, because than can reference guid from members on Disband
|
||||
// and this method removes given record from list. So invalid reference can happen.
|
||||
void DelMember(uint64 guid);
|
||||
|
||||
void SetEmblem(uint32 backgroundColor, uint32 emblemStyle, uint32 emblemColor, uint32 borderStyle, uint32 borderColor);
|
||||
|
||||
size_t GetMembersSize() const { return m_members.size(); }
|
||||
bool Empty() const { return m_members.empty(); }
|
||||
MemberList::iterator m_membersBegin() { return m_members.begin(); }
|
||||
MemberList::iterator m_membersEnd() { return m_members.end(); }
|
||||
bool HaveMember(const uint64& guid) const;
|
||||
|
||||
ArenaTeamMember* GetMember(const uint64& guid)
|
||||
{
|
||||
for (MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
|
||||
if (itr->guid == guid)
|
||||
return &(*itr);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ArenaTeamMember* GetMember(const std::string& name)
|
||||
{
|
||||
for (MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
|
||||
if (itr->name == name)
|
||||
return &(*itr);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool IsFighting() const;
|
||||
|
||||
bool LoadArenaTeamFromDB(QueryResult_AutoPtr arenaTeamDataResult);
|
||||
bool LoadMembersFromDB(QueryResult_AutoPtr arenaTeamMembersResult);
|
||||
void LoadStatsFromDB(uint32 ArenaTeamId);
|
||||
|
||||
void SaveToDB();
|
||||
|
||||
void BroadcastPacket(WorldPacket *packet);
|
||||
void BroadcastEvent(ArenaTeamEvents event, uint64 guid, uint8 strCount, std::string str1, std::string str2, std::string str3);
|
||||
|
||||
void Roster(WorldSession *session);
|
||||
void Query(WorldSession *session);
|
||||
void Stats(WorldSession *session);
|
||||
void InspectStats(WorldSession *session, uint64 guid);
|
||||
|
||||
uint32 GetPoints(uint32 MemberRating);
|
||||
float GetChanceAgainst(uint32 own_rating, uint32 enemy_rating);
|
||||
int32 WonAgainst(uint32 againstRating);
|
||||
void MemberWon(Player * plr, uint32 againstRating);
|
||||
int32 LostAgainst(uint32 againstRating);
|
||||
void MemberLost(Player * plr, uint32 againstRating);
|
||||
void OfflineMemberLost(uint64 guid, uint32 againstRating);
|
||||
|
||||
void UpdateArenaPointsHelper(std::map<uint32, uint32> & PlayerPoints);
|
||||
|
||||
void NotifyStatsChanged();
|
||||
|
||||
void FinishWeek();
|
||||
void FinishGame(int32 mod);
|
||||
|
||||
protected:
|
||||
|
||||
uint32 m_TeamId;
|
||||
uint32 m_Type;
|
||||
std::string m_Name;
|
||||
uint64 m_CaptainGuid;
|
||||
|
||||
uint32 m_BackgroundColor; // ARGB format
|
||||
uint32 m_EmblemStyle; // icon id
|
||||
uint32 m_EmblemColor; // ARGB format
|
||||
uint32 m_BorderStyle; // border image id
|
||||
uint32 m_BorderColor; // ARGB format
|
||||
|
||||
MemberList m_members;
|
||||
ArenaTeamStats m_stats;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,391 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Player.h"
|
||||
#include "World.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
|
||||
#include "ArenaTeam.h"
|
||||
#include "Log.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "SocialMgr.h"
|
||||
|
||||
void WorldSession::HandleInspectArenaTeamsOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
sLog.outDebug("MSG_INSPECT_ARENA_TEAMS");
|
||||
|
||||
uint64 guid;
|
||||
recv_data >> guid;
|
||||
sLog.outDebug("Inspect Arena stats (GUID: %u TypeId: %u)", GUID_LOPART(guid),GuidHigh2TypeId(GUID_HIPART(guid)));
|
||||
|
||||
if (Player *plr = objmgr.GetPlayer(guid))
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ARENA_SLOT; ++i)
|
||||
{
|
||||
if (uint32 a_id = plr->GetArenaTeamId(i))
|
||||
{
|
||||
if (ArenaTeam *at = objmgr.GetArenaTeamById(a_id))
|
||||
at->InspectStats(this, plr->GetGUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandleArenaTeamQueryOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: Received CMSG_ARENA_TEAM_QUERY");
|
||||
|
||||
uint32 ArenaTeamId;
|
||||
recv_data >> ArenaTeamId;
|
||||
|
||||
if (ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId))
|
||||
{
|
||||
arenateam->Query(this);
|
||||
arenateam->Stats(this);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandleArenaTeamRosterOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: Received CMSG_ARENA_TEAM_ROSTER");
|
||||
|
||||
uint32 ArenaTeamId; // arena team id
|
||||
recv_data >> ArenaTeamId;
|
||||
|
||||
if (ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId))
|
||||
arenateam->Roster(this);
|
||||
}
|
||||
|
||||
void WorldSession::HandleArenaTeamInviteOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
sLog.outDebug("CMSG_ARENA_TEAM_INVITE");
|
||||
|
||||
uint32 ArenaTeamId; // arena team id
|
||||
std::string Invitedname;
|
||||
|
||||
Player * player = NULL;
|
||||
|
||||
recv_data >> ArenaTeamId >> Invitedname;
|
||||
|
||||
if (!Invitedname.empty())
|
||||
{
|
||||
if (!normalizePlayerName(Invitedname))
|
||||
return;
|
||||
|
||||
player = ObjectAccessor::Instance().FindPlayerByName(Invitedname.c_str());
|
||||
}
|
||||
|
||||
if (!player)
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", Invitedname, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S);
|
||||
return;
|
||||
}
|
||||
|
||||
if (player->getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", player->GetName(), ERR_ARENA_TEAM_TARGET_TOO_LOW_S);
|
||||
return;
|
||||
}
|
||||
|
||||
ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId);
|
||||
if (!arenateam)
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM);
|
||||
return;
|
||||
}
|
||||
|
||||
// OK result but not send invite
|
||||
if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()))
|
||||
return;
|
||||
|
||||
if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != GetPlayer()->GetTeam())
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (player->GetArenaTeamId(arenateam->GetSlot()))
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", player->GetName(), ERR_ALREADY_IN_ARENA_TEAM_S);
|
||||
return;
|
||||
}
|
||||
|
||||
if (player->GetArenaTeamIdInvited())
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", player->GetName(), ERR_ALREADY_INVITED_TO_ARENA_TEAM_S);
|
||||
return;
|
||||
}
|
||||
|
||||
if (arenateam->GetMembersSize() >= arenateam->GetType() * 2)
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, arenateam->GetName(), "", ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S);
|
||||
return;
|
||||
}
|
||||
|
||||
sLog.outDebug("Player %s Invited %s to Join his ArenaTeam", GetPlayer()->GetName(), Invitedname.c_str());
|
||||
|
||||
player->SetArenaTeamIdInvited(arenateam->GetId());
|
||||
|
||||
WorldPacket data(SMSG_ARENA_TEAM_INVITE, (8+10));
|
||||
data << GetPlayer()->GetName();
|
||||
data << arenateam->GetName();
|
||||
player->GetSession()->SendPacket(&data);
|
||||
|
||||
sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_INVITE");
|
||||
}
|
||||
|
||||
void WorldSession::HandleArenaTeamAcceptOpcode(WorldPacket & /*recv_data*/)
|
||||
{
|
||||
sLog.outDebug("CMSG_ARENA_TEAM_ACCEPT"); // empty opcode
|
||||
|
||||
ArenaTeam *at = objmgr.GetArenaTeamById(_player->GetArenaTeamIdInvited());
|
||||
if (!at)
|
||||
return;
|
||||
|
||||
if (_player->GetArenaTeamId(at->GetSlot()))
|
||||
{
|
||||
// already in arena team that size
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ALREADY_IN_ARENA_TEAM);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && _player->GetTeam() != objmgr.GetPlayerTeamByGUID(at->GetCaptain()))
|
||||
{
|
||||
// not let enemies sign petition
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_NOT_ALLIED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!at->AddMember(_player->GetGUID()))
|
||||
{
|
||||
// arena team not found
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S,"","",ERR_ARENA_TEAM_INTERNAL);
|
||||
return;
|
||||
}
|
||||
|
||||
// event
|
||||
at->BroadcastEvent(ERR_ARENA_TEAM_JOIN_SS, _player->GetGUID(), 2, _player->GetName(), at->GetName(), "");
|
||||
}
|
||||
|
||||
void WorldSession::HandleArenaTeamDeclineOpcode(WorldPacket & /*recv_data*/)
|
||||
{
|
||||
sLog.outDebug("CMSG_ARENA_TEAM_DECLINE"); // empty opcode
|
||||
|
||||
_player->SetArenaTeamIdInvited(0); // no more invited
|
||||
}
|
||||
|
||||
void WorldSession::HandleArenaTeamLeaveOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
sLog.outDebug("CMSG_ARENA_TEAM_LEAVE");
|
||||
|
||||
uint32 ArenaTeamId; // arena team id
|
||||
recv_data >> ArenaTeamId;
|
||||
|
||||
ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId);
|
||||
if (!at)
|
||||
return;
|
||||
|
||||
if (_player->GetGUID() == at->GetCaptain() && at->GetMembersSize() > 1)
|
||||
{
|
||||
// check for correctness
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, "", "", ERR_ARENA_TEAM_LEADER_LEAVE_S);
|
||||
return;
|
||||
}
|
||||
|
||||
// arena team has only one member (=captain)
|
||||
if (_player->GetGUID() == at->GetCaptain())
|
||||
{
|
||||
at->Disband(this);
|
||||
delete at;
|
||||
return;
|
||||
}
|
||||
|
||||
at->DelMember(_player->GetGUID());
|
||||
|
||||
// event
|
||||
at->BroadcastEvent(ERR_ARENA_TEAM_LEAVE_SS, _player->GetGUID(), 2, _player->GetName(), at->GetName(), "");
|
||||
|
||||
// send you are no longer member of team
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, at->GetName(), "", 0);
|
||||
}
|
||||
|
||||
void WorldSession::HandleArenaTeamDisbandOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
sLog.outDebug("CMSG_ARENA_TEAM_DISBAND");
|
||||
|
||||
uint32 ArenaTeamId; // arena team id
|
||||
recv_data >> ArenaTeamId;
|
||||
|
||||
if (ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId))
|
||||
{
|
||||
if (at->GetCaptain() != _player->GetGUID())
|
||||
return;
|
||||
|
||||
if (at->IsFighting())
|
||||
return;
|
||||
|
||||
at->Disband(this);
|
||||
delete at;
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandleArenaTeamRemoveOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
sLog.outDebug("CMSG_ARENA_TEAM_REMOVE");
|
||||
|
||||
uint32 ArenaTeamId;
|
||||
std::string name;
|
||||
|
||||
recv_data >> ArenaTeamId;
|
||||
recv_data >> name;
|
||||
|
||||
ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId);
|
||||
if (!at) // arena team not found
|
||||
return;
|
||||
|
||||
if (at->GetCaptain() != _player->GetGUID())
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!normalizePlayerName(name))
|
||||
return;
|
||||
|
||||
ArenaTeamMember* member = at->GetMember(name);
|
||||
if (!member) // member not found
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", name, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S);
|
||||
return;
|
||||
}
|
||||
|
||||
if (at->GetCaptain() == member->guid)
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, "", "", ERR_ARENA_TEAM_LEADER_LEAVE_S);
|
||||
return;
|
||||
}
|
||||
|
||||
at->DelMember(member->guid);
|
||||
|
||||
// event
|
||||
at->BroadcastEvent(ERR_ARENA_TEAM_REMOVE_SSS, 0, 3, name, at->GetName(), _player->GetName());
|
||||
}
|
||||
|
||||
void WorldSession::HandleArenaTeamLeaderOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
sLog.outDebug("CMSG_ARENA_TEAM_LEADER");
|
||||
|
||||
uint32 ArenaTeamId;
|
||||
std::string name;
|
||||
|
||||
recv_data >> ArenaTeamId;
|
||||
recv_data >> name;
|
||||
|
||||
ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId);
|
||||
if (!at) // arena team not found
|
||||
return;
|
||||
|
||||
if (at->GetCaptain() != _player->GetGUID())
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!normalizePlayerName(name))
|
||||
return;
|
||||
|
||||
ArenaTeamMember* member = at->GetMember(name);
|
||||
if (!member) // member not found
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", name, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S);
|
||||
return;
|
||||
}
|
||||
|
||||
if (at->GetCaptain() == member->guid) // target player already captain
|
||||
return;
|
||||
|
||||
at->SetCaptain(member->guid);
|
||||
|
||||
// event
|
||||
at->BroadcastEvent(ERR_ARENA_TEAM_LEADER_CHANGED_SSS, 0, 3, _player->GetName(), name, at->GetName());
|
||||
}
|
||||
|
||||
void WorldSession::SendArenaTeamCommandResult(uint32 team_action, const std::string& team, const std::string& player, uint32 error_id)
|
||||
{
|
||||
WorldPacket data(SMSG_ARENA_TEAM_COMMAND_RESULT, 4+team.length()+1+player.length()+1+4);
|
||||
data << uint32(team_action);
|
||||
data << team;
|
||||
data << player;
|
||||
data << uint32(error_id);
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::SendNotInArenaTeamPacket(uint8 type)
|
||||
{
|
||||
WorldPacket data(SMSG_ARENA_ERROR, 4+1); // 886 - You are not in a %uv%u arena team
|
||||
uint32 unk = 0;
|
||||
data << uint32(unk); // unk(0)
|
||||
if (!unk)
|
||||
data << uint8(type); // team type (2=2v2,3=3v3,5=5v5), can be used for custom types...
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
/*
|
||||
+ERR_ARENA_NO_TEAM_II "You are not in a %dv%d arena team"
|
||||
|
||||
+ERR_ARENA_TEAM_CREATE_S "%s created. To disband, use /teamdisband [2v2, 3v3, 5v5]."
|
||||
+ERR_ARENA_TEAM_INVITE_SS "You have invited %s to join %s"
|
||||
+ERR_ARENA_TEAM_QUIT_S "You are no longer a member of %s"
|
||||
ERR_ARENA_TEAM_FOUNDER_S "Congratulations, you are a founding member of %s! To leave, use /teamquit [2v2, 3v3, 5v5]."
|
||||
|
||||
+ERR_ARENA_TEAM_INTERNAL "Internal arena team error"
|
||||
+ERR_ALREADY_IN_ARENA_TEAM "You are already in an arena team of that size"
|
||||
+ERR_ALREADY_IN_ARENA_TEAM_S "%s is already in an arena team of that size"
|
||||
+ERR_INVITED_TO_ARENA_TEAM "You have already been invited into an arena team"
|
||||
+ERR_ALREADY_INVITED_TO_ARENA_TEAM_S "%s has already been invited to an arena team"
|
||||
+ERR_ARENA_TEAM_NAME_INVALID "That name contains invalid characters, please enter a new name"
|
||||
+ERR_ARENA_TEAM_NAME_EXISTS_S "There is already an arena team named \"%s\""
|
||||
+ERR_ARENA_TEAM_LEADER_LEAVE_S "You must promote a new team captain using /teamcaptain before leaving the team"
|
||||
+ERR_ARENA_TEAM_PERMISSIONS "You don't have permission to do that"
|
||||
+ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM "You are not in an arena team of that size"
|
||||
+ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM_SS "%s is not in %s"
|
||||
+ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S "\"%s\" not found"
|
||||
+ERR_ARENA_TEAM_NOT_ALLIED "You cannot invite players from the opposing alliance"
|
||||
|
||||
+ERR_ARENA_TEAM_JOIN_SS "%s has joined %s"
|
||||
+ERR_ARENA_TEAM_YOU_JOIN_S "You have joined %s. To leave, use /teamquit [2v2, 3v3, 5v5]."
|
||||
|
||||
+ERR_ARENA_TEAM_LEAVE_SS "%s has left %s"
|
||||
|
||||
+ERR_ARENA_TEAM_LEADER_IS_SS "%s is the captain of %s"
|
||||
+ERR_ARENA_TEAM_LEADER_CHANGED_SSS "%s has made %s the new captain of %s"
|
||||
|
||||
+ERR_ARENA_TEAM_REMOVE_SSS "%s has been kicked out of %s by %s"
|
||||
|
||||
+ERR_ARENA_TEAM_DISBANDED_S "%s has disbanded %s"
|
||||
|
||||
ERR_ARENA_TEAM_TARGET_TOO_LOW_S "%s is not high enough level to join your team"
|
||||
|
||||
ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S "%s is full"
|
||||
|
||||
ERR_ARENA_TEAM_LEVEL_TOO_LOW_I "You must be level %d to form an arena team"
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,664 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "ObjectMgr.h"
|
||||
#include "Player.h"
|
||||
#include "World.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
|
||||
#include "AuctionHouseBot.h"
|
||||
#include "AuctionHouseMgr.h"
|
||||
#include "Log.h"
|
||||
#include "Opcodes.h"
|
||||
#include "UpdateMask.h"
|
||||
#include "Util.h"
|
||||
|
||||
//please DO NOT use iterator++, because it is slower than ++iterator!!!
|
||||
//post-incrementation is always slower than pre-incrementation !
|
||||
|
||||
//void called when player click on auctioneer npc
|
||||
void WorldSession::HandleAuctionHelloOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
uint64 guid; //NPC guid
|
||||
recv_data >> guid;
|
||||
|
||||
Creature *unit = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_AUCTIONEER);
|
||||
if (!unit)
|
||||
{
|
||||
sLog.outDebug("WORLD: HandleAuctionHelloOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)));
|
||||
return;
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
SendAuctionHello(guid, unit);
|
||||
}
|
||||
|
||||
//this void causes that auction window is opened
|
||||
void WorldSession::SendAuctionHello(uint64 guid, Creature* unit)
|
||||
{
|
||||
if (GetPlayer()->getLevel() < sWorld.getConfig(CONFIG_AUCTION_LEVEL_REQ))
|
||||
{
|
||||
SendNotification(GetTrinityString(LANG_AUCTION_REQ), sWorld.getConfig(CONFIG_AUCTION_LEVEL_REQ));
|
||||
return;
|
||||
}
|
||||
|
||||
AuctionHouseEntry const* ahEntry = AuctionHouseMgr::GetAuctionHouseEntry(unit->getFaction());
|
||||
if (!ahEntry)
|
||||
return;
|
||||
|
||||
WorldPacket data(MSG_AUCTION_HELLO, 12);
|
||||
data << uint64(guid);
|
||||
data << uint32(ahEntry->houseId);
|
||||
data << uint8(1); // 3.3.3: 1 - AH enabled, 0 - AH disabled
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
//call this method when player bids, creates, or deletes auction
|
||||
void WorldSession::SendAuctionCommandResult(uint32 auctionId, uint32 Action, uint32 ErrorCode, uint32 bidError)
|
||||
{
|
||||
WorldPacket data(SMSG_AUCTION_COMMAND_RESULT, 16);
|
||||
data << auctionId;
|
||||
data << Action;
|
||||
data << ErrorCode;
|
||||
if (!ErrorCode && Action)
|
||||
data << bidError; //when bid, then send 0, once...
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
//this function sends notification, if bidder is online
|
||||
void WorldSession::SendAuctionBidderNotification(uint32 location, uint32 auctionId, uint64 bidder, uint32 bidSum, uint32 diff, uint32 item_template)
|
||||
{
|
||||
WorldPacket data(SMSG_AUCTION_BIDDER_NOTIFICATION, (8*4));
|
||||
data << uint32(location);
|
||||
data << uint32(auctionId);
|
||||
data << uint64(bidder);
|
||||
data << uint32(bidSum);
|
||||
data << uint32(diff);
|
||||
data << uint32(item_template);
|
||||
data << uint32(0);
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
//this void causes on client to display: "Your auction sold"
|
||||
void WorldSession::SendAuctionOwnerNotification(AuctionEntry* auction)
|
||||
{
|
||||
WorldPacket data(SMSG_AUCTION_OWNER_NOTIFICATION, (7*4));
|
||||
data << auction->Id;
|
||||
data << auction->bid;
|
||||
data << (uint32) 0; //unk
|
||||
data << (uint32) 0; //unk
|
||||
data << (uint32) 0; //unk
|
||||
data << auction->item_template;
|
||||
data << (uint32) 0; //unk
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
//this function sends mail to old bidder
|
||||
void WorldSession::SendAuctionOutbiddedMail(AuctionEntry *auction, uint32 newPrice)
|
||||
{
|
||||
uint64 oldBidder_guid = MAKE_NEW_GUID(auction->bidder,0, HIGHGUID_PLAYER);
|
||||
Player *oldBidder = objmgr.GetPlayer(oldBidder_guid);
|
||||
|
||||
uint32 oldBidder_accId = 0;
|
||||
if (!oldBidder)
|
||||
oldBidder_accId = objmgr.GetPlayerAccountIdByGUID(oldBidder_guid);
|
||||
|
||||
// old bidder exist
|
||||
if (oldBidder || oldBidder_accId)
|
||||
{
|
||||
std::ostringstream msgAuctionOutbiddedSubject;
|
||||
msgAuctionOutbiddedSubject << auction->item_template << ":0:" << AUCTION_OUTBIDDED << ":0:0";
|
||||
|
||||
if (oldBidder && !_player)
|
||||
oldBidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, auctionbot.GetAHBplayerGUID(), newPrice, auction->GetAuctionOutBid(), auction->item_template);
|
||||
|
||||
if (oldBidder && _player)
|
||||
oldBidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, _player->GetGUID(), newPrice, auction->GetAuctionOutBid(), auction->item_template);
|
||||
|
||||
MailDraft(msgAuctionOutbiddedSubject.str(), "") // TODO: fix body
|
||||
.AddMoney(auction->bid)
|
||||
.SendMailTo(MailReceiver(oldBidder, auction->bidder), auction, MAIL_CHECK_MASK_COPIED);
|
||||
}
|
||||
}
|
||||
|
||||
//this function sends mail, when auction is cancelled to old bidder
|
||||
void WorldSession::SendAuctionCancelledToBidderMail(AuctionEntry* auction)
|
||||
{
|
||||
uint64 bidder_guid = MAKE_NEW_GUID(auction->bidder, 0, HIGHGUID_PLAYER);
|
||||
Player *bidder = objmgr.GetPlayer(bidder_guid);
|
||||
|
||||
uint32 bidder_accId = 0;
|
||||
if (!bidder)
|
||||
bidder_accId = objmgr.GetPlayerAccountIdByGUID(bidder_guid);
|
||||
|
||||
// bidder exist
|
||||
if (bidder || bidder_accId)
|
||||
{
|
||||
std::ostringstream msgAuctionCancelledSubject;
|
||||
msgAuctionCancelledSubject << auction->item_template << ":0:" << AUCTION_CANCELLED_TO_BIDDER << ":0:0";
|
||||
|
||||
MailDraft(msgAuctionCancelledSubject.str(), "") // TODO: fix body
|
||||
.AddMoney(auction->bid)
|
||||
.SendMailTo(MailReceiver(bidder, auction->bidder), auction, MAIL_CHECK_MASK_COPIED);
|
||||
}
|
||||
}
|
||||
|
||||
//this void creates new auction and adds auction to some auctionhouse
|
||||
void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data)
|
||||
{
|
||||
uint64 auctioneer, item;
|
||||
uint32 etime, bid, buyout;
|
||||
recv_data >> auctioneer;
|
||||
recv_data.read_skip<uint32>(); // const 1?
|
||||
recv_data >> item;
|
||||
recv_data.read_skip<uint32>(); // unk 3.2.2, const 1?
|
||||
recv_data >> bid;
|
||||
recv_data >> buyout;
|
||||
recv_data >> etime;
|
||||
|
||||
Player *pl = GetPlayer();
|
||||
|
||||
if (!item || !bid || !etime)
|
||||
return; //check for cheaters
|
||||
|
||||
Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer,UNIT_NPC_FLAG_AUCTIONEER);
|
||||
if (!pCreature)
|
||||
{
|
||||
sLog.outDebug("WORLD: HandleAuctionSellItem - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer)));
|
||||
return;
|
||||
}
|
||||
|
||||
AuctionHouseEntry const* auctionHouseEntry = AuctionHouseMgr::GetAuctionHouseEntry(pCreature->getFaction());
|
||||
if (!auctionHouseEntry)
|
||||
{
|
||||
sLog.outDebug("WORLD: HandleAuctionSellItem - Unit (GUID: %u) has wrong faction.", uint32(GUID_LOPART(auctioneer)));
|
||||
return;
|
||||
}
|
||||
|
||||
sLog.outDebug("WORLD: HandleAuctionSellItem - ETIME: %u", etime);
|
||||
|
||||
// client send time in minutes, convert to common used sec time
|
||||
etime *= MINUTE;
|
||||
|
||||
sLog.outDebug("WORLD: HandleAuctionSellItem - ETIME: %u", etime);
|
||||
|
||||
// client understand only 3 auction time
|
||||
switch(etime)
|
||||
{
|
||||
case 1*MIN_AUCTION_TIME:
|
||||
case 2*MIN_AUCTION_TIME:
|
||||
case 4*MIN_AUCTION_TIME:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
Item *it = pl->GetItemByGuid(item);
|
||||
//do not allow to sell already auctioned items
|
||||
if (auctionmgr.GetAItem(GUID_LOPART(item)))
|
||||
{
|
||||
sLog.outError("AuctionError, player %s is sending item id: %u, but item is already in another auction", pl->GetName(), GUID_LOPART(item));
|
||||
SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR);
|
||||
return;
|
||||
}
|
||||
// prevent sending bag with items (cheat: can be placed in bag after adding equiped empty bag to auction)
|
||||
if (!it)
|
||||
{
|
||||
SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_ITEM_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!it->CanBeTraded())
|
||||
{
|
||||
SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (it->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_CONJURED) || it->GetUInt32Value(ITEM_FIELD_DURATION))
|
||||
{
|
||||
SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap(pCreature->getFaction());
|
||||
|
||||
//we have to take deposit :
|
||||
uint32 deposit = auctionmgr.GetAuctionDeposit(auctionHouseEntry, etime, it);
|
||||
if (pl->GetMoney() < deposit)
|
||||
{
|
||||
SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_NOT_ENOUGHT_MONEY);
|
||||
return;
|
||||
}
|
||||
|
||||
if (GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE))
|
||||
{
|
||||
sLog.outCommand(GetAccountId(),"GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)",
|
||||
GetPlayerName(),GetAccountId(),it->GetProto()->Name1,it->GetEntry(),it->GetCount());
|
||||
}
|
||||
|
||||
pl->ModifyMoney(-int32(deposit));
|
||||
|
||||
uint32 auction_time = uint32(etime * sWorld.getRate(RATE_AUCTION_TIME));
|
||||
|
||||
AuctionEntry *AH = new AuctionEntry;
|
||||
AH->Id = objmgr.GenerateAuctionID();
|
||||
if (sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
|
||||
AH->auctioneer = 23442;
|
||||
else
|
||||
AH->auctioneer = GUID_LOPART(auctioneer);
|
||||
AH->item_guidlow = GUID_LOPART(item);
|
||||
AH->item_template = it->GetEntry();
|
||||
AH->owner = pl->GetGUIDLow();
|
||||
AH->startbid = bid;
|
||||
AH->bidder = 0;
|
||||
AH->bid = 0;
|
||||
AH->buyout = buyout;
|
||||
AH->expire_time = time(NULL) + auction_time;
|
||||
AH->deposit = deposit;
|
||||
AH->auctionHouseEntry = auctionHouseEntry;
|
||||
|
||||
sLog.outDetail("selling item %u to auctioneer %u with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u", GUID_LOPART(item), AH->auctioneer, bid, buyout, auction_time, AH->GetHouseId());
|
||||
auctionmgr.AddAItem(it);
|
||||
auctionHouse->AddAuction(AH);
|
||||
|
||||
pl->MoveItemFromInventory(it->GetBagSlot(), it->GetSlot(), true);
|
||||
|
||||
CharacterDatabase.BeginTransaction();
|
||||
it->DeleteFromInventoryDB();
|
||||
it->SaveToDB(); // recursive and not have transaction guard into self, not in inventiory and can be save standalone
|
||||
AH->SaveToDB();
|
||||
pl->SaveInventoryAndGoldToDB();
|
||||
CharacterDatabase.CommitTransaction();
|
||||
|
||||
SendAuctionCommandResult(AH->Id, AUCTION_SELL_ITEM, AUCTION_OK);
|
||||
|
||||
GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1);
|
||||
}
|
||||
|
||||
//this function is called when client bids or buys out auction
|
||||
void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data)
|
||||
{
|
||||
uint64 auctioneer;
|
||||
uint32 auctionId;
|
||||
uint32 price;
|
||||
recv_data >> auctioneer;
|
||||
recv_data >> auctionId >> price;
|
||||
|
||||
if (!auctionId || !price)
|
||||
return; //check for cheaters
|
||||
|
||||
Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer, UNIT_NPC_FLAG_AUCTIONEER);
|
||||
if (!pCreature)
|
||||
{
|
||||
sLog.outDebug("WORLD: HandleAuctionPlaceBid - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer)));
|
||||
return;
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
AuctionHouseObject *auctionHouse = auctionmgr.GetAuctionsMap(pCreature->getFaction());
|
||||
|
||||
AuctionEntry *auction = auctionHouse->GetAuction(auctionId);
|
||||
Player *pl = GetPlayer();
|
||||
|
||||
if (!auction || auction->owner == pl->GetGUIDLow())
|
||||
{
|
||||
//you cannot bid your own auction:
|
||||
SendAuctionCommandResult(0, AUCTION_PLACE_BID, CANNOT_BID_YOUR_AUCTION_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
// impossible have online own another character (use this for speedup check in case online owner)
|
||||
Player* auction_owner = objmgr.GetPlayer(MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER));
|
||||
if (!auction_owner && objmgr.GetPlayerAccountIdByGUID(MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER)) == pl->GetSession()->GetAccountId())
|
||||
{
|
||||
//you cannot bid your another character auction:
|
||||
SendAuctionCommandResult(0, AUCTION_PLACE_BID, CANNOT_BID_YOUR_AUCTION_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
// cheating
|
||||
if (price <= auction->bid || price < auction->startbid)
|
||||
return;
|
||||
|
||||
// price too low for next bid if not buyout
|
||||
if ((price < auction->buyout || auction->buyout == 0) &&
|
||||
price < auction->bid + auction->GetAuctionOutBid())
|
||||
{
|
||||
//auction has already higher bid, client tests it!
|
||||
return;
|
||||
}
|
||||
|
||||
if (price > pl->GetMoney())
|
||||
{
|
||||
//you don't have enought money!, client tests!
|
||||
//SendAuctionCommandResult(auction->auctionId, AUCTION_PLACE_BID, ???);
|
||||
return;
|
||||
}
|
||||
|
||||
if (price < auction->buyout || auction->buyout == 0)
|
||||
{
|
||||
if (auction->bidder > 0)
|
||||
{
|
||||
if (auction->bidder == pl->GetGUIDLow())
|
||||
pl->ModifyMoney(-int32(price - auction->bid));
|
||||
else
|
||||
{
|
||||
// mail to last bidder and return money
|
||||
SendAuctionOutbiddedMail(auction, price);
|
||||
pl->ModifyMoney(-int32(price));
|
||||
}
|
||||
}
|
||||
else
|
||||
pl->ModifyMoney(-int32(price));
|
||||
|
||||
auction->bidder = pl->GetGUIDLow();
|
||||
auction->bid = price;
|
||||
GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, price);
|
||||
|
||||
// after this update we should save player's money ...
|
||||
CharacterDatabase.BeginTransaction();
|
||||
CharacterDatabase.PExecute("UPDATE auctionhouse SET buyguid = '%u',lastbid = '%u' WHERE id = '%u'", auction->bidder, auction->bid, auction->Id);
|
||||
|
||||
SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, AUCTION_OK, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
//buyout:
|
||||
if (pl->GetGUIDLow() == auction->bidder)
|
||||
pl->ModifyMoney(-int32(auction->buyout - auction->bid));
|
||||
else
|
||||
{
|
||||
pl->ModifyMoney(-int32(auction->buyout));
|
||||
if (auction->bidder) //buyout for bidded auction ..
|
||||
SendAuctionOutbiddedMail(auction, auction->buyout);
|
||||
}
|
||||
auction->bidder = pl->GetGUIDLow();
|
||||
auction->bid = auction->buyout;
|
||||
GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, auction->buyout);
|
||||
|
||||
auctionmgr.SendAuctionSalePendingMail(auction);
|
||||
auctionmgr.SendAuctionSuccessfulMail(auction);
|
||||
auctionmgr.SendAuctionWonMail(auction);
|
||||
|
||||
SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, AUCTION_OK);
|
||||
|
||||
CharacterDatabase.BeginTransaction();
|
||||
auction->DeleteFromDB();
|
||||
uint32 item_template = auction->item_template;
|
||||
auctionmgr.RemoveAItem(auction->item_guidlow);
|
||||
auctionHouse->RemoveAuction(auction, item_template);
|
||||
}
|
||||
pl->SaveInventoryAndGoldToDB();
|
||||
CharacterDatabase.CommitTransaction();
|
||||
}
|
||||
|
||||
//this void is called when auction_owner cancels his auction
|
||||
void WorldSession::HandleAuctionRemoveItem(WorldPacket & recv_data)
|
||||
{
|
||||
uint64 auctioneer;
|
||||
uint32 auctionId;
|
||||
recv_data >> auctioneer;
|
||||
recv_data >> auctionId;
|
||||
//sLog.outDebug("Cancel AUCTION AuctionID: %u", auctionId);
|
||||
|
||||
Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer,UNIT_NPC_FLAG_AUCTIONEER);
|
||||
if (!pCreature)
|
||||
{
|
||||
sLog.outDebug("WORLD: HandleAuctionRemoveItem - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer)));
|
||||
return;
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap(pCreature->getFaction());
|
||||
|
||||
AuctionEntry *auction = auctionHouse->GetAuction(auctionId);
|
||||
Player *pl = GetPlayer();
|
||||
|
||||
if (auction && auction->owner == pl->GetGUIDLow())
|
||||
{
|
||||
Item *pItem = auctionmgr.GetAItem(auction->item_guidlow);
|
||||
if (pItem)
|
||||
{
|
||||
if (auction->bidder > 0) // If we have a bidder, we have to send him the money he paid
|
||||
{
|
||||
uint32 auctionCut = auction->GetAuctionCut();
|
||||
if (pl->GetMoney() < auctionCut) //player doesn't have enough money, maybe message needed
|
||||
return;
|
||||
//some auctionBidderNotification would be needed, but don't know that parts..
|
||||
SendAuctionCancelledToBidderMail(auction);
|
||||
pl->ModifyMoney(-int32(auctionCut));
|
||||
}
|
||||
// Return the item by mail
|
||||
std::ostringstream msgAuctionCanceledOwner;
|
||||
msgAuctionCanceledOwner << auction->item_template << ":0:" << AUCTION_CANCELED << ":0:0";
|
||||
|
||||
// item will deleted or added to received mail list
|
||||
MailDraft(msgAuctionCanceledOwner.str(), "") // TODO: fix body
|
||||
.AddItem(pItem)
|
||||
.SendMailTo(pl, auction, MAIL_CHECK_MASK_COPIED);
|
||||
}
|
||||
else
|
||||
{
|
||||
sLog.outError("Auction id: %u has non-existed item (item guid : %u)!!!", auction->Id, auction->item_guidlow);
|
||||
SendAuctionCommandResult(0, AUCTION_CANCEL, AUCTION_INTERNAL_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SendAuctionCommandResult(0, AUCTION_CANCEL, AUCTION_INTERNAL_ERROR);
|
||||
//this code isn't possible ... maybe there should be assert
|
||||
sLog.outError("CHEATER : %u, he tried to cancel auction (id: %u) of another player, or auction is NULL", pl->GetGUIDLow(), auctionId);
|
||||
return;
|
||||
}
|
||||
|
||||
//inform player, that auction is removed
|
||||
SendAuctionCommandResult(auction->Id, AUCTION_CANCEL, AUCTION_OK);
|
||||
|
||||
// Now remove the auction
|
||||
CharacterDatabase.BeginTransaction();
|
||||
pl->SaveInventoryAndGoldToDB();
|
||||
auction->DeleteFromDB();
|
||||
uint32 item_template = auction->item_template;
|
||||
auctionmgr.RemoveAItem(auction->item_guidlow);
|
||||
auctionHouse->RemoveAuction(auction, item_template);
|
||||
CharacterDatabase.CommitTransaction();
|
||||
}
|
||||
|
||||
//called when player lists his bids
|
||||
void WorldSession::HandleAuctionListBidderItems(WorldPacket & recv_data)
|
||||
{
|
||||
uint64 guid; //NPC guid
|
||||
uint32 listfrom; //page of auctions
|
||||
uint32 outbiddedCount; //count of outbidded auctions
|
||||
|
||||
recv_data >> guid;
|
||||
recv_data >> listfrom; // not used in fact (this list not have page control in client)
|
||||
recv_data >> outbiddedCount;
|
||||
if (recv_data.size() != (16 + outbiddedCount * 4))
|
||||
{
|
||||
sLog.outError("Client sent bad opcode!!! with count: %u and size : %lu (must be: %u)", outbiddedCount, (unsigned long)recv_data.size(),(16 + outbiddedCount * 4));
|
||||
outbiddedCount = 0;
|
||||
}
|
||||
|
||||
Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_AUCTIONEER);
|
||||
if (!pCreature)
|
||||
{
|
||||
sLog.outDebug("WORLD: HandleAuctionListBidderItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)));
|
||||
return;
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap(pCreature->getFaction());
|
||||
|
||||
WorldPacket data(SMSG_AUCTION_BIDDER_LIST_RESULT, (4+4+4));
|
||||
Player *pl = GetPlayer();
|
||||
data << (uint32) 0; //add 0 as count
|
||||
uint32 count = 0;
|
||||
uint32 totalcount = 0;
|
||||
while (outbiddedCount > 0) //add all data, which client requires
|
||||
{
|
||||
--outbiddedCount;
|
||||
uint32 outbiddedAuctionId;
|
||||
recv_data >> outbiddedAuctionId;
|
||||
AuctionEntry * auction = auctionHouse->GetAuction(outbiddedAuctionId);
|
||||
if (auction && auction->BuildAuctionInfo(data))
|
||||
{
|
||||
++totalcount;
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
auctionHouse->BuildListBidderItems(data,pl,count,totalcount);
|
||||
data.put<uint32>(0, count); // add count to placeholder
|
||||
data << totalcount;
|
||||
data << (uint32)300; //unk 2.3.0
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
//this void sends player info about his auctions
|
||||
void WorldSession::HandleAuctionListOwnerItems(WorldPacket & recv_data)
|
||||
{
|
||||
uint32 listfrom;
|
||||
uint64 guid;
|
||||
|
||||
recv_data >> guid;
|
||||
recv_data >> listfrom; // not used in fact (this list not have page control in client)
|
||||
|
||||
Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_AUCTIONEER);
|
||||
if (!pCreature)
|
||||
{
|
||||
sLog.outDebug("WORLD: HandleAuctionListOwnerItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)));
|
||||
return;
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap(pCreature->getFaction());
|
||||
|
||||
WorldPacket data(SMSG_AUCTION_OWNER_LIST_RESULT, (4+4+4));
|
||||
data << (uint32) 0; // amount place holder
|
||||
|
||||
uint32 count = 0;
|
||||
uint32 totalcount = 0;
|
||||
|
||||
auctionHouse->BuildListOwnerItems(data,_player,count,totalcount);
|
||||
data.put<uint32>(0, count);
|
||||
data << (uint32) totalcount;
|
||||
data << (uint32) 0;
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
//this void is called when player clicks on search button
|
||||
void WorldSession::HandleAuctionListItems(WorldPacket & recv_data)
|
||||
{
|
||||
std::string searchedname;
|
||||
uint8 levelmin, levelmax, usable;
|
||||
uint32 listfrom, auctionSlotID, auctionMainCategory, auctionSubCategory, quality;
|
||||
uint64 guid;
|
||||
|
||||
recv_data >> guid;
|
||||
recv_data >> listfrom; // start, used for page control listing by 50 elements
|
||||
recv_data >> searchedname;
|
||||
|
||||
recv_data >> levelmin >> levelmax;
|
||||
recv_data >> auctionSlotID >> auctionMainCategory >> auctionSubCategory;
|
||||
recv_data >> quality >> usable;
|
||||
|
||||
recv_data.read_skip(16); // unknown 16 bytes: 00 07 01 00 00 01 05 00 06 00 09 01 08 00 03 00
|
||||
|
||||
Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_AUCTIONEER);
|
||||
if (!pCreature)
|
||||
{
|
||||
sLog.outDebug("WORLD: HandleAuctionListItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)));
|
||||
return;
|
||||
}
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
||||
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap(pCreature->getFaction());
|
||||
|
||||
//sLog.outDebug("Auctionhouse search (GUID: %u TypeId: %u)", , list from: %u, searchedname: %s, levelmin: %u, levelmax: %u, auctionSlotID: %u, auctionMainCategory: %u, auctionSubCategory: %u, quality: %u, usable: %u",
|
||||
// GUID_LOPART(guid),GuidHigh2TypeId(GUID_HIPART(guid)), listfrom, searchedname.c_str(), levelmin, levelmax, auctionSlotID, auctionMainCategory, auctionSubCategory, quality, usable);
|
||||
|
||||
WorldPacket data(SMSG_AUCTION_LIST_RESULT, (4+4+4));
|
||||
uint32 count = 0;
|
||||
uint32 totalcount = 0;
|
||||
data << (uint32) 0;
|
||||
|
||||
// converting string that we try to find to lower case
|
||||
std::wstring wsearchedname;
|
||||
if (!Utf8toWStr(searchedname,wsearchedname))
|
||||
return;
|
||||
|
||||
wstrToLower(wsearchedname);
|
||||
|
||||
auctionHouse->BuildListAuctionItems(data,_player,
|
||||
wsearchedname, listfrom, levelmin, levelmax, usable,
|
||||
auctionSlotID, auctionMainCategory, auctionSubCategory, quality,
|
||||
count,totalcount);
|
||||
|
||||
data.put<uint32>(0, count);
|
||||
data << (uint32) totalcount;
|
||||
data << (uint32) 300; // unk 2.3.0 const?
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::HandleAuctionListPendingSales(WorldPacket & recv_data)
|
||||
{
|
||||
sLog.outDebug("CMSG_AUCTION_LIST_PENDING_SALES");
|
||||
|
||||
recv_data.read_skip<uint64>();
|
||||
|
||||
uint32 count = 0;
|
||||
|
||||
WorldPacket data(SMSG_AUCTION_LIST_PENDING_SALES, 4);
|
||||
data << uint32(count); // count
|
||||
/*for (uint32 i = 0; i < count; ++i)
|
||||
{
|
||||
data << ""; // string
|
||||
data << ""; // string
|
||||
data << uint32(0);
|
||||
data << uint32(0);
|
||||
data << float(0);
|
||||
}*/
|
||||
SendPacket(&data);
|
||||
}
|
||||
Executable
+750
@@ -0,0 +1,750 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Common.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Player.h"
|
||||
#include "World.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "Database/SQLStorage.h"
|
||||
#include "Policies/SingletonImp.h"
|
||||
#include "DBCStores.h"
|
||||
|
||||
#include "AccountMgr.h"
|
||||
#include "AuctionHouseMgr.h"
|
||||
#include "Item.h"
|
||||
#include "Language.h"
|
||||
#include "Log.h"
|
||||
#include "ProgressBar.h"
|
||||
#include <vector>
|
||||
|
||||
INSTANTIATE_SINGLETON_1(AuctionHouseMgr);
|
||||
|
||||
using namespace std;
|
||||
|
||||
AuctionHouseMgr::AuctionHouseMgr()
|
||||
{
|
||||
}
|
||||
|
||||
AuctionHouseMgr::~AuctionHouseMgr()
|
||||
{
|
||||
for (ItemMap::const_iterator itr = mAitems.begin(); itr != mAitems.end(); ++itr)
|
||||
delete itr->second;
|
||||
}
|
||||
|
||||
AuctionHouseObject * AuctionHouseMgr::GetAuctionsMap(uint32 factionTemplateId)
|
||||
{
|
||||
if (sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
|
||||
return &mNeutralAuctions;
|
||||
|
||||
// team have linked auction houses
|
||||
FactionTemplateEntry const* u_entry = sFactionTemplateStore.LookupEntry(factionTemplateId);
|
||||
if (!u_entry)
|
||||
return &mNeutralAuctions;
|
||||
else if (u_entry->ourMask & FACTION_MASK_ALLIANCE)
|
||||
return &mAllianceAuctions;
|
||||
else if (u_entry->ourMask & FACTION_MASK_HORDE)
|
||||
return &mHordeAuctions;
|
||||
else
|
||||
return &mNeutralAuctions;
|
||||
}
|
||||
|
||||
uint32 AuctionHouseMgr::GetAuctionDeposit(AuctionHouseEntry const* entry, uint32 time, Item *pItem)
|
||||
{
|
||||
uint32 MSV = pItem->GetProto()->SellPrice;
|
||||
int32 deposit;
|
||||
uint32 timeHr = (((time / 60) / 60) / 12);
|
||||
|
||||
if (MSV > 0)
|
||||
deposit = (int32)floor((double)MSV * (((double)(entry->depositPercent * 3) / 100.0f * (double)sWorld.getRate(RATE_AUCTION_DEPOSIT) * (double)pItem->GetCount()))) * timeHr;
|
||||
else
|
||||
deposit = 0;
|
||||
|
||||
sLog.outDebug("Sellprice: %u / Depositpercent: %f / AT1: %u / AT2: %u / AT3: %u / Count: %u", MSV, ((double)entry->depositPercent / 100.0f), time, MIN_AUCTION_TIME, timeHr, pItem->GetCount() );
|
||||
if (deposit > 0)
|
||||
{
|
||||
sLog.outDebug("Deposit: %u", deposit);
|
||||
return deposit;
|
||||
}
|
||||
else
|
||||
{
|
||||
sLog.outDebug("Deposit: 0");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//does not clear ram
|
||||
void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry *auction)
|
||||
{
|
||||
Item *pItem = GetAItem(auction->item_guidlow);
|
||||
if (!pItem)
|
||||
return;
|
||||
|
||||
uint32 bidder_accId = 0;
|
||||
uint32 bidder_security = 0;
|
||||
uint64 bidder_guid = MAKE_NEW_GUID(auction->bidder, 0, HIGHGUID_PLAYER);
|
||||
Player *bidder = objmgr.GetPlayer(bidder_guid);
|
||||
// data for gm.log
|
||||
if (sWorld.getConfig(CONFIG_GM_LOG_TRADE))
|
||||
{
|
||||
std::string bidder_name;
|
||||
if (bidder)
|
||||
{
|
||||
bidder_accId = bidder->GetSession()->GetAccountId();
|
||||
bidder_security = bidder->GetSession()->GetSecurity();
|
||||
bidder_name = bidder->GetName();
|
||||
}
|
||||
else
|
||||
{
|
||||
bidder_accId = objmgr.GetPlayerAccountIdByGUID(bidder_guid);
|
||||
bidder_security = accmgr.GetSecurity(bidder_accId);
|
||||
|
||||
if (bidder_security > SEC_PLAYER) // not do redundant DB requests
|
||||
{
|
||||
if (!objmgr.GetPlayerNameByGUID(bidder_guid,bidder_name))
|
||||
bidder_name = objmgr.GetTrinityStringForDBCLocale(LANG_UNKNOWN);
|
||||
}
|
||||
}
|
||||
if (bidder_security > SEC_PLAYER)
|
||||
{
|
||||
std::string owner_name;
|
||||
if (!objmgr.GetPlayerNameByGUID(auction->owner,owner_name))
|
||||
owner_name = objmgr.GetTrinityStringForDBCLocale(LANG_UNKNOWN);
|
||||
|
||||
uint32 owner_accid = objmgr.GetPlayerAccountIdByGUID(auction->owner);
|
||||
|
||||
sLog.outCommand(bidder_accId,"GM %s (Account: %u) won item in auction: %s (Entry: %u Count: %u) and pay money: %u. Original owner %s (Account: %u)",
|
||||
bidder_name.c_str(),bidder_accId,pItem->GetProto()->Name1,pItem->GetEntry(),pItem->GetCount(),auction->bid,owner_name.c_str(),owner_accid);
|
||||
}
|
||||
}
|
||||
|
||||
// receiver exist
|
||||
if (bidder || bidder_accId)
|
||||
{
|
||||
std::ostringstream msgAuctionWonSubject;
|
||||
msgAuctionWonSubject << auction->item_template << ":0:" << AUCTION_WON;
|
||||
|
||||
std::ostringstream msgAuctionWonBody;
|
||||
msgAuctionWonBody.width(16);
|
||||
msgAuctionWonBody << std::right << std::hex << auction->owner;
|
||||
msgAuctionWonBody << std::dec << ":" << auction->bid << ":" << auction->buyout;
|
||||
sLog.outDebug("AuctionWon body string : %s", msgAuctionWonBody.str().c_str());
|
||||
|
||||
// set owner to bidder (to prevent delete item with sender char deleting)
|
||||
// owner in `data` will set at mail receive and item extracting
|
||||
CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'",auction->bidder,pItem->GetGUIDLow());
|
||||
|
||||
if (bidder)
|
||||
{
|
||||
bidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, bidder_guid, 0, 0, auction->item_template);
|
||||
// FIXME: for offline player need also
|
||||
bidder->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS, 1);
|
||||
}
|
||||
|
||||
MailDraft(msgAuctionWonSubject.str(), msgAuctionWonBody.str())
|
||||
.AddItem(pItem)
|
||||
.SendMailTo(MailReceiver(bidder,auction->bidder), auction, MAIL_CHECK_MASK_COPIED);
|
||||
}
|
||||
}
|
||||
|
||||
void AuctionHouseMgr::SendAuctionSalePendingMail(AuctionEntry * auction)
|
||||
{
|
||||
uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER);
|
||||
Player *owner = objmgr.GetPlayer(owner_guid);
|
||||
uint32 owner_accId = objmgr.GetPlayerAccountIdByGUID(owner_guid);
|
||||
// owner exist (online or offline)
|
||||
if (owner || owner_accId)
|
||||
{
|
||||
std::ostringstream msgAuctionSalePendingSubject;
|
||||
msgAuctionSalePendingSubject << auction->item_template << ":0:" << AUCTION_SALE_PENDING;
|
||||
|
||||
std::ostringstream msgAuctionSalePendingBody;
|
||||
uint32 auctionCut = auction->GetAuctionCut();
|
||||
|
||||
time_t distrTime = time(NULL) + sWorld.getConfig(CONFIG_MAIL_DELIVERY_DELAY);
|
||||
|
||||
msgAuctionSalePendingBody.width(16);
|
||||
msgAuctionSalePendingBody << std::right << std::hex << auction->bidder;
|
||||
msgAuctionSalePendingBody << std::dec << ":" << auction->bid << ":" << auction->buyout;
|
||||
msgAuctionSalePendingBody << ":" << auction->deposit << ":" << auctionCut << ":0:";
|
||||
msgAuctionSalePendingBody << secsToTimeBitFields(distrTime);
|
||||
|
||||
sLog.outDebug("AuctionSalePending body string : %s", msgAuctionSalePendingBody.str().c_str());
|
||||
|
||||
MailDraft(msgAuctionSalePendingSubject.str(), msgAuctionSalePendingBody.str())
|
||||
.SendMailTo(MailReceiver(owner,auction->owner), auction, MAIL_CHECK_MASK_COPIED);
|
||||
}
|
||||
}
|
||||
|
||||
//call this method to send mail to auction owner, when auction is successful, it does not clear ram
|
||||
void AuctionHouseMgr::SendAuctionSuccessfulMail(AuctionEntry * auction)
|
||||
{
|
||||
uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER);
|
||||
Player *owner = objmgr.GetPlayer(owner_guid);
|
||||
uint32 owner_accId = objmgr.GetPlayerAccountIdByGUID(owner_guid);
|
||||
// owner exist
|
||||
if (owner || owner_accId)
|
||||
{
|
||||
std::ostringstream msgAuctionSuccessfulSubject;
|
||||
msgAuctionSuccessfulSubject << auction->item_template << ":0:" << AUCTION_SUCCESSFUL;
|
||||
|
||||
std::ostringstream auctionSuccessfulBody;
|
||||
uint32 auctionCut = auction->GetAuctionCut();
|
||||
|
||||
auctionSuccessfulBody.width(16);
|
||||
auctionSuccessfulBody << std::right << std::hex << auction->bidder;
|
||||
auctionSuccessfulBody << std::dec << ":" << auction->bid << ":" << auction->buyout;
|
||||
auctionSuccessfulBody << ":" << auction->deposit << ":" << auctionCut;
|
||||
|
||||
sLog.outDebug("AuctionSuccessful body string : %s", auctionSuccessfulBody.str().c_str());
|
||||
|
||||
uint32 profit = auction->bid + auction->deposit - auctionCut;
|
||||
|
||||
//FIXME: what do if owner offline
|
||||
if (owner && owner->GetGUIDLow() != auctionbot.GetAHBplayerGUID())
|
||||
{
|
||||
owner->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS, profit);
|
||||
owner->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD, auction->bid);
|
||||
//send auction owner notification, bidder must be current!
|
||||
owner->GetSession()->SendAuctionOwnerNotification(auction);
|
||||
}
|
||||
MailDraft(msgAuctionSuccessfulSubject.str(), auctionSuccessfulBody.str())
|
||||
.AddMoney(profit)
|
||||
.SendMailTo(MailReceiver(owner,auction->owner), auction, MAIL_CHECK_MASK_COPIED, sWorld.getConfig(CONFIG_MAIL_DELIVERY_DELAY));
|
||||
}
|
||||
}
|
||||
|
||||
//does not clear ram
|
||||
void AuctionHouseMgr::SendAuctionExpiredMail(AuctionEntry * auction)
|
||||
{ //return an item in auction to its owner by mail
|
||||
Item *pItem = GetAItem(auction->item_guidlow);
|
||||
if (!pItem)
|
||||
return;
|
||||
|
||||
uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER);
|
||||
Player *owner = objmgr.GetPlayer(owner_guid);
|
||||
uint32 owner_accId = objmgr.GetPlayerAccountIdByGUID(owner_guid);
|
||||
// owner exist
|
||||
if (owner || owner_accId)
|
||||
{
|
||||
std::ostringstream subject;
|
||||
subject << auction->item_template << ":0:" << AUCTION_EXPIRED << ":0:0";
|
||||
|
||||
if (owner && owner->GetGUIDLow() != auctionbot.GetAHBplayerGUID())
|
||||
owner->GetSession()->SendAuctionOwnerNotification(auction);
|
||||
|
||||
MailDraft(subject.str(), "") // TODO: fix body
|
||||
.AddItem(pItem)
|
||||
.SendMailTo(MailReceiver(owner,auction->owner), auction, MAIL_CHECK_MASK_COPIED);
|
||||
}
|
||||
}
|
||||
|
||||
void AuctionHouseMgr::LoadAuctionItems()
|
||||
{
|
||||
// data needs to be at first place for Item::LoadFromDB
|
||||
QueryResult_AutoPtr result = CharacterDatabase.Query("SELECT data, text, itemguid, item_template FROM auctionhouse JOIN item_instance ON itemguid = guid");
|
||||
|
||||
if (!result)
|
||||
{
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded 0 auction items");
|
||||
return;
|
||||
}
|
||||
|
||||
barGoLink bar(result->GetRowCount());
|
||||
|
||||
uint32 count = 0;
|
||||
|
||||
Field *fields;
|
||||
do
|
||||
{
|
||||
bar.step();
|
||||
|
||||
fields = result->Fetch();
|
||||
uint32 item_guid = fields[2].GetUInt32();
|
||||
uint32 item_template = fields[3].GetUInt32();
|
||||
|
||||
ItemPrototype const *proto = objmgr.GetItemPrototype(item_template);
|
||||
|
||||
if (!proto)
|
||||
{
|
||||
sLog.outError("AuctionHouseMgr::LoadAuctionItems: Unknown item (GUID: %u id: #%u) in auction, skipped.", item_guid,item_template);
|
||||
continue;
|
||||
}
|
||||
|
||||
Item *item = NewItemOrBag(proto);
|
||||
|
||||
if (!item->LoadFromDB(item_guid,0, result))
|
||||
{
|
||||
delete item;
|
||||
continue;
|
||||
}
|
||||
AddAItem(item);
|
||||
|
||||
++count;
|
||||
} while (result->NextRow());
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded %u auction items", count);
|
||||
}
|
||||
|
||||
void AuctionHouseMgr::LoadAuctions()
|
||||
{
|
||||
QueryResult_AutoPtr result = CharacterDatabase.Query("SELECT COUNT(*) FROM auctionhouse");
|
||||
if (!result)
|
||||
{
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
Field *fields = result->Fetch();
|
||||
uint32 AuctionCount=fields[0].GetUInt32();
|
||||
|
||||
if (!AuctionCount)
|
||||
{
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
result = CharacterDatabase.Query("SELECT id,auctioneerguid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit FROM auctionhouse");
|
||||
if (!result)
|
||||
{
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
barGoLink bar(AuctionCount);
|
||||
|
||||
AuctionEntry *aItem;
|
||||
|
||||
do
|
||||
{
|
||||
fields = result->Fetch();
|
||||
|
||||
bar.step();
|
||||
|
||||
aItem = new AuctionEntry;
|
||||
aItem->Id = fields[0].GetUInt32();
|
||||
aItem->auctioneer = fields[1].GetUInt32();
|
||||
aItem->item_guidlow = fields[2].GetUInt32();
|
||||
aItem->item_template = fields[3].GetUInt32();
|
||||
aItem->owner = fields[4].GetUInt32();
|
||||
aItem->buyout = fields[5].GetUInt32();
|
||||
aItem->expire_time = fields[6].GetUInt32();
|
||||
aItem->bidder = fields[7].GetUInt32();
|
||||
aItem->bid = fields[8].GetUInt32();
|
||||
aItem->startbid = fields[9].GetUInt32();
|
||||
aItem->deposit = fields[10].GetUInt32();
|
||||
|
||||
CreatureData const* auctioneerData = objmgr.GetCreatureData(aItem->auctioneer);
|
||||
if (!auctioneerData)
|
||||
{
|
||||
aItem->DeleteFromDB();
|
||||
sLog.outError("Auction %u has not a existing auctioneer (GUID : %u)", aItem->Id, aItem->auctioneer);
|
||||
delete aItem;
|
||||
continue;
|
||||
}
|
||||
|
||||
CreatureInfo const* auctioneerInfo = objmgr.GetCreatureTemplate(auctioneerData->id);
|
||||
if (!auctioneerInfo)
|
||||
{
|
||||
aItem->DeleteFromDB();
|
||||
sLog.outError("Auction %u has not a existing auctioneer (GUID : %u Entry: %u)", aItem->Id, aItem->auctioneer,auctioneerData->id);
|
||||
delete aItem;
|
||||
continue;
|
||||
}
|
||||
|
||||
aItem->auctionHouseEntry = AuctionHouseMgr::GetAuctionHouseEntry(auctioneerInfo->faction_A);
|
||||
if (!aItem->auctionHouseEntry)
|
||||
{
|
||||
aItem->DeleteFromDB();
|
||||
sLog.outError("Auction %u has auctioneer (GUID : %u Entry: %u) with wrong faction %u",
|
||||
aItem->Id, aItem->auctioneer,auctioneerData->id,auctioneerInfo->faction_A);
|
||||
delete aItem;
|
||||
continue;
|
||||
}
|
||||
|
||||
// check if sold item exists for guid
|
||||
// and item_template in fact (GetAItem will fail if problematic in result check in AuctionHouseMgr::LoadAuctionItems)
|
||||
if (!GetAItem(aItem->item_guidlow))
|
||||
{
|
||||
aItem->DeleteFromDB();
|
||||
sLog.outError("Auction %u has not a existing item : %u", aItem->Id, aItem->item_guidlow);
|
||||
delete aItem;
|
||||
continue;
|
||||
}
|
||||
|
||||
GetAuctionsMap(auctioneerInfo->faction_A)->AddAuction(aItem);
|
||||
|
||||
} while (result->NextRow());
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded %u auctions", AuctionCount);
|
||||
}
|
||||
|
||||
void AuctionHouseMgr::AddAItem(Item* it)
|
||||
{
|
||||
ASSERT(it);
|
||||
ASSERT(mAitems.find(it->GetGUIDLow()) == mAitems.end());
|
||||
mAitems[it->GetGUIDLow()] = it;
|
||||
}
|
||||
|
||||
bool AuctionHouseMgr::RemoveAItem(uint32 id)
|
||||
{
|
||||
ItemMap::iterator i = mAitems.find(id);
|
||||
if (i == mAitems.end())
|
||||
return false;
|
||||
|
||||
mAitems.erase(i);
|
||||
return true;
|
||||
}
|
||||
|
||||
void AuctionHouseMgr::Update()
|
||||
{
|
||||
mHordeAuctions.Update();
|
||||
mAllianceAuctions.Update();
|
||||
mNeutralAuctions.Update();
|
||||
}
|
||||
|
||||
AuctionHouseEntry const* AuctionHouseMgr::GetAuctionHouseEntry(uint32 factionTemplateId)
|
||||
{
|
||||
uint32 houseid = 7; // goblin auction house
|
||||
|
||||
if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
|
||||
{
|
||||
//FIXME: found way for proper auctionhouse selection by another way
|
||||
// AuctionHouse.dbc have faction field with _player_ factions associated with auction house races.
|
||||
// but no easy way convert creature faction to player race faction for specific city
|
||||
switch(factionTemplateId)
|
||||
{
|
||||
case 12: houseid = 1; break; // human
|
||||
case 29: houseid = 6; break; // orc, and generic for horde
|
||||
case 55: houseid = 2; break; // dwarf, and generic for alliance
|
||||
case 68: houseid = 4; break; // undead
|
||||
case 80: houseid = 3; break; // n-elf
|
||||
case 104: houseid = 5; break; // trolls
|
||||
case 120: houseid = 7; break; // booty bay, neutral
|
||||
case 474: houseid = 7; break; // gadgetzan, neutral
|
||||
case 855: houseid = 7; break; // everlook, neutral
|
||||
case 1604: houseid = 6; break; // b-elfs,
|
||||
default: // for unknown case
|
||||
{
|
||||
FactionTemplateEntry const* u_entry = sFactionTemplateStore.LookupEntry(factionTemplateId);
|
||||
if (!u_entry)
|
||||
houseid = 7; // goblin auction house
|
||||
else if (u_entry->ourMask & FACTION_MASK_ALLIANCE)
|
||||
houseid = 1; // human auction house
|
||||
else if (u_entry->ourMask & FACTION_MASK_HORDE)
|
||||
houseid = 6; // orc auction house
|
||||
else
|
||||
houseid = 7; // goblin auction house
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sAuctionHouseStore.LookupEntry(houseid);
|
||||
}
|
||||
void AuctionHouseObject::AddAuction(AuctionEntry *ah)
|
||||
{
|
||||
ASSERT(ah);
|
||||
AuctionsMap[ah->Id] = ah;
|
||||
auctionbot.IncrementItemCounts(ah);
|
||||
}
|
||||
|
||||
bool AuctionHouseObject::RemoveAuction(AuctionEntry *auction, uint32 item_template)
|
||||
{
|
||||
auctionbot.DecrementItemCounts(auction, item_template);
|
||||
return AuctionsMap.erase(auction->Id) ? true : false;
|
||||
}
|
||||
|
||||
void AuctionHouseObject::Update()
|
||||
{
|
||||
time_t curTime = sWorld.GetGameTime();
|
||||
///- Handle expired auctions
|
||||
|
||||
// If storage is empty, no need to update. next == NULL in this case.
|
||||
if (AuctionsMap.empty())
|
||||
return;
|
||||
|
||||
QueryResult_AutoPtr result = CharacterDatabase.PQuery("SELECT id FROM auctionhouse WHERE time <= %u ORDER BY TIME ASC", (uint32)curTime+60);
|
||||
|
||||
if (!result)
|
||||
return;
|
||||
|
||||
if (result->GetRowCount() == 0)
|
||||
return;
|
||||
|
||||
vector<uint32> expiredAuctions;
|
||||
|
||||
do
|
||||
{
|
||||
uint32 tmpdata = result->Fetch()->GetUInt32();
|
||||
expiredAuctions.push_back(tmpdata);
|
||||
} while (result->NextRow());
|
||||
|
||||
while (!expiredAuctions.empty())
|
||||
{
|
||||
vector<uint32>::iterator iter = expiredAuctions.begin();
|
||||
|
||||
// from auctionhousehandler.cpp, creates auction pointer & player pointer
|
||||
AuctionEntry* auction = GetAuction(*iter);
|
||||
|
||||
// Erase the auction from the vector.
|
||||
expiredAuctions.erase(iter);
|
||||
|
||||
if (!auction)
|
||||
continue;
|
||||
|
||||
///- Either cancel the auction if there was no bidder
|
||||
if (auction->bidder == 0)
|
||||
auctionmgr.SendAuctionExpiredMail(auction);
|
||||
///- Or perform the transaction
|
||||
else
|
||||
{
|
||||
//we should send an "item sold" message if the seller is online
|
||||
//we send the item to the winner
|
||||
//we send the money to the seller
|
||||
auctionmgr.SendAuctionSuccessfulMail(auction);
|
||||
auctionmgr.SendAuctionWonMail(auction);
|
||||
}
|
||||
|
||||
///- In any case clear the auction
|
||||
CharacterDatabase.BeginTransaction();
|
||||
auction->DeleteFromDB();
|
||||
uint32 item_template = auction->item_template;
|
||||
auctionmgr.RemoveAItem(auction->item_guidlow);
|
||||
RemoveAuction(auction, item_template);
|
||||
CharacterDatabase.CommitTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
void AuctionHouseObject::BuildListBidderItems(WorldPacket& data, Player* player, uint32& count, uint32& totalcount)
|
||||
{
|
||||
for (AuctionEntryMap::const_iterator itr = AuctionsMap.begin(); itr != AuctionsMap.end(); ++itr)
|
||||
{
|
||||
AuctionEntry *Aentry = itr->second;
|
||||
if (Aentry && Aentry->bidder == player->GetGUIDLow())
|
||||
{
|
||||
if (itr->second->BuildAuctionInfo(data))
|
||||
++count;
|
||||
|
||||
++totalcount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AuctionHouseObject::BuildListOwnerItems(WorldPacket& data, Player* player, uint32& count, uint32& totalcount)
|
||||
{
|
||||
for (AuctionEntryMap::const_iterator itr = AuctionsMap.begin(); itr != AuctionsMap.end(); ++itr)
|
||||
{
|
||||
AuctionEntry *Aentry = itr->second;
|
||||
if (Aentry && Aentry->owner == player->GetGUIDLow())
|
||||
{
|
||||
if (Aentry->BuildAuctionInfo(data))
|
||||
++count;
|
||||
|
||||
++totalcount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AuctionHouseObject::BuildListAuctionItems(WorldPacket& data, Player* player,
|
||||
std::wstring const& wsearchedname, uint32 listfrom, uint8 levelmin, uint8 levelmax, uint8 usable,
|
||||
uint32 inventoryType, uint32 itemClass, uint32 itemSubClass, uint32 quality,
|
||||
uint32& count, uint32& totalcount)
|
||||
{
|
||||
int loc_idx = player->GetSession()->GetSessionDbLocaleIndex();
|
||||
int locdbc_idx = player->GetSession()->GetSessionDbcLocale();
|
||||
|
||||
for (AuctionEntryMap::const_iterator itr = AuctionsMap.begin(); itr != AuctionsMap.end(); ++itr)
|
||||
{
|
||||
AuctionEntry *Aentry = itr->second;
|
||||
Item *item = auctionmgr.GetAItem(Aentry->item_guidlow);
|
||||
if (!item)
|
||||
continue;
|
||||
|
||||
ItemPrototype const *proto = item->GetProto();
|
||||
|
||||
if (itemClass != 0xffffffff && proto->Class != itemClass)
|
||||
continue;
|
||||
|
||||
if (itemSubClass != 0xffffffff && proto->SubClass != itemSubClass)
|
||||
continue;
|
||||
|
||||
if (inventoryType != 0xffffffff && proto->InventoryType != inventoryType)
|
||||
continue;
|
||||
|
||||
if (quality != 0xffffffff && proto->Quality != quality)
|
||||
continue;
|
||||
|
||||
if (levelmin != 0x00 && (proto->RequiredLevel < levelmin || (levelmax != 0x00 && proto->RequiredLevel > levelmax)))
|
||||
continue;
|
||||
|
||||
if (usable != 0x00 && player->CanUseItem(item) != EQUIP_ERR_OK)
|
||||
continue;
|
||||
|
||||
// Allow search by suffix (ie: of the Monkey) or partial name (ie: Monkey)
|
||||
// No need to do any of this if no search term was entered
|
||||
if (!wsearchedname.empty())
|
||||
{
|
||||
std::string name = proto->Name1;
|
||||
if (name.empty())
|
||||
continue;
|
||||
|
||||
// local name
|
||||
if (loc_idx >= 0)
|
||||
{
|
||||
ItemLocale const *il = objmgr.GetItemLocale(proto->ItemId);
|
||||
if (il)
|
||||
{
|
||||
if (il->Name.size() > size_t(loc_idx) && !il->Name[loc_idx].empty())
|
||||
name = il->Name[loc_idx];
|
||||
}
|
||||
}
|
||||
|
||||
// DO NOT use GetItemEnchantMod(proto->RandomProperty) as it may return a result
|
||||
// that matches the search but it may not equal item->GetItemRandomPropertyId()
|
||||
// used in BuildAuctionInfo() which then causes wrong items to be listed
|
||||
int32 propRefID = item->GetItemRandomPropertyId();
|
||||
|
||||
if (propRefID)
|
||||
{
|
||||
// Append the suffix to the name (ie: of the Monkey) if one exists
|
||||
// These are found in ItemRandomProperties.dbc, not ItemRandomSuffix.dbc
|
||||
// even though the DBC names seem misleading
|
||||
const ItemRandomPropertiesEntry *itemRandProp = sItemRandomPropertiesStore.LookupEntry(propRefID);
|
||||
|
||||
if (itemRandProp)
|
||||
{
|
||||
char* const* temp = itemRandProp->nameSuffix;
|
||||
//char* temp = itemRandProp->nameSuffix;
|
||||
|
||||
// dbc local name
|
||||
if (temp)
|
||||
{
|
||||
if (locdbc_idx >= 0)
|
||||
{
|
||||
// Append the suffix (ie: of the Monkey) to the name using localization
|
||||
name += " ";
|
||||
name += temp[locdbc_idx];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Invalid localization? Append the suffix using default enUS
|
||||
name += " ";
|
||||
name += temp[LOCALE_enUS];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Perform the search (with or without suffix)
|
||||
if (!Utf8FitTo(name, wsearchedname))
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add the item if no search term or if entered search term was found
|
||||
if (count < 50 && totalcount >= listfrom)
|
||||
{
|
||||
++count;
|
||||
Aentry->BuildAuctionInfo(data);
|
||||
}
|
||||
++totalcount;
|
||||
}
|
||||
}
|
||||
|
||||
//this function inserts to WorldPacket auction's data
|
||||
bool AuctionEntry::BuildAuctionInfo(WorldPacket & data) const
|
||||
{
|
||||
Item *pItem = auctionmgr.GetAItem(item_guidlow);
|
||||
if (!pItem)
|
||||
{
|
||||
sLog.outError("auction to item, that doesn't exist !!!!");
|
||||
return false;
|
||||
}
|
||||
data << uint32(Id);
|
||||
data << uint32(pItem->GetEntry());
|
||||
|
||||
for (uint8 i = 0; i < MAX_INSPECTED_ENCHANTMENT_SLOT; ++i)
|
||||
{
|
||||
data << uint32(pItem->GetEnchantmentId(EnchantmentSlot(i)));
|
||||
data << uint32(pItem->GetEnchantmentDuration(EnchantmentSlot(i)));
|
||||
data << uint32(pItem->GetEnchantmentCharges(EnchantmentSlot(i)));
|
||||
}
|
||||
|
||||
data << int32(pItem->GetItemRandomPropertyId()); //random item property id
|
||||
data << uint32(pItem->GetItemSuffixFactor()); //SuffixFactor
|
||||
data << uint32(pItem->GetCount()); //item->count
|
||||
data << uint32(pItem->GetSpellCharges()); //item->charge FFFFFFF
|
||||
data << uint32(0); //Unknown
|
||||
data << uint64(owner); //Auction->owner
|
||||
data << uint32(startbid); //Auction->startbid (not sure if useful)
|
||||
data << uint32(bid ? GetAuctionOutBid() : 0);
|
||||
//minimal outbid
|
||||
data << uint32(buyout); //auction->buyout
|
||||
data << uint32((expire_time-time(NULL))*IN_MILISECONDS);//time left
|
||||
data << uint64(bidder) ; //auction->bidder current
|
||||
data << uint32(bid); //current bid
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32 AuctionEntry::GetAuctionCut() const
|
||||
{
|
||||
int32 cut = int32(((double)auctionHouseEntry->cutPercent / 100.0f) * (double)sWorld.getRate(RATE_AUCTION_CUT)) * bid;
|
||||
if (cut > 0)
|
||||
return cut;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// the sum of outbid is (1% from current bid)*5, if bid is very small, it is 1c
|
||||
uint32 AuctionEntry::GetAuctionOutBid() const
|
||||
{
|
||||
uint32 outbid = (uint32)((double)bid / 100.0f) * 5;
|
||||
if (!outbid)
|
||||
outbid = 1;
|
||||
return outbid;
|
||||
}
|
||||
|
||||
void AuctionEntry::DeleteFromDB() const
|
||||
{
|
||||
//No SQL injection (Id is integer)
|
||||
CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",Id);
|
||||
}
|
||||
|
||||
void AuctionEntry::SaveToDB() const
|
||||
{
|
||||
//No SQL injection (no strings)
|
||||
CharacterDatabase.PExecute("INSERT INTO auctionhouse (id,auctioneerguid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit) "
|
||||
"VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '" UI64FMTD "', '%u', '%u', '%u', '%u')",
|
||||
Id, auctioneer, item_guidlow, item_template, owner, buyout, (uint64)expire_time, bidder, bid, startbid, deposit);
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _AUCTION_HOUSE_MGR_H
|
||||
#define _AUCTION_HOUSE_MGR_H
|
||||
|
||||
#include "Policies/Singleton.h"
|
||||
|
||||
#include "SharedDefines.h"
|
||||
|
||||
#include "AuctionHouseBot.h"
|
||||
|
||||
class Item;
|
||||
class Player;
|
||||
class WorldPacket;
|
||||
|
||||
#define MIN_AUCTION_TIME (12*HOUR)
|
||||
|
||||
enum AuctionError
|
||||
{
|
||||
AUCTION_OK = 0,
|
||||
AUCTION_INTERNAL_ERROR = 2,
|
||||
AUCTION_NOT_ENOUGHT_MONEY = 3,
|
||||
AUCTION_ITEM_NOT_FOUND = 4,
|
||||
CANNOT_BID_YOUR_AUCTION_ERROR = 10
|
||||
};
|
||||
|
||||
enum AuctionAction
|
||||
{
|
||||
AUCTION_SELL_ITEM = 0,
|
||||
AUCTION_CANCEL = 1,
|
||||
AUCTION_PLACE_BID = 2
|
||||
};
|
||||
|
||||
struct AuctionEntry
|
||||
{
|
||||
uint32 Id;
|
||||
uint32 auctioneer; // creature low guid
|
||||
uint32 item_guidlow;
|
||||
uint32 item_template;
|
||||
uint32 owner;
|
||||
uint32 startbid; //maybe useless
|
||||
uint32 bid;
|
||||
uint32 buyout;
|
||||
time_t expire_time;
|
||||
uint32 bidder;
|
||||
uint32 deposit; //deposit can be calculated only when creating auction
|
||||
AuctionHouseEntry const* auctionHouseEntry; // in AuctionHouse.dbc
|
||||
|
||||
// helpers
|
||||
uint32 GetHouseId() const { return auctionHouseEntry->houseId; }
|
||||
uint32 GetHouseFaction() const { return auctionHouseEntry->faction; }
|
||||
uint32 GetAuctionCut() const;
|
||||
uint32 GetAuctionOutBid() const;
|
||||
bool BuildAuctionInfo(WorldPacket & data) const;
|
||||
void DeleteFromDB() const;
|
||||
void SaveToDB() const;
|
||||
};
|
||||
|
||||
//this class is used as auctionhouse instance
|
||||
class AuctionHouseObject
|
||||
{
|
||||
public:
|
||||
// Initialize storage
|
||||
AuctionHouseObject() { next = AuctionsMap.begin(); }
|
||||
~AuctionHouseObject()
|
||||
{
|
||||
for (AuctionEntryMap::iterator itr = AuctionsMap.begin(); itr != AuctionsMap.end(); ++itr)
|
||||
delete itr->second;
|
||||
}
|
||||
|
||||
typedef std::map<uint32, AuctionEntry*> AuctionEntryMap;
|
||||
|
||||
uint32 Getcount() { return AuctionsMap.size(); }
|
||||
|
||||
AuctionEntryMap::iterator GetAuctionsBegin() {return AuctionsMap.begin();}
|
||||
AuctionEntryMap::iterator GetAuctionsEnd() {return AuctionsMap.end();}
|
||||
|
||||
AuctionEntry* GetAuction(uint32 id) const
|
||||
{
|
||||
AuctionEntryMap::const_iterator itr = AuctionsMap.find(id);
|
||||
return itr != AuctionsMap.end() ? itr->second : NULL;
|
||||
}
|
||||
|
||||
void AddAuction(AuctionEntry *ah);
|
||||
|
||||
bool RemoveAuction(AuctionEntry *auction, uint32 item_template);
|
||||
|
||||
void Update();
|
||||
|
||||
void BuildListBidderItems(WorldPacket& data, Player* player, uint32& count, uint32& totalcount);
|
||||
void BuildListOwnerItems(WorldPacket& data, Player* player, uint32& count, uint32& totalcount);
|
||||
void BuildListAuctionItems(WorldPacket& data, Player* player,
|
||||
std::wstring const& searchedname, uint32 listfrom, uint8 levelmin, uint8 levelmax, uint8 usable,
|
||||
uint32 inventoryType, uint32 itemClass, uint32 itemSubClass, uint32 quality,
|
||||
uint32& count, uint32& totalcount);
|
||||
|
||||
private:
|
||||
AuctionEntryMap AuctionsMap;
|
||||
|
||||
// storage for "next" auction item for next Update()
|
||||
AuctionEntryMap::const_iterator next;
|
||||
};
|
||||
|
||||
class AuctionHouseMgr
|
||||
{
|
||||
public:
|
||||
AuctionHouseMgr();
|
||||
~AuctionHouseMgr();
|
||||
|
||||
typedef UNORDERED_MAP<uint32, Item*> ItemMap;
|
||||
|
||||
AuctionHouseObject* GetAuctionsMap(uint32 factionTemplateId);
|
||||
AuctionHouseObject* GetBidsMap(uint32 factionTemplateId);
|
||||
|
||||
Item* GetAItem(uint32 id)
|
||||
{
|
||||
ItemMap::const_iterator itr = mAitems.find(id);
|
||||
if (itr != mAitems.end())
|
||||
{
|
||||
return itr->second;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//auction messages
|
||||
void SendAuctionWonMail(AuctionEntry * auction);
|
||||
void SendAuctionSalePendingMail(AuctionEntry * auction);
|
||||
void SendAuctionSuccessfulMail(AuctionEntry * auction);
|
||||
void SendAuctionExpiredMail(AuctionEntry * auction);
|
||||
static uint32 GetAuctionDeposit(AuctionHouseEntry const* entry, uint32 time, Item *pItem);
|
||||
static AuctionHouseEntry const* GetAuctionHouseEntry(uint32 factionTemplateId);
|
||||
|
||||
public:
|
||||
//load first auction items, because of check if item exists, when loading
|
||||
void LoadAuctionItems();
|
||||
void LoadAuctions();
|
||||
|
||||
void AddAItem(Item* it);
|
||||
bool RemoveAItem(uint32 id);
|
||||
|
||||
void Update();
|
||||
|
||||
private:
|
||||
AuctionHouseObject mHordeAuctions;
|
||||
AuctionHouseObject mAllianceAuctions;
|
||||
AuctionHouseObject mNeutralAuctions;
|
||||
|
||||
ItemMap mAitems;
|
||||
};
|
||||
|
||||
#define auctionmgr Trinity::Singleton<AuctionHouseMgr>::Instance()
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Common.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
|
||||
#include "Bag.h"
|
||||
#include "Log.h"
|
||||
#include "UpdateData.h"
|
||||
|
||||
Bag::Bag(): Item()
|
||||
{
|
||||
m_objectType |= TYPEMASK_CONTAINER;
|
||||
m_objectTypeId = TYPEID_CONTAINER;
|
||||
|
||||
m_valuesCount = CONTAINER_END;
|
||||
|
||||
memset(m_bagslot, 0, sizeof(Item *) * MAX_BAG_SIZE);
|
||||
}
|
||||
|
||||
Bag::~Bag()
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_BAG_SIZE; ++i)
|
||||
if (Item *item = m_bagslot[i])
|
||||
{
|
||||
if (item->IsInWorld())
|
||||
{
|
||||
sLog.outCrash("Item %u (slot %u, bag slot %u) in bag %u (slot %u, bag slot %u, m_bagslot %u) is to be deleted but is still in world.",
|
||||
item->GetEntry(), (uint32)item->GetSlot(), (uint32)item->GetBagSlot(),
|
||||
GetEntry(), (uint32)GetSlot(), (uint32)GetBagSlot(), (uint32)i);
|
||||
item->RemoveFromWorld();
|
||||
}
|
||||
delete m_bagslot[i];
|
||||
}
|
||||
}
|
||||
|
||||
void Bag::AddToWorld()
|
||||
{
|
||||
Item::AddToWorld();
|
||||
|
||||
for (uint32 i = 0; i < GetBagSize(); ++i)
|
||||
if (m_bagslot[i])
|
||||
m_bagslot[i]->AddToWorld();
|
||||
}
|
||||
|
||||
void Bag::RemoveFromWorld()
|
||||
{
|
||||
for (uint32 i = 0; i < GetBagSize(); ++i)
|
||||
if (m_bagslot[i])
|
||||
m_bagslot[i]->RemoveFromWorld();
|
||||
|
||||
Item::RemoveFromWorld();
|
||||
}
|
||||
|
||||
bool Bag::Create(uint32 guidlow, uint32 itemid, Player const* owner)
|
||||
{
|
||||
ItemPrototype const * itemProto = objmgr.GetItemPrototype(itemid);
|
||||
|
||||
if (!itemProto || itemProto->ContainerSlots > MAX_BAG_SIZE)
|
||||
return false;
|
||||
|
||||
Object::_Create(guidlow, 0, HIGHGUID_CONTAINER);
|
||||
|
||||
SetEntry(itemid);
|
||||
SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f);
|
||||
|
||||
SetUInt64Value(ITEM_FIELD_OWNER, owner ? owner->GetGUID() : 0);
|
||||
SetUInt64Value(ITEM_FIELD_CONTAINED, owner ? owner->GetGUID() : 0);
|
||||
|
||||
SetUInt32Value(ITEM_FIELD_MAXDURABILITY, itemProto->MaxDurability);
|
||||
SetUInt32Value(ITEM_FIELD_DURABILITY, itemProto->MaxDurability);
|
||||
SetUInt32Value(ITEM_FIELD_FLAGS, itemProto->Flags);
|
||||
SetUInt32Value(ITEM_FIELD_STACK_COUNT, 1);
|
||||
|
||||
// Setting the number of Slots the Container has
|
||||
SetUInt32Value(CONTAINER_FIELD_NUM_SLOTS, itemProto->ContainerSlots);
|
||||
|
||||
// Cleaning 20 slots
|
||||
for (uint8 i = 0; i < MAX_BAG_SIZE; ++i)
|
||||
{
|
||||
SetUInt64Value(CONTAINER_FIELD_SLOT_1 + (i*2), 0);
|
||||
m_bagslot[i] = NULL;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Bag::SaveToDB()
|
||||
{
|
||||
Item::SaveToDB();
|
||||
}
|
||||
|
||||
bool Bag::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult_AutoPtr result)
|
||||
{
|
||||
if (!Item::LoadFromDB(guid, owner_guid, result))
|
||||
return false;
|
||||
|
||||
// cleanup bag content related item value fields (its will be filled correctly from `character_inventory`)
|
||||
for (uint8 i = 0; i < MAX_BAG_SIZE; ++i)
|
||||
{
|
||||
SetUInt64Value(CONTAINER_FIELD_SLOT_1 + (i*2), 0);
|
||||
if (m_bagslot[i])
|
||||
{
|
||||
delete m_bagslot[i];
|
||||
m_bagslot[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Bag::DeleteFromDB()
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_BAG_SIZE; ++i)
|
||||
if (m_bagslot[i])
|
||||
m_bagslot[i]->DeleteFromDB();
|
||||
|
||||
Item::DeleteFromDB();
|
||||
}
|
||||
|
||||
uint32 Bag::GetFreeSlots() const
|
||||
{
|
||||
uint32 slots = 0;
|
||||
for (uint32 i=0; i < GetBagSize(); ++i)
|
||||
if (!m_bagslot[i])
|
||||
++slots;
|
||||
|
||||
return slots;
|
||||
}
|
||||
|
||||
void Bag::RemoveItem(uint8 slot, bool /*update*/)
|
||||
{
|
||||
assert(slot < MAX_BAG_SIZE);
|
||||
|
||||
if (m_bagslot[slot])
|
||||
m_bagslot[slot]->SetContainer(NULL);
|
||||
|
||||
m_bagslot[slot] = NULL;
|
||||
SetUInt64Value(CONTAINER_FIELD_SLOT_1 + (slot * 2), 0);
|
||||
}
|
||||
|
||||
void Bag::StoreItem(uint8 slot, Item *pItem, bool /*update*/)
|
||||
{
|
||||
assert(slot < MAX_BAG_SIZE);
|
||||
|
||||
if (pItem && pItem->GetGUID() != this->GetGUID())
|
||||
{
|
||||
m_bagslot[slot] = pItem;
|
||||
SetUInt64Value(CONTAINER_FIELD_SLOT_1 + (slot * 2), pItem->GetGUID());
|
||||
pItem->SetUInt64Value(ITEM_FIELD_CONTAINED, GetGUID());
|
||||
pItem->SetUInt64Value(ITEM_FIELD_OWNER, GetOwnerGUID());
|
||||
pItem->SetContainer(this);
|
||||
pItem->SetSlot(slot);
|
||||
}
|
||||
}
|
||||
|
||||
void Bag::BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) const
|
||||
{
|
||||
Item::BuildCreateUpdateBlockForPlayer(data, target);
|
||||
|
||||
for (uint32 i = 0; i < GetBagSize(); ++i)
|
||||
if (m_bagslot[i])
|
||||
m_bagslot[i]->BuildCreateUpdateBlockForPlayer(data, target);
|
||||
}
|
||||
|
||||
// If the bag is empty returns true
|
||||
bool Bag::IsEmpty() const
|
||||
{
|
||||
for (uint32 i = 0; i < GetBagSize(); ++i)
|
||||
if (m_bagslot[i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32 Bag::GetItemCount(uint32 item, Item* eItem) const
|
||||
{
|
||||
Item *pItem;
|
||||
uint32 count = 0;
|
||||
for (uint32 i=0; i < GetBagSize(); ++i)
|
||||
{
|
||||
pItem = m_bagslot[i];
|
||||
if (pItem && pItem != eItem && pItem->GetEntry() == item)
|
||||
count += pItem->GetCount();
|
||||
}
|
||||
|
||||
if (eItem && eItem->GetProto()->GemProperties)
|
||||
{
|
||||
for (uint32 i=0; i < GetBagSize(); ++i)
|
||||
{
|
||||
pItem = m_bagslot[i];
|
||||
if (pItem && pItem != eItem && pItem->GetProto()->Socket[0].Color)
|
||||
count += pItem->GetGemCountWithID(item);
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
uint8 Bag::GetSlotByItemGUID(uint64 guid) const
|
||||
{
|
||||
for (uint32 i = 0; i < GetBagSize(); ++i)
|
||||
if (m_bagslot[i] != 0)
|
||||
if (m_bagslot[i]->GetGUID() == guid)
|
||||
return i;
|
||||
|
||||
return NULL_SLOT;
|
||||
}
|
||||
|
||||
Item* Bag::GetItemByPos(uint8 slot) const
|
||||
{
|
||||
if (slot < GetBagSize())
|
||||
return m_bagslot[slot];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_BAG_H
|
||||
#define TRINITY_BAG_H
|
||||
|
||||
// Maximum 36 Slots ((CONTAINER_END - CONTAINER_FIELD_SLOT_1)/2
|
||||
#define MAX_BAG_SIZE 36 // 2.0.12
|
||||
|
||||
#include "Item.h"
|
||||
#include "ItemPrototype.h"
|
||||
|
||||
class Bag : public Item
|
||||
{
|
||||
public:
|
||||
|
||||
Bag();
|
||||
~Bag();
|
||||
|
||||
void AddToWorld();
|
||||
void RemoveFromWorld();
|
||||
|
||||
bool Create(uint32 guidlow, uint32 itemid, Player const* owner);
|
||||
|
||||
void Clear();
|
||||
void StoreItem(uint8 slot, Item *pItem, bool update);
|
||||
void RemoveItem(uint8 slot, bool update);
|
||||
|
||||
Item* GetItemByPos(uint8 slot) const;
|
||||
uint32 GetItemCount(uint32 item, Item* eItem = NULL) const;
|
||||
|
||||
uint8 GetSlotByItemGUID(uint64 guid) const;
|
||||
bool IsEmpty() const;
|
||||
uint32 GetFreeSlots() const;
|
||||
uint32 GetBagSize() const { return GetUInt32Value(CONTAINER_FIELD_NUM_SLOTS); }
|
||||
|
||||
// DB operations
|
||||
// overwrite virtual Item::SaveToDB
|
||||
void SaveToDB();
|
||||
// overwrite virtual Item::LoadFromDB
|
||||
bool LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult_AutoPtr result);
|
||||
// overwrite virtual Item::DeleteFromDB
|
||||
void DeleteFromDB();
|
||||
|
||||
void BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) const;
|
||||
|
||||
protected:
|
||||
|
||||
// Bag Storage space
|
||||
Item* m_bagslot[MAX_BAG_SIZE];
|
||||
};
|
||||
|
||||
inline Item* NewItemOrBag(ItemPrototype const * proto)
|
||||
{
|
||||
return (proto->InventoryType == INVTYPE_BAG) ? new Bag : new Item;
|
||||
}
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,664 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __BATTLEGROUND_H
|
||||
#define __BATTLEGROUND_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "DBCEnums.h"
|
||||
|
||||
class Creature;
|
||||
class GameObject;
|
||||
class Group;
|
||||
class Player;
|
||||
class WorldPacket;
|
||||
class BattleGroundMap;
|
||||
|
||||
struct PvPDifficultyEntry;
|
||||
struct WorldSafeLocsEntry;
|
||||
|
||||
enum BattleGroundSounds
|
||||
{
|
||||
SOUND_HORDE_WINS = 8454,
|
||||
SOUND_ALLIANCE_WINS = 8455,
|
||||
SOUND_BG_START = 3439,
|
||||
SOUND_BG_START_L70ETC = 11803,
|
||||
};
|
||||
|
||||
enum BattleGroundQuests
|
||||
{
|
||||
SPELL_WS_QUEST_REWARD = 43483,
|
||||
SPELL_AB_QUEST_REWARD = 43484,
|
||||
SPELL_AV_QUEST_REWARD = 43475,
|
||||
SPELL_AV_QUEST_KILLED_BOSS = 23658,
|
||||
SPELL_EY_QUEST_REWARD = 43477,
|
||||
SPELL_SA_QUEST_REWARD = 61213,
|
||||
SPELL_AB_QUEST_REWARD_4_BASES = 24061,
|
||||
SPELL_AB_QUEST_REWARD_5_BASES = 24064
|
||||
};
|
||||
|
||||
enum BattleGroundMarks
|
||||
{
|
||||
SPELL_WS_MARK_LOSER = 24950,
|
||||
SPELL_WS_MARK_WINNER = 24951,
|
||||
SPELL_AB_MARK_LOSER = 24952,
|
||||
SPELL_AB_MARK_WINNER = 24953,
|
||||
SPELL_AV_MARK_LOSER = 24954,
|
||||
SPELL_AV_MARK_WINNER = 24955,
|
||||
SPELL_SA_MARK_WINNER = 61160,
|
||||
SPELL_SA_MARK_LOSER = 61159,
|
||||
ITEM_AV_MARK_OF_HONOR = 20560,
|
||||
ITEM_WS_MARK_OF_HONOR = 20558,
|
||||
ITEM_AB_MARK_OF_HONOR = 20559,
|
||||
ITEM_EY_MARK_OF_HONOR = 29024,
|
||||
ITEM_SA_MARK_OF_HONOR = 42425
|
||||
};
|
||||
|
||||
enum BattleGroundMarksCount
|
||||
{
|
||||
ITEM_WINNER_COUNT = 3,
|
||||
ITEM_LOSER_COUNT = 1
|
||||
};
|
||||
|
||||
enum BattleGroundCreatures
|
||||
{
|
||||
BG_CREATURE_ENTRY_A_SPIRITGUIDE = 13116, // alliance
|
||||
BG_CREATURE_ENTRY_H_SPIRITGUIDE = 13117, // horde
|
||||
};
|
||||
|
||||
enum BattleGroundSpells
|
||||
{
|
||||
SPELL_WAITING_FOR_RESURRECT = 2584, // Waiting to Resurrect
|
||||
SPELL_SPIRIT_HEAL_CHANNEL = 22011, // Spirit Heal Channel
|
||||
SPELL_SPIRIT_HEAL = 22012, // Spirit Heal
|
||||
SPELL_RESURRECTION_VISUAL = 24171, // Resurrection Impact Visual
|
||||
SPELL_ARENA_PREPARATION = 32727, // use this one, 32728 not correct
|
||||
SPELL_ALLIANCE_GOLD_FLAG = 32724,
|
||||
SPELL_ALLIANCE_GREEN_FLAG = 32725,
|
||||
SPELL_HORDE_GOLD_FLAG = 35774,
|
||||
SPELL_HORDE_GREEN_FLAG = 35775,
|
||||
SPELL_PREPARATION = 44521, // Preparation
|
||||
SPELL_SPIRIT_HEAL_MANA = 44535, // Spirit Heal
|
||||
SPELL_RECENTLY_DROPPED_FLAG = 42792, // Recently Dropped Flag
|
||||
SPELL_AURA_PLAYER_INACTIVE = 43681, // Inactive
|
||||
SPELL_HONORABLE_DEFENDER_25Y = 68652, // +50% honor when standing at a capture point that you control, 25yards radius (added in 3.2)
|
||||
SPELL_HONORABLE_DEFENDER_60Y = 66157 // +50% honor when standing at a capture point that you control, 60yards radius (added in 3.2), probably for 40+ player battlegrounds
|
||||
};
|
||||
|
||||
enum BattleGroundTimeIntervals
|
||||
{
|
||||
RESURRECTION_INTERVAL = 30000, // ms
|
||||
//REMIND_INTERVAL = 10000, // ms
|
||||
INVITATION_REMIND_TIME = 20000, // ms
|
||||
INVITE_ACCEPT_WAIT_TIME = 40000, // ms
|
||||
TIME_TO_AUTOREMOVE = 120000, // ms
|
||||
MAX_OFFLINE_TIME = 300, // secs
|
||||
RESPAWN_ONE_DAY = 86400, // secs
|
||||
RESPAWN_IMMEDIATELY = 0, // secs
|
||||
BUFF_RESPAWN_TIME = 180, // secs
|
||||
};
|
||||
|
||||
enum BattleGroundStartTimeIntervals
|
||||
{
|
||||
BG_START_DELAY_2M = 120000, // ms (2 minutes)
|
||||
BG_START_DELAY_1M = 60000, // ms (1 minute)
|
||||
BG_START_DELAY_30S = 30000, // ms (30 seconds)
|
||||
BG_START_DELAY_15S = 15000, // ms (15 seconds) Used only in arena
|
||||
BG_START_DELAY_NONE = 0, // ms
|
||||
};
|
||||
|
||||
enum BattleGroundBuffObjects
|
||||
{
|
||||
BG_OBJECTID_SPEEDBUFF_ENTRY = 179871,
|
||||
BG_OBJECTID_REGENBUFF_ENTRY = 179904,
|
||||
BG_OBJECTID_BERSERKERBUFF_ENTRY = 179905
|
||||
};
|
||||
|
||||
enum BattleGroundRandomRewards
|
||||
{
|
||||
BG_REWARD_WINNER_HONOR_FIRST = 30,
|
||||
BG_REWARD_WINNER_ARENA_FIRST = 25,
|
||||
BG_REWARD_WINNER_HONOR_LAST = 15,
|
||||
BG_REWARD_WINNER_ARENA_LAST = 0,
|
||||
BG_REWARD_LOOSER_HONOR_FIRST = 5,
|
||||
BG_REWARD_LOOSER_HONOR_LAST = 5
|
||||
};
|
||||
|
||||
const uint32 Buff_Entries[3] = { BG_OBJECTID_SPEEDBUFF_ENTRY, BG_OBJECTID_REGENBUFF_ENTRY, BG_OBJECTID_BERSERKERBUFF_ENTRY };
|
||||
|
||||
enum BattleGroundStatus
|
||||
{
|
||||
STATUS_NONE = 0, // first status, should mean bg is not instance
|
||||
STATUS_WAIT_QUEUE = 1, // means bg is empty and waiting for queue
|
||||
STATUS_WAIT_JOIN = 2, // this means, that BG has already started and it is waiting for more players
|
||||
STATUS_IN_PROGRESS = 3, // means bg is running
|
||||
STATUS_WAIT_LEAVE = 4 // means some faction has won BG and it is ending
|
||||
};
|
||||
|
||||
struct BattleGroundPlayer
|
||||
{
|
||||
time_t OfflineRemoveTime; // for tracking and removing offline players from queue after 5 minutes
|
||||
uint32 Team; // Player's team
|
||||
};
|
||||
|
||||
struct BattleGroundObjectInfo
|
||||
{
|
||||
BattleGroundObjectInfo() : object(NULL), timer(0), spellid(0) {}
|
||||
|
||||
GameObject *object;
|
||||
int32 timer;
|
||||
uint32 spellid;
|
||||
};
|
||||
|
||||
// handle the queue types and bg types separately to enable joining queue for different sized arenas at the same time
|
||||
enum BattleGroundQueueTypeId
|
||||
{
|
||||
BATTLEGROUND_QUEUE_NONE = 0,
|
||||
BATTLEGROUND_QUEUE_AV = 1,
|
||||
BATTLEGROUND_QUEUE_WS = 2,
|
||||
BATTLEGROUND_QUEUE_AB = 3,
|
||||
BATTLEGROUND_QUEUE_EY = 4,
|
||||
BATTLEGROUND_QUEUE_SA = 5,
|
||||
BATTLEGROUND_QUEUE_IC = 6,
|
||||
BATTLEGROUND_QUEUE_RB = 7,
|
||||
BATTLEGROUND_QUEUE_2v2 = 8,
|
||||
BATTLEGROUND_QUEUE_3v3 = 9,
|
||||
BATTLEGROUND_QUEUE_5v5 = 10,
|
||||
MAX_BATTLEGROUND_QUEUE_TYPES
|
||||
};
|
||||
|
||||
enum ScoreType
|
||||
{
|
||||
SCORE_KILLING_BLOWS = 1,
|
||||
SCORE_DEATHS = 2,
|
||||
SCORE_HONORABLE_KILLS = 3,
|
||||
SCORE_BONUS_HONOR = 4,
|
||||
//EY, but in MSG_PVP_LOG_DATA opcode!
|
||||
SCORE_DAMAGE_DONE = 5,
|
||||
SCORE_HEALING_DONE = 6,
|
||||
//WS
|
||||
SCORE_FLAG_CAPTURES = 7,
|
||||
SCORE_FLAG_RETURNS = 8,
|
||||
//AB
|
||||
SCORE_BASES_ASSAULTED = 9,
|
||||
SCORE_BASES_DEFENDED = 10,
|
||||
//AV
|
||||
SCORE_GRAVEYARDS_ASSAULTED = 11,
|
||||
SCORE_GRAVEYARDS_DEFENDED = 12,
|
||||
SCORE_TOWERS_ASSAULTED = 13,
|
||||
SCORE_TOWERS_DEFENDED = 14,
|
||||
SCORE_MINES_CAPTURED = 15,
|
||||
SCORE_LEADERS_KILLED = 16,
|
||||
SCORE_SECONDARY_OBJECTIVES = 17,
|
||||
//SOTA
|
||||
SCORE_DESTROYED_DEMOLISHER = 18,
|
||||
SCORE_DESTROYED_WALL = 19
|
||||
};
|
||||
|
||||
enum ArenaType
|
||||
{
|
||||
ARENA_TYPE_2v2 = 2,
|
||||
ARENA_TYPE_3v3 = 3,
|
||||
ARENA_TYPE_5v5 = 5
|
||||
};
|
||||
|
||||
enum BattleGroundType
|
||||
{
|
||||
TYPE_BATTLEGROUND = 3,
|
||||
TYPE_ARENA = 4
|
||||
};
|
||||
|
||||
enum BattleGroundWinner
|
||||
{
|
||||
WINNER_HORDE = 0,
|
||||
WINNER_ALLIANCE = 1,
|
||||
WINNER_NONE = 2
|
||||
};
|
||||
|
||||
enum BattleGroundTeamId
|
||||
{
|
||||
BG_TEAM_ALLIANCE = 0,
|
||||
BG_TEAM_HORDE = 1
|
||||
};
|
||||
#define BG_TEAMS_COUNT 2
|
||||
|
||||
enum BattleGroundStartingEvents
|
||||
{
|
||||
BG_STARTING_EVENT_NONE = 0x00,
|
||||
BG_STARTING_EVENT_1 = 0x01,
|
||||
BG_STARTING_EVENT_2 = 0x02,
|
||||
BG_STARTING_EVENT_3 = 0x04,
|
||||
BG_STARTING_EVENT_4 = 0x08
|
||||
};
|
||||
|
||||
enum BattleGroundStartingEventsIds
|
||||
{
|
||||
BG_STARTING_EVENT_FIRST = 0,
|
||||
BG_STARTING_EVENT_SECOND = 1,
|
||||
BG_STARTING_EVENT_THIRD = 2,
|
||||
BG_STARTING_EVENT_FOURTH = 3
|
||||
};
|
||||
#define BG_STARTING_EVENT_COUNT 4
|
||||
|
||||
enum BG_OBJECT_DMG_HIT_TYPE
|
||||
{
|
||||
BG_OBJECT_DMG_HIT_TYPE_JUST_DAMAGED = 0,
|
||||
BG_OBJECT_DMG_HIT_TYPE_DAMAGED = 1,
|
||||
BG_OBJECT_DMG_HIT_TYPE_JUST_HIGH_DAMAGED = 2,
|
||||
BG_OBJECT_DMG_HIT_TYPE_HIGH_DAMAGED = 3,
|
||||
BG_OBJECT_DMG_HIT_TYPE_JUST_DESTROYED = 4
|
||||
};
|
||||
|
||||
enum GroupJoinBattlegroundResult
|
||||
{
|
||||
// positive values are indexes in BattlemasterList.dbc
|
||||
ERR_GROUP_JOIN_BATTLEGROUND_FAIL = 0, // Your group has joined a battleground queue, but you are not eligible (showed for non existing BattlemasterList.dbc indexes)
|
||||
ERR_BATTLEGROUND_NONE = -1, // not show anything
|
||||
ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS = -2, // You cannot join the battleground yet because you or one of your party members is flagged as a Deserter.
|
||||
ERR_ARENA_TEAM_PARTY_SIZE = -3, // Incorrect party size for this arena.
|
||||
ERR_BATTLEGROUND_TOO_MANY_QUEUES = -4, // You can only be queued for 2 battles at once
|
||||
ERR_BATTLEGROUND_CANNOT_QUEUE_FOR_RATED = -5, // You cannot queue for a rated match while queued for other battles
|
||||
ERR_BATTLEDGROUND_QUEUED_FOR_RATED = -6, // You cannot queue for another battle while queued for a rated arena match
|
||||
ERR_BATTLEGROUND_TEAM_LEFT_QUEUE = -7, // Your team has left the arena queue
|
||||
ERR_BATTLEGROUND_NOT_IN_BATTLEGROUND = -8, // You can't do that in a battleground.
|
||||
ERR_BATTLEGROUND_JOIN_XP_GAIN = -9, // wtf, doesn't exist in client...
|
||||
ERR_BATTLEGROUND_JOIN_RANGE_INDEX = -10, // Cannot join the queue unless all members of your party are in the same battleground level range.
|
||||
ERR_BATTLEGROUND_JOIN_TIMED_OUT = -11, // %s was unavailable to join the queue. (uint64 guid exist in client cache)
|
||||
ERR_BATTLEGROUND_JOIN_FAILED = -12, // Join as a group failed (uint64 guid doesn't exist in client cache)
|
||||
ERR_LFG_CANT_USE_BATTLEGROUND = -13, // You cannot queue for a battleground or arena while using the dungeon system.
|
||||
ERR_IN_RANDOM_BG = -14, // Can't do that while in a Random Battleground queue.
|
||||
ERR_IN_NON_RANDOM_BG = -15, // Can't queue for Random Battleground while in another Battleground queue.
|
||||
};
|
||||
|
||||
class BattleGroundScore
|
||||
{
|
||||
public:
|
||||
BattleGroundScore() : KillingBlows(0), Deaths(0), HonorableKills(0),
|
||||
BonusHonor(0), DamageDone(0), HealingDone(0)
|
||||
{}
|
||||
virtual ~BattleGroundScore() {} //virtual destructor is used when deleting score from scores map
|
||||
|
||||
uint32 KillingBlows;
|
||||
uint32 Deaths;
|
||||
uint32 HonorableKills;
|
||||
uint32 BonusHonor;
|
||||
uint32 DamageDone;
|
||||
uint32 HealingDone;
|
||||
};
|
||||
|
||||
enum BGHonorMode
|
||||
{
|
||||
BG_NORMAL = 0,
|
||||
BG_HOLIDAY,
|
||||
BG_HONOR_MODE_NUM
|
||||
};
|
||||
|
||||
/*
|
||||
This class is used to:
|
||||
1. Add player to battleground
|
||||
2. Remove player from battleground
|
||||
3. some certain cases, same for all battlegrounds
|
||||
4. It has properties same for all battlegrounds
|
||||
*/
|
||||
class BattleGround
|
||||
{
|
||||
friend class BattleGroundMgr;
|
||||
|
||||
public:
|
||||
/* Construction */
|
||||
BattleGround();
|
||||
/*BattleGround(const BattleGround& bg);*/
|
||||
virtual ~BattleGround();
|
||||
virtual void Update(uint32 diff); // must be implemented in BG subclass of BG specific update code, but must in begginning call parent version
|
||||
virtual bool SetupBattleGround() // must be implemented in BG subclass
|
||||
{
|
||||
return true;
|
||||
}
|
||||
virtual void Reset(); // resets all common properties for battlegrounds, must be implemented and called in BG subclass
|
||||
virtual void StartingEventCloseDoors() {}
|
||||
virtual void StartingEventOpenDoors() {}
|
||||
virtual void ResetBGSubclass() // must be implemented in BG subclass
|
||||
{
|
||||
}
|
||||
|
||||
virtual void DestroyGate(Player* pl, GameObject* go, uint32 destroyedEvent) {}
|
||||
|
||||
/* achievement req. */
|
||||
virtual bool IsAllNodesConrolledByTeam(uint32 /*team*/) const { return false; }
|
||||
bool IsTeamScoreInRange(uint32 team, uint32 minScore, uint32 maxScore) const;
|
||||
|
||||
/* Battleground */
|
||||
// Get methods:
|
||||
char const* GetName() const { return m_Name; }
|
||||
BattleGroundTypeId GetTypeID(bool GetRandom = false) const { return GetRandom ? m_RandomTypeID : m_TypeID; }
|
||||
BattleGroundBracketId GetBracketId() const { return m_BracketId; }
|
||||
uint32 GetInstanceID() const { return m_InstanceID; }
|
||||
BattleGroundStatus GetStatus() const { return m_Status; }
|
||||
uint32 GetClientInstanceID() const { return m_ClientInstanceID; }
|
||||
uint32 GetStartTime() const { return m_StartTime; }
|
||||
uint32 GetEndTime() const { return m_EndTime; }
|
||||
uint32 GetLastResurrectTime() const { return m_LastResurrectTime; }
|
||||
uint32 GetMaxPlayers() const { return m_MaxPlayers; }
|
||||
uint32 GetMinPlayers() const { return m_MinPlayers; }
|
||||
|
||||
uint32 GetMinLevel() const { return m_LevelMin; }
|
||||
uint32 GetMaxLevel() const { return m_LevelMax; }
|
||||
|
||||
uint32 GetMaxPlayersPerTeam() const { return m_MaxPlayersPerTeam; }
|
||||
uint32 GetMinPlayersPerTeam() const { return m_MinPlayersPerTeam; }
|
||||
|
||||
int32 GetStartDelayTime() const { return m_StartDelayTime; }
|
||||
uint8 GetArenaType() const { return m_ArenaType; }
|
||||
uint8 GetWinner() const { return m_Winner; }
|
||||
uint32 GetBattlemasterEntry() const;
|
||||
uint32 GetBonusHonorFromKill(uint32 kills) const;
|
||||
bool IsRandom() { return m_IsRandom; }
|
||||
|
||||
// Set methods:
|
||||
void SetName(char const* Name) { m_Name = Name; }
|
||||
void SetTypeID(BattleGroundTypeId TypeID) { m_TypeID = TypeID; }
|
||||
void SetRandomTypeID(BattleGroundTypeId TypeID) { m_RandomTypeID = TypeID; }
|
||||
//here we can count minlevel and maxlevel for players
|
||||
void SetBracket(PvPDifficultyEntry const* bracketEntry);
|
||||
void SetInstanceID(uint32 InstanceID) { m_InstanceID = InstanceID; }
|
||||
void SetStatus(BattleGroundStatus Status) { m_Status = Status; }
|
||||
void SetClientInstanceID(uint32 InstanceID) { m_ClientInstanceID = InstanceID; }
|
||||
void SetStartTime(uint32 Time) { m_StartTime = Time; }
|
||||
void SetEndTime(uint32 Time) { m_EndTime = Time; }
|
||||
void SetLastResurrectTime(uint32 Time) { m_LastResurrectTime = Time; }
|
||||
void SetMaxPlayers(uint32 MaxPlayers) { m_MaxPlayers = MaxPlayers; }
|
||||
void SetMinPlayers(uint32 MinPlayers) { m_MinPlayers = MinPlayers; }
|
||||
void SetLevelRange(uint32 min, uint32 max) { m_LevelMin = min; m_LevelMax = max; }
|
||||
void SetRated(bool state) { m_IsRated = state; }
|
||||
void SetArenaType(uint8 type) { m_ArenaType = type; }
|
||||
void SetArenaorBGType(bool _isArena) { m_IsArena = _isArena; }
|
||||
void SetWinner(uint8 winner) { m_Winner = winner; }
|
||||
|
||||
void ModifyStartDelayTime(int diff) { m_StartDelayTime -= diff; }
|
||||
void SetStartDelayTime(int Time) { m_StartDelayTime = Time; }
|
||||
|
||||
void SetMaxPlayersPerTeam(uint32 MaxPlayers) { m_MaxPlayersPerTeam = MaxPlayers; }
|
||||
void SetMinPlayersPerTeam(uint32 MinPlayers) { m_MinPlayersPerTeam = MinPlayers; }
|
||||
|
||||
void AddToBGFreeSlotQueue(); //this queue will be useful when more battlegrounds instances will be available
|
||||
void RemoveFromBGFreeSlotQueue(); //this method could delete whole BG instance, if another free is available
|
||||
|
||||
void DecreaseInvitedCount(uint32 team) { (team == ALLIANCE) ? --m_InvitedAlliance : --m_InvitedHorde; }
|
||||
void IncreaseInvitedCount(uint32 team) { (team == ALLIANCE) ? ++m_InvitedAlliance : ++m_InvitedHorde; }
|
||||
|
||||
void SetRandom(bool isRandom) { m_IsRandom = isRandom; }
|
||||
uint32 GetInvitedCount(uint32 team) const
|
||||
{
|
||||
if (team == ALLIANCE)
|
||||
return m_InvitedAlliance;
|
||||
else
|
||||
return m_InvitedHorde;
|
||||
}
|
||||
bool HasFreeSlots() const;
|
||||
uint32 GetFreeSlotsForTeam(uint32 Team) const;
|
||||
|
||||
bool isArena() const { return m_IsArena; }
|
||||
bool isBattleGround() const { return !m_IsArena; }
|
||||
bool isRated() const { return m_IsRated; }
|
||||
|
||||
typedef std::map<uint64, BattleGroundPlayer> BattleGroundPlayerMap;
|
||||
BattleGroundPlayerMap const& GetPlayers() const { return m_Players; }
|
||||
uint32 GetPlayersSize() const { return m_Players.size(); }
|
||||
|
||||
typedef std::map<uint64, BattleGroundScore*> BattleGroundScoreMap;
|
||||
BattleGroundScoreMap::const_iterator GetPlayerScoresBegin() const { return m_PlayerScores.begin(); }
|
||||
BattleGroundScoreMap::const_iterator GetPlayerScoresEnd() const { return m_PlayerScores.end(); }
|
||||
uint32 GetPlayerScoresSize() const { return m_PlayerScores.size(); }
|
||||
|
||||
uint32 GetReviveQueueSize() const { return m_ReviveQueue.size(); }
|
||||
|
||||
void AddPlayerToResurrectQueue(uint64 npc_guid, uint64 player_guid);
|
||||
void RemovePlayerFromResurrectQueue(uint64 player_guid);
|
||||
|
||||
void StartBattleGround();
|
||||
|
||||
GameObject* GetBGObject(uint32 type);
|
||||
Creature* GetBGCreature(uint32 type);
|
||||
/* Location */
|
||||
void SetMapId(uint32 MapID) { m_MapId = MapID; }
|
||||
uint32 GetMapId() const { return m_MapId; }
|
||||
|
||||
/* Map pointers */
|
||||
void SetBgMap(BattleGroundMap* map) { m_Map = map; }
|
||||
BattleGroundMap* GetBgMap()
|
||||
{
|
||||
ASSERT(m_Map);
|
||||
return m_Map;
|
||||
}
|
||||
|
||||
void SetTeamStartLoc(uint32 TeamID, float X, float Y, float Z, float O);
|
||||
void GetTeamStartLoc(uint32 TeamID, float &X, float &Y, float &Z, float &O) const
|
||||
{
|
||||
BattleGroundTeamId idx = GetTeamIndexByTeamId(TeamID);
|
||||
X = m_TeamStartLocX[idx];
|
||||
Y = m_TeamStartLocY[idx];
|
||||
Z = m_TeamStartLocZ[idx];
|
||||
O = m_TeamStartLocO[idx];
|
||||
}
|
||||
|
||||
/* Packet Transfer */
|
||||
// method that should fill worldpacket with actual world states (not yet implemented for all battlegrounds!)
|
||||
virtual void FillInitialWorldStates(WorldPacket& /*data*/) {}
|
||||
void SendPacketToTeam(uint32 TeamID, WorldPacket *packet, Player *sender = NULL, bool self = true);
|
||||
void SendPacketToAll(WorldPacket *packet);
|
||||
void YellToAll(Creature* creature, const char* text, uint32 language);
|
||||
|
||||
template<class Do>
|
||||
void BroadcastWorker(Do& _do);
|
||||
|
||||
void PlaySoundToTeam(uint32 SoundID, uint32 TeamID);
|
||||
void PlaySoundToAll(uint32 SoundID);
|
||||
void CastSpellOnTeam(uint32 SpellID, uint32 TeamID);
|
||||
void RewardHonorToTeam(uint32 Honor, uint32 TeamID);
|
||||
void RewardReputationToTeam(uint32 faction_id, uint32 Reputation, uint32 TeamID);
|
||||
void UpdateWorldState(uint32 Field, uint32 Value);
|
||||
void UpdateWorldStateForPlayer(uint32 Field, uint32 Value, Player *Source);
|
||||
void EndBattleGround(uint32 winner);
|
||||
void BlockMovement(Player *plr);
|
||||
|
||||
void SendWarningToAll(int32 entry, ...);
|
||||
void SendMessageToAll(int32 entry, ChatMsg type, Player const* source = NULL);
|
||||
void PSendMessageToAll(int32 entry, ChatMsg type, Player const* source, ...);
|
||||
|
||||
// specialized version with 2 string id args
|
||||
void SendMessage2ToAll(int32 entry, ChatMsg type, Player const* source, int32 strId1 = 0, int32 strId2 = 0);
|
||||
|
||||
/* Raid Group */
|
||||
Group *GetBgRaid(uint32 TeamID) const { return TeamID == ALLIANCE ? m_BgRaids[BG_TEAM_ALLIANCE] : m_BgRaids[BG_TEAM_HORDE]; }
|
||||
void SetBgRaid(uint32 TeamID, Group *bg_raid);
|
||||
|
||||
virtual void UpdatePlayerScore(Player *Source, uint32 type, uint32 value, bool doAddHonor = true);
|
||||
|
||||
static BattleGroundTeamId GetTeamIndexByTeamId(uint32 Team) { return Team == ALLIANCE ? BG_TEAM_ALLIANCE : BG_TEAM_HORDE; }
|
||||
uint32 GetPlayersCountByTeam(uint32 Team) const { return m_PlayersCount[GetTeamIndexByTeamId(Team)]; }
|
||||
uint32 GetAlivePlayersCountByTeam(uint32 Team) const; // used in arenas to correctly handle death in spirit of redemption / last stand etc. (killer = killed) cases
|
||||
void UpdatePlayersCountByTeam(uint32 Team, bool remove)
|
||||
{
|
||||
if (remove)
|
||||
--m_PlayersCount[GetTeamIndexByTeamId(Team)];
|
||||
else
|
||||
++m_PlayersCount[GetTeamIndexByTeamId(Team)];
|
||||
}
|
||||
|
||||
// used for rated arena battles
|
||||
void SetArenaTeamIdForTeam(uint32 Team, uint32 ArenaTeamId) { m_ArenaTeamIds[GetTeamIndexByTeamId(Team)] = ArenaTeamId; }
|
||||
uint32 GetArenaTeamIdForTeam(uint32 Team) const { return m_ArenaTeamIds[GetTeamIndexByTeamId(Team)]; }
|
||||
void SetArenaTeamRatingChangeForTeam(uint32 Team, int32 RatingChange) { m_ArenaTeamRatingChanges[GetTeamIndexByTeamId(Team)] = RatingChange; }
|
||||
int32 GetArenaTeamRatingChangeForTeam(uint32 Team) const { return m_ArenaTeamRatingChanges[GetTeamIndexByTeamId(Team)]; }
|
||||
void CheckArenaWinConditions();
|
||||
void UpdateArenaWorldState();
|
||||
|
||||
/* Triggers handle */
|
||||
// must be implemented in BG subclass
|
||||
virtual void HandleAreaTrigger(Player* /*Source*/, uint32 /*Trigger*/) {}
|
||||
// must be implemented in BG subclass if need AND call base class generic code
|
||||
virtual void HandleKillPlayer(Player *player, Player *killer);
|
||||
virtual void HandleKillUnit(Creature* /*unit*/, Player* /*killer*/);
|
||||
|
||||
/* Battleground events */
|
||||
virtual void EventPlayerDroppedFlag(Player* /*player*/) {}
|
||||
virtual void EventPlayerClickedOnFlag(Player* /*player*/, GameObject* /*target_obj*/) {}
|
||||
virtual void EventPlayerCapturedFlag(Player* /*player*/) {}
|
||||
void EventPlayerLoggedIn(Player* player, uint64 plr_guid);
|
||||
void EventPlayerLoggedOut(Player* player);
|
||||
virtual void EventPlayerDamagedGO(Player* plr, GameObject* go, uint8 hitType, uint32 destroyedEvent) {}
|
||||
virtual void EventPlayerUsedGO(Player* /*player*/, GameObject* /*go*/){}
|
||||
|
||||
/* Death related */
|
||||
virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player);
|
||||
|
||||
virtual void AddPlayer(Player *plr); // must be implemented in BG subclass
|
||||
|
||||
void AddOrSetPlayerToCorrectBgGroup(Player *plr, uint64 plr_guid, uint32 team);
|
||||
|
||||
virtual void RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPacket);
|
||||
// can be extended in in BG subclass
|
||||
|
||||
void HandleTriggerBuff(uint64 const& go_guid);
|
||||
void SetHoliday(bool is_holiday);
|
||||
|
||||
// TODO: make this protected:
|
||||
typedef std::vector<uint64> BGObjects;
|
||||
typedef std::vector<uint64> BGCreatures;
|
||||
BGObjects m_BgObjects;
|
||||
BGCreatures m_BgCreatures;
|
||||
void SpawnBGObject(uint32 type, uint32 respawntime);
|
||||
bool AddObject(uint32 type, uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime = 0);
|
||||
// void SpawnBGCreature(uint32 type, uint32 respawntime);
|
||||
Creature* AddCreature(uint32 entry, uint32 type, uint32 teamval, float x, float y, float z, float o, uint32 respawntime = 0);
|
||||
bool DelCreature(uint32 type);
|
||||
bool DelObject(uint32 type);
|
||||
bool AddSpiritGuide(uint32 type, float x, float y, float z, float o, uint32 team);
|
||||
int32 GetObjectType(uint64 guid);
|
||||
|
||||
void DoorOpen(uint32 type);
|
||||
void DoorClose(uint32 type);
|
||||
//to be removed
|
||||
const char *GetTrinityString(int32 entry);
|
||||
|
||||
virtual bool HandlePlayerUnderMap(Player * /*plr*/) { return false; }
|
||||
|
||||
// since arenas can be AvA or Hvh, we have to get the "temporary" team of a player
|
||||
uint32 GetPlayerTeam(uint64 guid);
|
||||
uint32 GetOtherTeam(uint32 teamId);
|
||||
bool IsPlayerInBattleGround(uint64 guid);
|
||||
|
||||
void SetDeleteThis() {m_SetDeleteThis = true;}
|
||||
|
||||
/* virtual score-array - get's used in bg-subclasses */
|
||||
int32 m_TeamScores[BG_TEAMS_COUNT];
|
||||
|
||||
void RewardXPAtKill(Player* plr, Player* victim);
|
||||
|
||||
protected:
|
||||
//this method is called, when BG cannot spawn its own spirit guide, or something is wrong, It correctly ends BattleGround
|
||||
void EndNow();
|
||||
void PlayerAddedToBGCheckIfBGIsRunning(Player* plr);
|
||||
|
||||
/* Scorekeeping */
|
||||
|
||||
BattleGroundScoreMap m_PlayerScores; // Player scores
|
||||
// must be implemented in BG subclass
|
||||
virtual void RemovePlayer(Player * /*player*/, uint64 /*guid*/) {}
|
||||
|
||||
/* Player lists, those need to be accessible by inherited classes */
|
||||
BattleGroundPlayerMap m_Players;
|
||||
// Spirit Guide guid + Player list GUIDS
|
||||
std::map<uint64, std::vector<uint64> > m_ReviveQueue;
|
||||
|
||||
/*
|
||||
these are important variables used for starting messages
|
||||
*/
|
||||
uint8 m_Events;
|
||||
BattleGroundStartTimeIntervals m_StartDelayTimes[BG_STARTING_EVENT_COUNT];
|
||||
//this must be filled in constructors!
|
||||
uint32 m_StartMessageIds[BG_STARTING_EVENT_COUNT];
|
||||
|
||||
bool m_BuffChange;
|
||||
bool m_IsRandom;
|
||||
|
||||
BGHonorMode m_HonorMode;
|
||||
private:
|
||||
/* Battleground */
|
||||
BattleGroundTypeId m_TypeID;
|
||||
BattleGroundTypeId m_RandomTypeID;
|
||||
uint32 m_InstanceID; //BattleGround Instance's GUID!
|
||||
BattleGroundStatus m_Status;
|
||||
uint32 m_ClientInstanceID; //the instance-id which is sent to the client and without any other internal use
|
||||
uint32 m_StartTime;
|
||||
int32 m_EndTime; // it is set to 120000 when bg is ending and it decreases itself
|
||||
uint32 m_LastResurrectTime;
|
||||
BattleGroundBracketId m_BracketId;
|
||||
uint8 m_ArenaType; // 2=2v2, 3=3v3, 5=5v5
|
||||
bool m_InBGFreeSlotQueue; // used to make sure that BG is only once inserted into the BattleGroundMgr.BGFreeSlotQueue[bgTypeId] deque
|
||||
bool m_SetDeleteThis; // used for safe deletion of the bg after end / all players leave
|
||||
bool m_IsArena;
|
||||
uint8 m_Winner; // 0=alliance, 1=horde, 2=none
|
||||
int32 m_StartDelayTime;
|
||||
bool m_IsRated; // is this battle rated?
|
||||
bool m_PrematureCountDown;
|
||||
uint32 m_PrematureCountDownTimer;
|
||||
char const *m_Name;
|
||||
|
||||
/* Player lists */
|
||||
std::vector<uint64> m_ResurrectQueue; // Player GUID
|
||||
std::deque<uint64> m_OfflineQueue; // Player GUID
|
||||
|
||||
/* Invited counters are useful for player invitation to BG - do not allow, if BG is started to one faction to have 2 more players than another faction */
|
||||
/* Invited counters will be changed only when removing already invited player from queue, removing player from battleground and inviting player to BG */
|
||||
/* Invited players counters*/
|
||||
uint32 m_InvitedAlliance;
|
||||
uint32 m_InvitedHorde;
|
||||
|
||||
/* Raid Group */
|
||||
Group *m_BgRaids[BG_TEAMS_COUNT]; // 0 - alliance, 1 - horde
|
||||
|
||||
/* Players count by team */
|
||||
uint32 m_PlayersCount[BG_TEAMS_COUNT];
|
||||
|
||||
/* Arena team ids by team */
|
||||
uint32 m_ArenaTeamIds[BG_TEAMS_COUNT];
|
||||
|
||||
int32 m_ArenaTeamRatingChanges[BG_TEAMS_COUNT];
|
||||
|
||||
/* Limits */
|
||||
uint32 m_LevelMin;
|
||||
uint32 m_LevelMax;
|
||||
uint32 m_MaxPlayersPerTeam;
|
||||
uint32 m_MaxPlayers;
|
||||
uint32 m_MinPlayersPerTeam;
|
||||
uint32 m_MinPlayers;
|
||||
|
||||
/* Start location */
|
||||
uint32 m_MapId;
|
||||
BattleGroundMap* m_Map;
|
||||
float m_TeamStartLocX[BG_TEAMS_COUNT];
|
||||
float m_TeamStartLocY[BG_TEAMS_COUNT];
|
||||
float m_TeamStartLocZ[BG_TEAMS_COUNT];
|
||||
float m_TeamStartLocO[BG_TEAMS_COUNT];
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "BattleGround.h"
|
||||
#include "BattleGroundAA.h"
|
||||
#include "Language.h"
|
||||
#include "Player.h"
|
||||
|
||||
BattleGroundAA::BattleGroundAA()
|
||||
{
|
||||
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE;
|
||||
//we must set messageIds
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattleGroundAA::~BattleGroundAA()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void BattleGroundAA::Update(uint32 diff)
|
||||
{
|
||||
BattleGround::Update(diff);
|
||||
}
|
||||
|
||||
void BattleGroundAA::StartingEventCloseDoors()
|
||||
{
|
||||
}
|
||||
|
||||
void BattleGroundAA::StartingEventOpenDoors()
|
||||
{
|
||||
}
|
||||
|
||||
void BattleGroundAA::AddPlayer(Player *plr)
|
||||
{
|
||||
BattleGround::AddPlayer(plr);
|
||||
//create score and add it to map, default values are set in constructor
|
||||
BattleGroundAAScore* sc = new BattleGroundAAScore;
|
||||
|
||||
m_PlayerScores[plr->GetGUID()] = sc;
|
||||
}
|
||||
|
||||
void BattleGroundAA::RemovePlayer(Player * /*plr*/, uint64 /*guid*/)
|
||||
{
|
||||
}
|
||||
|
||||
void BattleGroundAA::HandleKillPlayer(Player* player, Player* killer)
|
||||
{
|
||||
BattleGround::HandleKillPlayer(player, killer);
|
||||
}
|
||||
|
||||
void BattleGroundAA::HandleAreaTrigger(Player * /*Source*/, uint32 /*Trigger*/)
|
||||
{
|
||||
}
|
||||
|
||||
bool BattleGroundAA::SetupBattleGround()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __BATTLEGROUNDAA_H
|
||||
#define __BATTLEGROUNDAA_H
|
||||
|
||||
class BattleGround;
|
||||
|
||||
class BattleGroundAAScore : public BattleGroundScore
|
||||
{
|
||||
public:
|
||||
BattleGroundAAScore() {};
|
||||
virtual ~BattleGroundAAScore() {};
|
||||
//TODO fix me
|
||||
};
|
||||
|
||||
class BattleGroundAA : public BattleGround
|
||||
{
|
||||
friend class BattleGroundMgr;
|
||||
|
||||
public:
|
||||
BattleGroundAA();
|
||||
~BattleGroundAA();
|
||||
void Update(uint32 diff);
|
||||
|
||||
/* inherited from BattlegroundClass */
|
||||
virtual void AddPlayer(Player *plr);
|
||||
virtual void StartingEventCloseDoors();
|
||||
virtual void StartingEventOpenDoors();
|
||||
|
||||
void RemovePlayer(Player *plr, uint64 guid);
|
||||
void HandleAreaTrigger(Player *Source, uint32 Trigger);
|
||||
bool SetupBattleGround();
|
||||
void HandleKillPlayer(Player* player, Player *killer);
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,715 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "World.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "BattleGroundMgr.h"
|
||||
#include "BattleGround.h"
|
||||
#include "BattleGroundAB.h"
|
||||
#include "Creature.h"
|
||||
#include "Language.h"
|
||||
#include "Object.h"
|
||||
#include "Player.h"
|
||||
#include "Util.h"
|
||||
|
||||
// these variables aren't used outside of this file, so declare them only here
|
||||
uint32 BG_AB_HonorScoreTicks[BG_HONOR_MODE_NUM] = {
|
||||
330, // normal honor
|
||||
200 // holiday
|
||||
};
|
||||
|
||||
uint32 BG_AB_ReputationScoreTicks[BG_HONOR_MODE_NUM] = {
|
||||
200, // normal honor
|
||||
150 // holiday
|
||||
};
|
||||
|
||||
BattleGroundAB::BattleGroundAB()
|
||||
{
|
||||
m_BuffChange = true;
|
||||
m_BgObjects.resize(BG_AB_OBJECT_MAX);
|
||||
m_BgCreatures.resize(BG_AB_ALL_NODES_COUNT + 5);//+5 for aura triggers
|
||||
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_AB_START_TWO_MINUTES;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_AB_START_ONE_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_AB_START_HALF_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_AB_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattleGroundAB::~BattleGroundAB()
|
||||
{
|
||||
}
|
||||
|
||||
void BattleGroundAB::Update(uint32 diff)
|
||||
{
|
||||
BattleGround::Update(diff);
|
||||
|
||||
if (GetStatus() == STATUS_IN_PROGRESS)
|
||||
{
|
||||
int team_points[BG_TEAMS_COUNT] = { 0, 0 };
|
||||
|
||||
for (int node = 0; node < BG_AB_DYNAMIC_NODES_COUNT; ++node)
|
||||
{
|
||||
// 3 sec delay to spawn new banner instead previous despawned one
|
||||
if (m_BannerTimers[node].timer)
|
||||
{
|
||||
if (m_BannerTimers[node].timer > diff)
|
||||
m_BannerTimers[node].timer -= diff;
|
||||
else
|
||||
{
|
||||
m_BannerTimers[node].timer = 0;
|
||||
_CreateBanner(node, m_BannerTimers[node].type, m_BannerTimers[node].teamIndex, false);
|
||||
}
|
||||
}
|
||||
|
||||
// 1-minute to occupy a node from contested state
|
||||
if (m_NodeTimers[node])
|
||||
{
|
||||
if (m_NodeTimers[node] > diff)
|
||||
m_NodeTimers[node] -= diff;
|
||||
else
|
||||
{
|
||||
m_NodeTimers[node] = 0;
|
||||
// Change from contested to occupied !
|
||||
uint8 teamIndex = m_Nodes[node]-1;
|
||||
m_prevNodes[node] = m_Nodes[node];
|
||||
m_Nodes[node] += 2;
|
||||
// burn current contested banner
|
||||
_DelBanner(node, BG_AB_NODE_TYPE_CONTESTED, teamIndex);
|
||||
// create new occupied banner
|
||||
_CreateBanner(node, BG_AB_NODE_TYPE_OCCUPIED, teamIndex, true);
|
||||
_SendNodeUpdate(node);
|
||||
_NodeOccupied(node,(teamIndex == 0) ? ALLIANCE:HORDE);
|
||||
// Message to chatlog
|
||||
|
||||
if (teamIndex == 0)
|
||||
{
|
||||
// FIXME: team and node names not localized
|
||||
SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN,CHAT_MSG_BG_SYSTEM_ALLIANCE,NULL,LANG_BG_AB_ALLY,_GetNodeNameId(node));
|
||||
PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME: team and node names not localized
|
||||
SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN,CHAT_MSG_BG_SYSTEM_HORDE,NULL,LANG_BG_AB_HORDE,_GetNodeNameId(node));
|
||||
PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int team = 0; team < BG_TEAMS_COUNT; ++team)
|
||||
if (m_Nodes[node] == team + BG_AB_NODE_TYPE_OCCUPIED)
|
||||
++team_points[team];
|
||||
}
|
||||
|
||||
// Accumulate points
|
||||
for (int team = 0; team < BG_TEAMS_COUNT; ++team)
|
||||
{
|
||||
int points = team_points[team];
|
||||
if (!points)
|
||||
continue;
|
||||
m_lastTick[team] += diff;
|
||||
if (m_lastTick[team] > BG_AB_TickIntervals[points])
|
||||
{
|
||||
m_lastTick[team] -= BG_AB_TickIntervals[points];
|
||||
m_TeamScores[team] += BG_AB_TickPoints[points];
|
||||
m_HonorScoreTics[team] += BG_AB_TickPoints[points];
|
||||
m_ReputationScoreTics[team] += BG_AB_TickPoints[points];
|
||||
if (m_ReputationScoreTics[team] >= m_ReputationTics)
|
||||
{
|
||||
(team == BG_TEAM_ALLIANCE) ? RewardReputationToTeam(509, 10, ALLIANCE) : RewardReputationToTeam(510, 10, HORDE);
|
||||
m_ReputationScoreTics[team] -= m_ReputationTics;
|
||||
}
|
||||
if (m_HonorScoreTics[team] >= m_HonorTics)
|
||||
{
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), (team == BG_TEAM_ALLIANCE) ? ALLIANCE : HORDE);
|
||||
m_HonorScoreTics[team] -= m_HonorTics;
|
||||
}
|
||||
if (!m_IsInformedNearVictory && m_TeamScores[team] > BG_AB_WARNING_NEAR_VICTORY_SCORE)
|
||||
{
|
||||
if (team == BG_TEAM_ALLIANCE)
|
||||
SendMessageToAll(LANG_BG_AB_A_NEAR_VICTORY, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
else
|
||||
SendMessageToAll(LANG_BG_AB_H_NEAR_VICTORY, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
PlaySoundToAll(BG_AB_SOUND_NEAR_VICTORY);
|
||||
m_IsInformedNearVictory = true;
|
||||
}
|
||||
|
||||
if (m_TeamScores[team] > BG_AB_MAX_TEAM_SCORE)
|
||||
m_TeamScores[team] = BG_AB_MAX_TEAM_SCORE;
|
||||
if (team == BG_TEAM_ALLIANCE)
|
||||
UpdateWorldState(BG_AB_OP_RESOURCES_ALLY, m_TeamScores[team]);
|
||||
if (team == BG_TEAM_HORDE)
|
||||
UpdateWorldState(BG_AB_OP_RESOURCES_HORDE, m_TeamScores[team]);
|
||||
// update achievement flags
|
||||
// we increased m_TeamScores[team] so we just need to check if it is 500 more than other teams resources
|
||||
uint8 otherTeam = (team + 1) % BG_TEAMS_COUNT;
|
||||
if (m_TeamScores[team] > m_TeamScores[otherTeam] + 500)
|
||||
m_TeamScores500Disadvantage[otherTeam] = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Test win condition
|
||||
if (m_TeamScores[BG_TEAM_ALLIANCE] >= BG_AB_MAX_TEAM_SCORE)
|
||||
EndBattleGround(ALLIANCE);
|
||||
if (m_TeamScores[BG_TEAM_HORDE] >= BG_AB_MAX_TEAM_SCORE)
|
||||
EndBattleGround(HORDE);
|
||||
}
|
||||
}
|
||||
|
||||
void BattleGroundAB::StartingEventCloseDoors()
|
||||
{
|
||||
// despawn banners, auras and buffs
|
||||
for (int obj = BG_AB_OBJECT_BANNER_NEUTRAL; obj < BG_AB_DYNAMIC_NODES_COUNT * 8; ++obj)
|
||||
SpawnBGObject(obj, RESPAWN_ONE_DAY);
|
||||
for (int i = 0; i < BG_AB_DYNAMIC_NODES_COUNT * 3; ++i)
|
||||
SpawnBGObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + i, RESPAWN_ONE_DAY);
|
||||
|
||||
// Starting doors
|
||||
DoorClose(BG_AB_OBJECT_GATE_A);
|
||||
DoorClose(BG_AB_OBJECT_GATE_H);
|
||||
SpawnBGObject(BG_AB_OBJECT_GATE_A, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(BG_AB_OBJECT_GATE_H, RESPAWN_IMMEDIATELY);
|
||||
|
||||
// Starting base spirit guides
|
||||
_NodeOccupied(BG_AB_SPIRIT_ALIANCE,ALLIANCE);
|
||||
_NodeOccupied(BG_AB_SPIRIT_HORDE,HORDE);
|
||||
}
|
||||
|
||||
void BattleGroundAB::StartingEventOpenDoors()
|
||||
{
|
||||
// spawn neutral banners
|
||||
for (int banner = BG_AB_OBJECT_BANNER_NEUTRAL, i = 0; i < 5; banner += 8, ++i)
|
||||
SpawnBGObject(banner, RESPAWN_IMMEDIATELY);
|
||||
for (int i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
|
||||
{
|
||||
//randomly select buff to spawn
|
||||
uint8 buff = urand(0, 2);
|
||||
SpawnBGObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + buff + i * 3, RESPAWN_IMMEDIATELY);
|
||||
}
|
||||
DoorOpen(BG_AB_OBJECT_GATE_A);
|
||||
DoorOpen(BG_AB_OBJECT_GATE_H);
|
||||
}
|
||||
|
||||
void BattleGroundAB::AddPlayer(Player *plr)
|
||||
{
|
||||
BattleGround::AddPlayer(plr);
|
||||
//create score and add it to map, default values are set in the constructor
|
||||
BattleGroundABScore* sc = new BattleGroundABScore;
|
||||
|
||||
m_PlayerScores[plr->GetGUID()] = sc;
|
||||
}
|
||||
|
||||
void BattleGroundAB::RemovePlayer(Player * /*plr*/, uint64 /*guid*/)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void BattleGroundAB::HandleAreaTrigger(Player *Source, uint32 Trigger)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
switch(Trigger)
|
||||
{
|
||||
case 3948: // Arathi Basin Alliance Exit.
|
||||
if (Source->GetTeam() != ALLIANCE)
|
||||
Source->GetSession()->SendAreaTriggerMessage("Only The Alliance can use that portal");
|
||||
else
|
||||
Source->LeaveBattleground();
|
||||
break;
|
||||
case 3949: // Arathi Basin Horde Exit.
|
||||
if (Source->GetTeam() != HORDE)
|
||||
Source->GetSession()->SendAreaTriggerMessage("Only The Horde can use that portal");
|
||||
else
|
||||
Source->LeaveBattleground();
|
||||
break;
|
||||
case 3866: // Stables
|
||||
case 3869: // Gold Mine
|
||||
case 3867: // Farm
|
||||
case 3868: // Lumber Mill
|
||||
case 3870: // Black Smith
|
||||
case 4020: // Unk1
|
||||
case 4021: // Unk2
|
||||
//break;
|
||||
default:
|
||||
//sLog.outError("WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger);
|
||||
//Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* type: 0-neutral, 1-contested, 3-occupied
|
||||
teamIndex: 0-ally, 1-horde */
|
||||
void BattleGroundAB::_CreateBanner(uint8 node, uint8 type, uint8 teamIndex, bool delay)
|
||||
{
|
||||
// Just put it into the queue
|
||||
if (delay)
|
||||
{
|
||||
m_BannerTimers[node].timer = 2000;
|
||||
m_BannerTimers[node].type = type;
|
||||
m_BannerTimers[node].teamIndex = teamIndex;
|
||||
return;
|
||||
}
|
||||
|
||||
uint8 obj = node*8 + type + teamIndex;
|
||||
|
||||
SpawnBGObject(obj, RESPAWN_IMMEDIATELY);
|
||||
|
||||
// handle aura with banner
|
||||
if (!type)
|
||||
return;
|
||||
obj = node * 8 + ((type == BG_AB_NODE_TYPE_OCCUPIED) ? (5 + teamIndex) : 7);
|
||||
SpawnBGObject(obj, RESPAWN_IMMEDIATELY);
|
||||
}
|
||||
|
||||
void BattleGroundAB::_DelBanner(uint8 node, uint8 type, uint8 teamIndex)
|
||||
{
|
||||
uint8 obj = node*8 + type + teamIndex;
|
||||
SpawnBGObject(obj, RESPAWN_ONE_DAY);
|
||||
|
||||
// handle aura with banner
|
||||
if (!type)
|
||||
return;
|
||||
obj = node * 8 + ((type == BG_AB_NODE_TYPE_OCCUPIED) ? (5 + teamIndex) : 7);
|
||||
SpawnBGObject(obj, RESPAWN_ONE_DAY);
|
||||
}
|
||||
|
||||
int32 BattleGroundAB::_GetNodeNameId(uint8 node)
|
||||
{
|
||||
switch (node)
|
||||
{
|
||||
case BG_AB_NODE_STABLES: return LANG_BG_AB_NODE_STABLES;
|
||||
case BG_AB_NODE_BLACKSMITH: return LANG_BG_AB_NODE_BLACKSMITH;
|
||||
case BG_AB_NODE_FARM: return LANG_BG_AB_NODE_FARM;
|
||||
case BG_AB_NODE_LUMBER_MILL:return LANG_BG_AB_NODE_LUMBER_MILL;
|
||||
case BG_AB_NODE_GOLD_MINE: return LANG_BG_AB_NODE_GOLD_MINE;
|
||||
default:
|
||||
ASSERT(0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void BattleGroundAB::FillInitialWorldStates(WorldPacket& data)
|
||||
{
|
||||
const uint8 plusArray[] = {0, 2, 3, 0, 1};
|
||||
|
||||
// Node icons
|
||||
for (uint8 node = 0; node < BG_AB_DYNAMIC_NODES_COUNT; ++node)
|
||||
data << uint32(BG_AB_OP_NODEICONS[node]) << uint32((m_Nodes[node] == 0)?1:0);
|
||||
|
||||
// Node occupied states
|
||||
for (uint8 node = 0; node < BG_AB_DYNAMIC_NODES_COUNT; ++node)
|
||||
for (uint8 i = 1; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
|
||||
data << uint32(BG_AB_OP_NODESTATES[node] + plusArray[i]) << uint32((m_Nodes[node] == i)?1:0);
|
||||
|
||||
// How many bases each team owns
|
||||
uint8 ally = 0, horde = 0;
|
||||
for (uint8 node = 0; node < BG_AB_DYNAMIC_NODES_COUNT; ++node)
|
||||
if (m_Nodes[node] == BG_AB_NODE_STATUS_ALLY_OCCUPIED)
|
||||
++ally;
|
||||
else if (m_Nodes[node] == BG_AB_NODE_STATUS_HORDE_OCCUPIED)
|
||||
++horde;
|
||||
|
||||
data << uint32(BG_AB_OP_OCCUPIED_BASES_ALLY) << uint32(ally);
|
||||
data << uint32(BG_AB_OP_OCCUPIED_BASES_HORDE) << uint32(horde);
|
||||
|
||||
// Team scores
|
||||
data << uint32(BG_AB_OP_RESOURCES_MAX) << uint32(BG_AB_MAX_TEAM_SCORE);
|
||||
data << uint32(BG_AB_OP_RESOURCES_WARNING) << uint32(BG_AB_WARNING_NEAR_VICTORY_SCORE);
|
||||
data << uint32(BG_AB_OP_RESOURCES_ALLY) << uint32(m_TeamScores[BG_TEAM_ALLIANCE]);
|
||||
data << uint32(BG_AB_OP_RESOURCES_HORDE) << uint32(m_TeamScores[BG_TEAM_HORDE]);
|
||||
|
||||
// other unknown
|
||||
data << uint32(0x745) << uint32(0x2); // 37 1861 unk
|
||||
}
|
||||
|
||||
void BattleGroundAB::_SendNodeUpdate(uint8 node)
|
||||
{
|
||||
// Send node owner state update to refresh map icons on client
|
||||
const uint8 plusArray[] = {0, 2, 3, 0, 1};
|
||||
|
||||
if (m_prevNodes[node])
|
||||
UpdateWorldState(BG_AB_OP_NODESTATES[node] + plusArray[m_prevNodes[node]], 0);
|
||||
else
|
||||
UpdateWorldState(BG_AB_OP_NODEICONS[node], 0);
|
||||
|
||||
UpdateWorldState(BG_AB_OP_NODESTATES[node] + plusArray[m_Nodes[node]], 1);
|
||||
|
||||
// How many bases each team owns
|
||||
uint8 ally = 0, horde = 0;
|
||||
for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
|
||||
if (m_Nodes[i] == BG_AB_NODE_STATUS_ALLY_OCCUPIED)
|
||||
++ally;
|
||||
else if (m_Nodes[i] == BG_AB_NODE_STATUS_HORDE_OCCUPIED)
|
||||
++horde;
|
||||
|
||||
UpdateWorldState(BG_AB_OP_OCCUPIED_BASES_ALLY, ally);
|
||||
UpdateWorldState(BG_AB_OP_OCCUPIED_BASES_HORDE, horde);
|
||||
}
|
||||
|
||||
void BattleGroundAB::_NodeOccupied(uint8 node,Team team)
|
||||
{
|
||||
if (!AddSpiritGuide(node, BG_AB_SpiritGuidePos[node][0], BG_AB_SpiritGuidePos[node][1], BG_AB_SpiritGuidePos[node][2], BG_AB_SpiritGuidePos[node][3], team))
|
||||
sLog.outError("Failed to spawn spirit guide! point: %u, team: %u,", node, team);
|
||||
|
||||
uint8 capturedNodes = 0;
|
||||
for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
|
||||
{
|
||||
if (m_Nodes[node] == GetTeamIndexByTeamId(team) + BG_AB_NODE_TYPE_OCCUPIED && !m_NodeTimers[i])
|
||||
++capturedNodes;
|
||||
}
|
||||
if (capturedNodes >= 5)
|
||||
CastSpellOnTeam(SPELL_AB_QUEST_REWARD_5_BASES, team);
|
||||
if (capturedNodes >= 4)
|
||||
CastSpellOnTeam(SPELL_AB_QUEST_REWARD_4_BASES, team);
|
||||
|
||||
if(node >= BG_AB_DYNAMIC_NODES_COUNT)//only dynamic nodes, no start points
|
||||
return;
|
||||
Creature* trigger = GetBGCreature(node+7);//0-6 spirit guides
|
||||
if (!trigger)
|
||||
trigger = AddCreature(WORLD_TRIGGER,node+7,team,BG_AB_NodePositions[node][0],BG_AB_NodePositions[node][1],BG_AB_NodePositions[node][2],BG_AB_NodePositions[node][3]);
|
||||
|
||||
//add bonus honor aura trigger creature when node is accupied
|
||||
//cast bonus aura (+50% honor in 25yards)
|
||||
//aura should only apply to players who have accupied the node, set correct faction for trigger
|
||||
if (trigger)
|
||||
{
|
||||
trigger->setFaction(team == ALLIANCE ? 84 : 83);
|
||||
trigger->CastSpell(trigger, SPELL_HONORABLE_DEFENDER_25Y, false);
|
||||
}
|
||||
}
|
||||
|
||||
void BattleGroundAB::_NodeDeOccupied(uint8 node)
|
||||
{
|
||||
if (node >= BG_AB_DYNAMIC_NODES_COUNT)
|
||||
return;
|
||||
|
||||
//remove bonus honor aura trigger creature when node is lost
|
||||
if(node < BG_AB_DYNAMIC_NODES_COUNT)//only dynamic nodes, no start points
|
||||
DelCreature(node+7);//NULL checks are in DelCreature! 0-6 spirit guides
|
||||
|
||||
// Those who are waiting to resurrect at this node are taken to the closest own node's graveyard
|
||||
std::vector<uint64> ghost_list = m_ReviveQueue[m_BgCreatures[node]];
|
||||
if (!ghost_list.empty())
|
||||
{
|
||||
WorldSafeLocsEntry const *ClosestGrave = NULL;
|
||||
for (std::vector<uint64>::const_iterator itr = ghost_list.begin(); itr != ghost_list.end(); ++itr)
|
||||
{
|
||||
Player* plr = objmgr.GetPlayer(*itr);
|
||||
if (!plr)
|
||||
continue;
|
||||
|
||||
if (!ClosestGrave) // cache
|
||||
ClosestGrave = GetClosestGraveYard(plr);
|
||||
|
||||
if (ClosestGrave)
|
||||
plr->TeleportTo(GetMapId(), ClosestGrave->x, ClosestGrave->y, ClosestGrave->z, plr->GetOrientation());
|
||||
}
|
||||
}
|
||||
|
||||
if (m_BgCreatures[node])
|
||||
DelCreature(node);
|
||||
|
||||
// buff object isn't despawned
|
||||
}
|
||||
|
||||
/* Invoked if a player used a banner as a gameobject */
|
||||
void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*target_obj*/)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
uint8 node = BG_AB_NODE_STABLES;
|
||||
GameObject* obj=GetBgMap()->GetGameObject(m_BgObjects[node*8+7]);
|
||||
while ((node < BG_AB_DYNAMIC_NODES_COUNT) && ((!obj) || (!source->IsWithinDistInMap(obj,10))))
|
||||
{
|
||||
++node;
|
||||
obj=GetBgMap()->GetGameObject(m_BgObjects[node*8+BG_AB_OBJECT_AURA_CONTESTED]);
|
||||
}
|
||||
|
||||
if (node == BG_AB_DYNAMIC_NODES_COUNT)
|
||||
{
|
||||
// this means our player isn't close to any of banners - maybe cheater ??
|
||||
return;
|
||||
}
|
||||
|
||||
BattleGroundTeamId teamIndex = GetTeamIndexByTeamId(source->GetTeam());
|
||||
|
||||
// Check if player really could use this banner, not cheated
|
||||
if (!(m_Nodes[node] == 0 || teamIndex == m_Nodes[node]%2))
|
||||
return;
|
||||
|
||||
source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
|
||||
uint32 sound = 0;
|
||||
// If node is neutral, change to contested
|
||||
if (m_Nodes[node] == BG_AB_NODE_TYPE_NEUTRAL)
|
||||
{
|
||||
UpdatePlayerScore(source, SCORE_BASES_ASSAULTED, 1);
|
||||
m_prevNodes[node] = m_Nodes[node];
|
||||
m_Nodes[node] = teamIndex + 1;
|
||||
// burn current neutral banner
|
||||
_DelBanner(node, BG_AB_NODE_TYPE_NEUTRAL, 0);
|
||||
// create new contested banner
|
||||
_CreateBanner(node, BG_AB_NODE_TYPE_CONTESTED, teamIndex, true);
|
||||
_SendNodeUpdate(node);
|
||||
m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME;
|
||||
|
||||
// FIXME: team and node names not localized
|
||||
if (teamIndex == 0)
|
||||
SendMessage2ToAll(LANG_BG_AB_NODE_CLAIMED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node), LANG_BG_AB_ALLY);
|
||||
else
|
||||
SendMessage2ToAll(LANG_BG_AB_NODE_CLAIMED,CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node), LANG_BG_AB_HORDE);
|
||||
|
||||
sound = BG_AB_SOUND_NODE_CLAIMED;
|
||||
}
|
||||
// If node is contested
|
||||
else if ((m_Nodes[node] == BG_AB_NODE_STATUS_ALLY_CONTESTED) || (m_Nodes[node] == BG_AB_NODE_STATUS_HORDE_CONTESTED))
|
||||
{
|
||||
// If last state is NOT occupied, change node to enemy-contested
|
||||
if (m_prevNodes[node] < BG_AB_NODE_TYPE_OCCUPIED)
|
||||
{
|
||||
UpdatePlayerScore(source, SCORE_BASES_ASSAULTED, 1);
|
||||
m_prevNodes[node] = m_Nodes[node];
|
||||
m_Nodes[node] = teamIndex + BG_AB_NODE_TYPE_CONTESTED;
|
||||
// burn current contested banner
|
||||
_DelBanner(node, BG_AB_NODE_TYPE_CONTESTED, !teamIndex);
|
||||
// create new contested banner
|
||||
_CreateBanner(node, BG_AB_NODE_TYPE_CONTESTED, teamIndex, true);
|
||||
_SendNodeUpdate(node);
|
||||
m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME;
|
||||
|
||||
// FIXME: node names not localized
|
||||
if (teamIndex == BG_TEAM_ALLIANCE)
|
||||
SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node));
|
||||
else
|
||||
SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node));
|
||||
}
|
||||
// If contested, change back to occupied
|
||||
else
|
||||
{
|
||||
UpdatePlayerScore(source, SCORE_BASES_DEFENDED, 1);
|
||||
m_prevNodes[node] = m_Nodes[node];
|
||||
m_Nodes[node] = teamIndex + BG_AB_NODE_TYPE_OCCUPIED;
|
||||
// burn current contested banner
|
||||
_DelBanner(node, BG_AB_NODE_TYPE_CONTESTED, !teamIndex);
|
||||
// create new occupied banner
|
||||
_CreateBanner(node, BG_AB_NODE_TYPE_OCCUPIED, teamIndex, true);
|
||||
_SendNodeUpdate(node);
|
||||
m_NodeTimers[node] = 0;
|
||||
_NodeOccupied(node,(teamIndex == BG_TEAM_ALLIANCE) ? ALLIANCE:HORDE);
|
||||
|
||||
// FIXME: node names not localized
|
||||
if (teamIndex == BG_TEAM_ALLIANCE)
|
||||
SendMessage2ToAll(LANG_BG_AB_NODE_DEFENDED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node));
|
||||
else
|
||||
SendMessage2ToAll(LANG_BG_AB_NODE_DEFENDED,CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node));
|
||||
}
|
||||
sound = (teamIndex == BG_TEAM_ALLIANCE) ? BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE : BG_AB_SOUND_NODE_ASSAULTED_HORDE;
|
||||
}
|
||||
// If node is occupied, change to enemy-contested
|
||||
else
|
||||
{
|
||||
UpdatePlayerScore(source, SCORE_BASES_ASSAULTED, 1);
|
||||
m_prevNodes[node] = m_Nodes[node];
|
||||
m_Nodes[node] = teamIndex + BG_AB_NODE_TYPE_CONTESTED;
|
||||
// burn current occupied banner
|
||||
_DelBanner(node, BG_AB_NODE_TYPE_OCCUPIED, !teamIndex);
|
||||
// create new contested banner
|
||||
_CreateBanner(node, BG_AB_NODE_TYPE_CONTESTED, teamIndex, true);
|
||||
_SendNodeUpdate(node);
|
||||
_NodeDeOccupied(node);
|
||||
m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME;
|
||||
|
||||
// FIXME: node names not localized
|
||||
if (teamIndex == BG_TEAM_ALLIANCE)
|
||||
SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node));
|
||||
else
|
||||
SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node));
|
||||
|
||||
sound = (teamIndex == BG_TEAM_ALLIANCE) ? BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE : BG_AB_SOUND_NODE_ASSAULTED_HORDE;
|
||||
}
|
||||
|
||||
// If node is occupied again, send "X has taken the Y" msg.
|
||||
if (m_Nodes[node] >= BG_AB_NODE_TYPE_OCCUPIED)
|
||||
{
|
||||
// FIXME: team and node names not localized
|
||||
if (teamIndex == BG_TEAM_ALLIANCE)
|
||||
SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN,CHAT_MSG_BG_SYSTEM_ALLIANCE, NULL, LANG_BG_AB_ALLY, _GetNodeNameId(node));
|
||||
else
|
||||
SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN,CHAT_MSG_BG_SYSTEM_HORDE, NULL, LANG_BG_AB_HORDE, _GetNodeNameId(node));
|
||||
}
|
||||
PlaySoundToAll(sound);
|
||||
}
|
||||
|
||||
bool BattleGroundAB::SetupBattleGround()
|
||||
{
|
||||
for (int i = 0 ; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
|
||||
{
|
||||
if (!AddObject(BG_AB_OBJECT_BANNER_NEUTRAL + 8*i,BG_AB_OBJECTID_NODE_BANNER_0 + i,BG_AB_NodePositions[i][0],BG_AB_NodePositions[i][1],BG_AB_NodePositions[i][2],BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2),RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_AB_OBJECT_BANNER_CONT_A + 8*i,BG_AB_OBJECTID_BANNER_CONT_A,BG_AB_NodePositions[i][0],BG_AB_NodePositions[i][1],BG_AB_NodePositions[i][2],BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2),RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_AB_OBJECT_BANNER_CONT_H + 8*i,BG_AB_OBJECTID_BANNER_CONT_H,BG_AB_NodePositions[i][0],BG_AB_NodePositions[i][1],BG_AB_NodePositions[i][2],BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2),RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_AB_OBJECT_BANNER_ALLY + 8*i,BG_AB_OBJECTID_BANNER_A,BG_AB_NodePositions[i][0],BG_AB_NodePositions[i][1],BG_AB_NodePositions[i][2],BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2),RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_AB_OBJECT_BANNER_HORDE + 8*i,BG_AB_OBJECTID_BANNER_H,BG_AB_NodePositions[i][0],BG_AB_NodePositions[i][1],BG_AB_NodePositions[i][2],BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2),RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_AB_OBJECT_AURA_ALLY + 8*i,BG_AB_OBJECTID_AURA_A,BG_AB_NodePositions[i][0],BG_AB_NodePositions[i][1],BG_AB_NodePositions[i][2],BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2),RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_AB_OBJECT_AURA_HORDE + 8*i,BG_AB_OBJECTID_AURA_H,BG_AB_NodePositions[i][0],BG_AB_NodePositions[i][1],BG_AB_NodePositions[i][2],BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2),RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_AB_OBJECT_AURA_CONTESTED + 8*i,BG_AB_OBJECTID_AURA_C,BG_AB_NodePositions[i][0],BG_AB_NodePositions[i][1],BG_AB_NodePositions[i][2],BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2),RESPAWN_ONE_DAY)
|
||||
)
|
||||
{
|
||||
sLog.outErrorDb("BatteGroundAB: Failed to spawn some object BattleGround not created!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!AddObject(BG_AB_OBJECT_GATE_A,BG_AB_OBJECTID_GATE_A,BG_AB_DoorPositions[0][0],BG_AB_DoorPositions[0][1],BG_AB_DoorPositions[0][2],BG_AB_DoorPositions[0][3],BG_AB_DoorPositions[0][4],BG_AB_DoorPositions[0][5],BG_AB_DoorPositions[0][6],BG_AB_DoorPositions[0][7],RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_AB_OBJECT_GATE_H,BG_AB_OBJECTID_GATE_H,BG_AB_DoorPositions[1][0],BG_AB_DoorPositions[1][1],BG_AB_DoorPositions[1][2],BG_AB_DoorPositions[1][3],BG_AB_DoorPositions[1][4],BG_AB_DoorPositions[1][5],BG_AB_DoorPositions[1][6],BG_AB_DoorPositions[1][7],RESPAWN_IMMEDIATELY)
|
||||
)
|
||||
{
|
||||
sLog.outErrorDb("BatteGroundAB: Failed to spawn door object BattleGround not created!");
|
||||
return false;
|
||||
}
|
||||
//buffs
|
||||
for (int i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
|
||||
{
|
||||
if (!AddObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + 3 * i, Buff_Entries[0], BG_AB_BuffPositions[i][0], BG_AB_BuffPositions[i][1], BG_AB_BuffPositions[i][2], BG_AB_BuffPositions[i][3], 0, 0, sin(BG_AB_BuffPositions[i][3]/2), cos(BG_AB_BuffPositions[i][3]/2), RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + 3 * i + 1, Buff_Entries[1], BG_AB_BuffPositions[i][0], BG_AB_BuffPositions[i][1], BG_AB_BuffPositions[i][2], BG_AB_BuffPositions[i][3], 0, 0, sin(BG_AB_BuffPositions[i][3]/2), cos(BG_AB_BuffPositions[i][3]/2), RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + 3 * i + 2, Buff_Entries[2], BG_AB_BuffPositions[i][0], BG_AB_BuffPositions[i][1], BG_AB_BuffPositions[i][2], BG_AB_BuffPositions[i][3], 0, 0, sin(BG_AB_BuffPositions[i][3]/2), cos(BG_AB_BuffPositions[i][3]/2), RESPAWN_ONE_DAY)
|
||||
)
|
||||
sLog.outErrorDb("BatteGroundAB: Failed to spawn buff object!");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BattleGroundAB::Reset()
|
||||
{
|
||||
//call parent's class reset
|
||||
BattleGround::Reset();
|
||||
|
||||
m_TeamScores[BG_TEAM_ALLIANCE] = 0;
|
||||
m_TeamScores[BG_TEAM_HORDE] = 0;
|
||||
m_lastTick[BG_TEAM_ALLIANCE] = 0;
|
||||
m_lastTick[BG_TEAM_HORDE] = 0;
|
||||
m_HonorScoreTics[BG_TEAM_ALLIANCE] = 0;
|
||||
m_HonorScoreTics[BG_TEAM_HORDE] = 0;
|
||||
m_ReputationScoreTics[BG_TEAM_ALLIANCE] = 0;
|
||||
m_ReputationScoreTics[BG_TEAM_HORDE] = 0;
|
||||
m_IsInformedNearVictory = false;
|
||||
bool isBGWeekend = sBattleGroundMgr.IsBGWeekend(GetTypeID());
|
||||
m_HonorTics = (isBGWeekend) ? BG_AB_ABBGWeekendHonorTicks : BG_AB_NotABBGWeekendHonorTicks;
|
||||
m_ReputationTics = (isBGWeekend) ? BG_AB_ABBGWeekendReputationTicks : BG_AB_NotABBGWeekendReputationTicks;
|
||||
m_TeamScores500Disadvantage[BG_TEAM_ALLIANCE] = false;
|
||||
m_TeamScores500Disadvantage[BG_TEAM_HORDE] = false;
|
||||
|
||||
for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
|
||||
{
|
||||
m_Nodes[i] = 0;
|
||||
m_prevNodes[i] = 0;
|
||||
m_NodeTimers[i] = 0;
|
||||
m_BannerTimers[i].timer = 0;
|
||||
}
|
||||
|
||||
for (uint8 i = 0; i < BG_AB_ALL_NODES_COUNT + 5; ++i)//+5 for aura triggers
|
||||
if (m_BgCreatures[i])
|
||||
DelCreature(i);
|
||||
}
|
||||
|
||||
void BattleGroundAB::EndBattleGround(uint32 winner)
|
||||
{
|
||||
//win reward
|
||||
if (winner == ALLIANCE)
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), ALLIANCE);
|
||||
if (winner == HORDE)
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), HORDE);
|
||||
//complete map_end rewards (even if no team wins)
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), HORDE);
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), ALLIANCE);
|
||||
|
||||
BattleGround::EndBattleGround(winner);
|
||||
}
|
||||
|
||||
WorldSafeLocsEntry const* BattleGroundAB::GetClosestGraveYard(Player* player)
|
||||
{
|
||||
BattleGroundTeamId teamIndex = GetTeamIndexByTeamId(player->GetTeam());
|
||||
|
||||
// Is there any occupied node for this team?
|
||||
std::vector<uint8> nodes;
|
||||
for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
|
||||
if (m_Nodes[i] == teamIndex + 3)
|
||||
nodes.push_back(i);
|
||||
|
||||
WorldSafeLocsEntry const* good_entry = NULL;
|
||||
// If so, select the closest node to place ghost on
|
||||
if (!nodes.empty())
|
||||
{
|
||||
float plr_x = player->GetPositionX();
|
||||
float plr_y = player->GetPositionY();
|
||||
|
||||
float mindist = 999999.0f;
|
||||
for (uint8 i = 0; i < nodes.size(); ++i)
|
||||
{
|
||||
WorldSafeLocsEntry const*entry = sWorldSafeLocsStore.LookupEntry(BG_AB_GraveyardIds[nodes[i]]);
|
||||
if (!entry)
|
||||
continue;
|
||||
float dist = (entry->x - plr_x)*(entry->x - plr_x)+(entry->y - plr_y)*(entry->y - plr_y);
|
||||
if (mindist > dist)
|
||||
{
|
||||
mindist = dist;
|
||||
good_entry = entry;
|
||||
}
|
||||
}
|
||||
nodes.clear();
|
||||
}
|
||||
// If not, place ghost on starting location
|
||||
if (!good_entry)
|
||||
good_entry = sWorldSafeLocsStore.LookupEntry(BG_AB_GraveyardIds[teamIndex+5]);
|
||||
|
||||
return good_entry;
|
||||
}
|
||||
|
||||
void BattleGroundAB::UpdatePlayerScore(Player *Source, uint32 type, uint32 value, bool doAddHonor)
|
||||
{
|
||||
BattleGroundScoreMap::iterator itr = m_PlayerScores.find(Source->GetGUID());
|
||||
if (itr == m_PlayerScores.end()) // player not found...
|
||||
return;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case SCORE_BASES_ASSAULTED:
|
||||
((BattleGroundABScore*)itr->second)->BasesAssaulted += value;
|
||||
break;
|
||||
case SCORE_BASES_DEFENDED:
|
||||
((BattleGroundABScore*)itr->second)->BasesDefended += value;
|
||||
break;
|
||||
default:
|
||||
BattleGround::UpdatePlayerScore(Source,type,value, doAddHonor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool BattleGroundAB::IsAllNodesConrolledByTeam(uint32 team) const
|
||||
{
|
||||
uint32 count = 0;
|
||||
for (int i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
|
||||
if ((team == ALLIANCE && m_Nodes[i] == BG_AB_NODE_STATUS_ALLY_OCCUPIED) ||
|
||||
(team == HORDE && m_Nodes[i] == BG_AB_NODE_STATUS_HORDE_OCCUPIED))
|
||||
++count;
|
||||
|
||||
return count == BG_AB_DYNAMIC_NODES_COUNT;
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __BATTLEGROUNDAB_H
|
||||
#define __BATTLEGROUNDAB_H
|
||||
|
||||
class BattleGround;
|
||||
|
||||
enum BG_AB_WorldStates
|
||||
{
|
||||
BG_AB_OP_OCCUPIED_BASES_HORDE = 1778,
|
||||
BG_AB_OP_OCCUPIED_BASES_ALLY = 1779,
|
||||
BG_AB_OP_RESOURCES_ALLY = 1776,
|
||||
BG_AB_OP_RESOURCES_HORDE = 1777,
|
||||
BG_AB_OP_RESOURCES_MAX = 1780,
|
||||
BG_AB_OP_RESOURCES_WARNING = 1955
|
||||
/*
|
||||
BG_AB_OP_STABLE_ICON = 1842, //Stable map icon (NONE)
|
||||
BG_AB_OP_STABLE_STATE_ALIENCE = 1767, //Stable map state (ALIENCE)
|
||||
BG_AB_OP_STABLE_STATE_HORDE = 1768, //Stable map state (HORDE)
|
||||
BG_AB_OP_STABLE_STATE_CON_ALI = 1769, //Stable map state (CON ALIENCE)
|
||||
BG_AB_OP_STABLE_STATE_CON_HOR = 1770, //Stable map state (CON HORDE)
|
||||
BG_AB_OP_FARM_ICON = 1845, //Farm map icon (NONE)
|
||||
BG_AB_OP_FARM_STATE_ALIENCE = 1772, //Farm state (ALIENCE)
|
||||
BG_AB_OP_FARM_STATE_HORDE = 1773, //Farm state (HORDE)
|
||||
BG_AB_OP_FARM_STATE_CON_ALI = 1774, //Farm state (CON ALIENCE)
|
||||
BG_AB_OP_FARM_STATE_CON_HOR = 1775, //Farm state (CON HORDE)
|
||||
|
||||
BG_AB_OP_BLACKSMITH_ICON = 1846, //Blacksmith map icon (NONE)
|
||||
BG_AB_OP_BLACKSMITH_STATE_ALIENCE = 1782, //Blacksmith map state (ALIENCE)
|
||||
BG_AB_OP_BLACKSMITH_STATE_HORDE = 1783, //Blacksmith map state (HORDE)
|
||||
BG_AB_OP_BLACKSMITH_STATE_CON_ALI = 1784, //Blacksmith map state (CON ALIENCE)
|
||||
BG_AB_OP_BLACKSMITH_STATE_CON_HOR = 1785, //Blacksmith map state (CON HORDE)
|
||||
BG_AB_OP_LUMBERMILL_ICON = 1844, //Lumber Mill map icon (NONE)
|
||||
BG_AB_OP_LUMBERMILL_STATE_ALIENCE = 1792, //Lumber Mill map state (ALIENCE)
|
||||
BG_AB_OP_LUMBERMILL_STATE_HORDE = 1793, //Lumber Mill map state (HORDE)
|
||||
BG_AB_OP_LUMBERMILL_STATE_CON_ALI = 1794, //Lumber Mill map state (CON ALIENCE)
|
||||
BG_AB_OP_LUMBERMILL_STATE_CON_HOR = 1795, //Lumber Mill map state (CON HORDE)
|
||||
BG_AB_OP_GOLDMINE_ICON = 1843, //Gold Mine map icon (NONE)
|
||||
BG_AB_OP_GOLDMINE_STATE_ALIENCE = 1787, //Gold Mine map state (ALIENCE)
|
||||
BG_AB_OP_GOLDMINE_STATE_HORDE = 1788, //Gold Mine map state (HORDE)
|
||||
BG_AB_OP_GOLDMINE_STATE_CON_ALI = 1789, //Gold Mine map state (CON ALIENCE
|
||||
BG_AB_OP_GOLDMINE_STATE_CON_HOR = 1790, //Gold Mine map state (CON HORDE)
|
||||
*/
|
||||
};
|
||||
|
||||
const uint32 BG_AB_OP_NODESTATES[5] = {1767, 1782, 1772, 1792, 1787};
|
||||
|
||||
const uint32 BG_AB_OP_NODEICONS[5] = {1842, 1846, 1845, 1844, 1843};
|
||||
|
||||
/* Note: code uses that these IDs follow each other */
|
||||
enum BG_AB_NodeObjectId
|
||||
{
|
||||
BG_AB_OBJECTID_NODE_BANNER_0 = 180087, // Stables banner
|
||||
BG_AB_OBJECTID_NODE_BANNER_1 = 180088, // Blacksmith banner
|
||||
BG_AB_OBJECTID_NODE_BANNER_2 = 180089, // Farm banner
|
||||
BG_AB_OBJECTID_NODE_BANNER_3 = 180090, // Lumber mill banner
|
||||
BG_AB_OBJECTID_NODE_BANNER_4 = 180091 // Gold mine banner
|
||||
};
|
||||
|
||||
enum BG_AB_ObjectType
|
||||
{
|
||||
// for all 5 node points 8*5=40 objects
|
||||
BG_AB_OBJECT_BANNER_NEUTRAL = 0,
|
||||
BG_AB_OBJECT_BANNER_CONT_A = 1,
|
||||
BG_AB_OBJECT_BANNER_CONT_H = 2,
|
||||
BG_AB_OBJECT_BANNER_ALLY = 3,
|
||||
BG_AB_OBJECT_BANNER_HORDE = 4,
|
||||
BG_AB_OBJECT_AURA_ALLY = 5,
|
||||
BG_AB_OBJECT_AURA_HORDE = 6,
|
||||
BG_AB_OBJECT_AURA_CONTESTED = 7,
|
||||
//gates
|
||||
BG_AB_OBJECT_GATE_A = 40,
|
||||
BG_AB_OBJECT_GATE_H = 41,
|
||||
//buffs
|
||||
BG_AB_OBJECT_SPEEDBUFF_STABLES = 42,
|
||||
BG_AB_OBJECT_REGENBUFF_STABLES = 43,
|
||||
BG_AB_OBJECT_BERSERKBUFF_STABLES = 44,
|
||||
BG_AB_OBJECT_SPEEDBUFF_BLACKSMITH = 45,
|
||||
BG_AB_OBJECT_REGENBUFF_BLACKSMITH = 46,
|
||||
BG_AB_OBJECT_BERSERKBUFF_BLACKSMITH = 47,
|
||||
BG_AB_OBJECT_SPEEDBUFF_FARM = 48,
|
||||
BG_AB_OBJECT_REGENBUFF_FARM = 49,
|
||||
BG_AB_OBJECT_BERSERKBUFF_FARM = 50,
|
||||
BG_AB_OBJECT_SPEEDBUFF_LUMBER_MILL = 51,
|
||||
BG_AB_OBJECT_REGENBUFF_LUMBER_MILL = 52,
|
||||
BG_AB_OBJECT_BERSERKBUFF_LUMBER_MILL = 53,
|
||||
BG_AB_OBJECT_SPEEDBUFF_GOLD_MINE = 54,
|
||||
BG_AB_OBJECT_REGENBUFF_GOLD_MINE = 55,
|
||||
BG_AB_OBJECT_BERSERKBUFF_GOLD_MINE = 56,
|
||||
BG_AB_OBJECT_MAX = 57,
|
||||
};
|
||||
|
||||
/* Object id templates from DB */
|
||||
enum BG_AB_ObjectTypes
|
||||
{
|
||||
BG_AB_OBJECTID_BANNER_A = 180058,
|
||||
BG_AB_OBJECTID_BANNER_CONT_A = 180059,
|
||||
BG_AB_OBJECTID_BANNER_H = 180060,
|
||||
BG_AB_OBJECTID_BANNER_CONT_H = 180061,
|
||||
|
||||
BG_AB_OBJECTID_AURA_A = 180100,
|
||||
BG_AB_OBJECTID_AURA_H = 180101,
|
||||
BG_AB_OBJECTID_AURA_C = 180102,
|
||||
|
||||
BG_AB_OBJECTID_GATE_A = 180255,
|
||||
BG_AB_OBJECTID_GATE_H = 180256
|
||||
};
|
||||
|
||||
enum BG_AB_Timers
|
||||
{
|
||||
BG_AB_FLAG_CAPTURING_TIME = 60000,
|
||||
};
|
||||
|
||||
enum BG_AB_Score
|
||||
{
|
||||
BG_AB_WARNING_NEAR_VICTORY_SCORE = 1400,
|
||||
BG_AB_MAX_TEAM_SCORE = 1600
|
||||
};
|
||||
|
||||
/* do NOT change the order, else wrong behaviour */
|
||||
enum BG_AB_BattleGroundNodes
|
||||
{
|
||||
BG_AB_NODE_STABLES = 0,
|
||||
BG_AB_NODE_BLACKSMITH = 1,
|
||||
BG_AB_NODE_FARM = 2,
|
||||
BG_AB_NODE_LUMBER_MILL = 3,
|
||||
BG_AB_NODE_GOLD_MINE = 4,
|
||||
|
||||
BG_AB_DYNAMIC_NODES_COUNT = 5, // dynamic nodes that can be captured
|
||||
|
||||
BG_AB_SPIRIT_ALIANCE = 5,
|
||||
BG_AB_SPIRIT_HORDE = 6,
|
||||
|
||||
BG_AB_ALL_NODES_COUNT = 7, // all nodes (dynamic and static)
|
||||
};
|
||||
|
||||
enum BG_AB_NodeStatus
|
||||
{
|
||||
BG_AB_NODE_TYPE_NEUTRAL = 0,
|
||||
BG_AB_NODE_TYPE_CONTESTED = 1,
|
||||
BG_AB_NODE_STATUS_ALLY_CONTESTED = 1,
|
||||
BG_AB_NODE_STATUS_HORDE_CONTESTED = 2,
|
||||
BG_AB_NODE_TYPE_OCCUPIED = 3,
|
||||
BG_AB_NODE_STATUS_ALLY_OCCUPIED = 3,
|
||||
BG_AB_NODE_STATUS_HORDE_OCCUPIED = 4
|
||||
};
|
||||
|
||||
enum BG_AB_Sounds
|
||||
{
|
||||
BG_AB_SOUND_NODE_CLAIMED = 8192,
|
||||
BG_AB_SOUND_NODE_CAPTURED_ALLIANCE = 8173,
|
||||
BG_AB_SOUND_NODE_CAPTURED_HORDE = 8213,
|
||||
BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE = 8212,
|
||||
BG_AB_SOUND_NODE_ASSAULTED_HORDE = 8174,
|
||||
BG_AB_SOUND_NEAR_VICTORY = 8456
|
||||
};
|
||||
|
||||
#define BG_AB_NotABBGWeekendHonorTicks 330
|
||||
#define BG_AB_ABBGWeekendHonorTicks 200
|
||||
#define BG_AB_NotABBGWeekendReputationTicks 200
|
||||
#define BG_AB_ABBGWeekendReputationTicks 150
|
||||
|
||||
// x, y, z, o
|
||||
const float BG_AB_NodePositions[BG_AB_DYNAMIC_NODES_COUNT][4] = {
|
||||
{1166.785f, 1200.132f, -56.70859f, 0.9075713f}, // stables
|
||||
{977.0156f, 1046.616f, -44.80923f, -2.600541f}, // blacksmith
|
||||
{806.1821f, 874.2723f, -55.99371f, -2.303835f}, // farm
|
||||
{856.1419f, 1148.902f, 11.18469f, -2.303835f}, // lumber mill
|
||||
{1146.923f, 848.1782f, -110.917f, -0.7330382f} // gold mine
|
||||
};
|
||||
|
||||
// x, y, z, o, rot0, rot1, rot2, rot3
|
||||
const float BG_AB_DoorPositions[2][8] = {
|
||||
{1284.597f, 1281.167f, -15.97792f, 0.7068594f, 0.012957f, -0.060288f, 0.344959f, 0.93659f},
|
||||
{708.0903f, 708.4479f, -17.8342f, -2.391099f, 0.050291f, 0.015127f, 0.929217f, -0.365784f}
|
||||
};
|
||||
|
||||
// Tick intervals and given points: case 0,1,2,3,4,5 captured nodes
|
||||
const uint32 BG_AB_TickIntervals[6] = {0, 12000, 9000, 6000, 3000, 1000};
|
||||
const uint32 BG_AB_TickPoints[6] = {0, 10, 10, 10, 10, 30};
|
||||
|
||||
// WorldSafeLocs ids for 5 nodes, and for ally, and horde starting location
|
||||
const uint32 BG_AB_GraveyardIds[BG_AB_ALL_NODES_COUNT] = {895, 894, 893, 897, 896, 898, 899};
|
||||
|
||||
// x, y, z, o
|
||||
const float BG_AB_BuffPositions[BG_AB_DYNAMIC_NODES_COUNT][4] = {
|
||||
{1185.71f, 1185.24f, -56.36f, 2.56f}, // stables
|
||||
{990.75f, 1008.18f, -42.60f, 2.43f}, // blacksmith
|
||||
{817.66f, 843.34f, -56.54f, 3.01f}, // farm
|
||||
{807.46f, 1189.16f, 11.92f, 5.44f}, // lumber mill
|
||||
{1146.62f, 816.94f, -98.49f, 6.14f} // gold mine
|
||||
};
|
||||
|
||||
// x, y, z, o
|
||||
const float BG_AB_SpiritGuidePos[BG_AB_ALL_NODES_COUNT][4] = {
|
||||
{1200.03f, 1171.09f, -56.47f, 5.15f}, // stables
|
||||
{1017.43f, 960.61f, -42.95f, 4.88f}, // blacksmith
|
||||
{833.00f, 793.00f, -57.25f, 5.27f}, // farm
|
||||
{775.17f, 1206.40f, 15.79f, 1.90f}, // lumber mill
|
||||
{1207.48f, 787.00f, -83.36f, 5.51f}, // gold mine
|
||||
{1354.05f, 1275.48f, -11.30f, 4.77f}, // alliance starting base
|
||||
{714.61f, 646.15f, -10.87f, 4.34f} // horde starting base
|
||||
};
|
||||
|
||||
struct BG_AB_BannerTimer
|
||||
{
|
||||
uint32 timer;
|
||||
uint8 type;
|
||||
uint8 teamIndex;
|
||||
};
|
||||
|
||||
class BattleGroundABScore : public BattleGroundScore
|
||||
{
|
||||
public:
|
||||
BattleGroundABScore(): BasesAssaulted(0), BasesDefended(0) {};
|
||||
virtual ~BattleGroundABScore() {};
|
||||
uint32 BasesAssaulted;
|
||||
uint32 BasesDefended;
|
||||
};
|
||||
|
||||
class BattleGroundAB : public BattleGround
|
||||
{
|
||||
friend class BattleGroundMgr;
|
||||
|
||||
public:
|
||||
BattleGroundAB();
|
||||
~BattleGroundAB();
|
||||
|
||||
void Update(uint32 diff);
|
||||
void AddPlayer(Player *plr);
|
||||
virtual void StartingEventCloseDoors();
|
||||
virtual void StartingEventOpenDoors();
|
||||
void RemovePlayer(Player *plr,uint64 guid);
|
||||
void HandleAreaTrigger(Player *Source, uint32 Trigger);
|
||||
virtual bool SetupBattleGround();
|
||||
virtual void Reset();
|
||||
void EndBattleGround(uint32 winner);
|
||||
virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player);
|
||||
|
||||
/* Scorekeeping */
|
||||
virtual void UpdatePlayerScore(Player *Source, uint32 type, uint32 value, bool doAddHonor = true);
|
||||
|
||||
virtual void FillInitialWorldStates(WorldPacket& data);
|
||||
|
||||
/* Nodes occupying */
|
||||
virtual void EventPlayerClickedOnFlag(Player *source, GameObject* target_obj);
|
||||
|
||||
/* achievement req. */
|
||||
bool IsAllNodesConrolledByTeam(uint32 team) const; // overwrited
|
||||
bool IsTeamScores500Disadvantage(uint32 team) const { return m_TeamScores500Disadvantage[GetTeamIndexByTeamId(team)]; }
|
||||
private:
|
||||
/* Gameobject spawning/despawning */
|
||||
void _CreateBanner(uint8 node, uint8 type, uint8 teamIndex, bool delay);
|
||||
void _DelBanner(uint8 node, uint8 type, uint8 teamIndex);
|
||||
void _SendNodeUpdate(uint8 node);
|
||||
|
||||
/* Creature spawning/despawning */
|
||||
// TODO: working, scripted peons spawning
|
||||
void _NodeOccupied(uint8 node,Team team);
|
||||
void _NodeDeOccupied(uint8 node);
|
||||
|
||||
int32 _GetNodeNameId(uint8 node);
|
||||
|
||||
/* Nodes info:
|
||||
0: neutral
|
||||
1: ally contested
|
||||
2: horde contested
|
||||
3: ally occupied
|
||||
4: horde occupied */
|
||||
uint8 m_Nodes[BG_AB_DYNAMIC_NODES_COUNT];
|
||||
uint8 m_prevNodes[BG_AB_DYNAMIC_NODES_COUNT];
|
||||
BG_AB_BannerTimer m_BannerTimers[BG_AB_DYNAMIC_NODES_COUNT];
|
||||
uint32 m_NodeTimers[BG_AB_DYNAMIC_NODES_COUNT];
|
||||
uint32 m_lastTick[BG_TEAMS_COUNT];
|
||||
uint32 m_HonorScoreTics[BG_TEAMS_COUNT];
|
||||
uint32 m_ReputationScoreTics[BG_TEAMS_COUNT];
|
||||
bool m_IsInformedNearVictory;
|
||||
uint32 m_HonorTics;
|
||||
uint32 m_ReputationTics;
|
||||
// need for achievements
|
||||
bool m_TeamScores500Disadvantage[BG_TEAMS_COUNT];
|
||||
};
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "BattleGround.h"
|
||||
#include "BattleGroundBE.h"
|
||||
#include "Language.h"
|
||||
#include "Object.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Player.h"
|
||||
#include "WorldPacket.h"
|
||||
|
||||
BattleGroundBE::BattleGroundBE()
|
||||
{
|
||||
m_BgObjects.resize(BG_BE_OBJECT_MAX);
|
||||
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE;
|
||||
//we must set messageIds
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattleGroundBE::~BattleGroundBE()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void BattleGroundBE::Update(uint32 diff)
|
||||
{
|
||||
BattleGround::Update(diff);
|
||||
|
||||
/*if (GetStatus() == STATUS_IN_PROGRESS)
|
||||
{
|
||||
// update something
|
||||
}*/
|
||||
}
|
||||
|
||||
void BattleGroundBE::StartingEventCloseDoors()
|
||||
{
|
||||
for (uint32 i = BG_BE_OBJECT_DOOR_1; i <= BG_BE_OBJECT_DOOR_4; ++i)
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
|
||||
for (uint32 i = BG_BE_OBJECT_BUFF_1; i <= BG_BE_OBJECT_BUFF_2; ++i)
|
||||
SpawnBGObject(i, RESPAWN_ONE_DAY);
|
||||
}
|
||||
|
||||
void BattleGroundBE::StartingEventOpenDoors()
|
||||
{
|
||||
for (uint32 i = BG_BE_OBJECT_DOOR_1; i <= BG_BE_OBJECT_DOOR_2; ++i)
|
||||
DoorOpen(i);
|
||||
|
||||
for (uint32 i = BG_BE_OBJECT_BUFF_1; i <= BG_BE_OBJECT_BUFF_2; ++i)
|
||||
SpawnBGObject(i, 60);
|
||||
}
|
||||
|
||||
void BattleGroundBE::AddPlayer(Player *plr)
|
||||
{
|
||||
BattleGround::AddPlayer(plr);
|
||||
//create score and add it to map, default values are set in constructor
|
||||
BattleGroundBEScore* sc = new BattleGroundBEScore;
|
||||
|
||||
m_PlayerScores[plr->GetGUID()] = sc;
|
||||
|
||||
UpdateArenaWorldState();
|
||||
}
|
||||
|
||||
void BattleGroundBE::RemovePlayer(Player* /*plr*/, uint64 /*guid*/)
|
||||
{
|
||||
if (GetStatus() == STATUS_WAIT_LEAVE)
|
||||
return;
|
||||
|
||||
UpdateArenaWorldState();
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
|
||||
void BattleGroundBE::HandleKillPlayer(Player *player, Player *killer)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
if (!killer)
|
||||
{
|
||||
sLog.outError("Killer player not found");
|
||||
return;
|
||||
}
|
||||
|
||||
BattleGround::HandleKillPlayer(player,killer);
|
||||
|
||||
UpdateArenaWorldState();
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
|
||||
bool BattleGroundBE::HandlePlayerUnderMap(Player *player)
|
||||
{
|
||||
player->TeleportTo(GetMapId(),6238.930176,262.963470,0.889519,player->GetOrientation(),false);
|
||||
return true;
|
||||
}
|
||||
|
||||
void BattleGroundBE::HandleAreaTrigger(Player *Source, uint32 Trigger)
|
||||
{
|
||||
// this is wrong way to implement these things. On official it done by gameobject spell cast.
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
//uint32 SpellId = 0;
|
||||
//uint64 buff_guid = 0;
|
||||
switch(Trigger)
|
||||
{
|
||||
case 4538: // buff trigger?
|
||||
//buff_guid = m_BgObjects[BG_BE_OBJECT_BUFF_1];
|
||||
break;
|
||||
case 4539: // buff trigger?
|
||||
//buff_guid = m_BgObjects[BG_BE_OBJECT_BUFF_2];
|
||||
break;
|
||||
default:
|
||||
sLog.outError("WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger);
|
||||
Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger);
|
||||
break;
|
||||
}
|
||||
|
||||
//if (buff_guid)
|
||||
// HandleTriggerBuff(buff_guid,Source);
|
||||
}
|
||||
|
||||
void BattleGroundBE::FillInitialWorldStates(WorldPacket &data)
|
||||
{
|
||||
data << uint32(0x9f3) << uint32(1); // 9
|
||||
UpdateArenaWorldState();
|
||||
}
|
||||
|
||||
void BattleGroundBE::Reset()
|
||||
{
|
||||
//call parent's class reset
|
||||
BattleGround::Reset();
|
||||
}
|
||||
|
||||
bool BattleGroundBE::SetupBattleGround()
|
||||
{
|
||||
// gates
|
||||
if (!AddObject(BG_BE_OBJECT_DOOR_1, BG_BE_OBJECT_TYPE_DOOR_1, 6287.277f, 282.1877f, 3.810925f, -2.260201f, 0, 0, 0.9044551f, -0.4265689f, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_BE_OBJECT_DOOR_2, BG_BE_OBJECT_TYPE_DOOR_2, 6189.546f, 241.7099f, 3.101481f, 0.8813917f, 0, 0, 0.4265689f, 0.9044551f, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_BE_OBJECT_DOOR_3, BG_BE_OBJECT_TYPE_DOOR_3, 6299.116f, 296.5494f, 3.308032f, 0.8813917f, 0, 0, 0.4265689f, 0.9044551f, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_BE_OBJECT_DOOR_4, BG_BE_OBJECT_TYPE_DOOR_4, 6177.708f, 227.3481f, 3.604374f, -2.260201f, 0, 0, 0.9044551f, -0.4265689f, RESPAWN_IMMEDIATELY)
|
||||
// buffs
|
||||
|| !AddObject(BG_BE_OBJECT_BUFF_1, BG_BE_OBJECT_TYPE_BUFF_1, 6249.042f, 275.3239f, 11.22033f, -1.448624f, 0, 0, 0.6626201f, -0.7489557f, 120)
|
||||
|| !AddObject(BG_BE_OBJECT_BUFF_2, BG_BE_OBJECT_TYPE_BUFF_2, 6228.26f, 249.566f, 11.21812f, -0.06981307f, 0, 0, 0.03489945f, -0.9993908f, 120))
|
||||
{
|
||||
sLog.outErrorDb("BatteGroundBE: Failed to spawn some object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BattleGroundBE::UpdatePlayerScore(Player* Source, uint32 type, uint32 value, bool doAddHonor)
|
||||
{
|
||||
|
||||
BattleGroundScoreMap::iterator itr = m_PlayerScores.find(Source->GetGUID());
|
||||
if (itr == m_PlayerScores.end()) // player not found...
|
||||
return;
|
||||
|
||||
//there is nothing special in this score
|
||||
BattleGround::UpdatePlayerScore(Source,type,value, doAddHonor);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
21:45:46 id:231310 [S2C] SMSG_INIT_WORLD_STATES (706 = 0x02C2) len: 86
|
||||
0000: 32 02 00 00 76 0e 00 00 00 00 00 00 09 00 f3 09 | 2...v...........
|
||||
0010: 00 00 01 00 00 00 f1 09 00 00 01 00 00 00 f0 09 | ................
|
||||
0020: 00 00 02 00 00 00 d4 08 00 00 00 00 00 00 d8 08 | ................
|
||||
0030: 00 00 00 00 00 00 d7 08 00 00 00 00 00 00 d6 08 | ................
|
||||
0040: 00 00 00 00 00 00 d5 08 00 00 00 00 00 00 d3 08 | ................
|
||||
0050: 00 00 00 00 00 00 | ......
|
||||
|
||||
spell 32724 - Gold Team
|
||||
spell 32725 - Green Team
|
||||
35774 Gold Team
|
||||
35775 Green Team
|
||||
*/
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __BATTLEGROUNDBE_H
|
||||
#define __BATTLEGROUNDBE_H
|
||||
|
||||
class BattleGround;
|
||||
|
||||
enum BattleGroundBEObjectTypes
|
||||
{
|
||||
BG_BE_OBJECT_DOOR_1 = 0,
|
||||
BG_BE_OBJECT_DOOR_2 = 1,
|
||||
BG_BE_OBJECT_DOOR_3 = 2,
|
||||
BG_BE_OBJECT_DOOR_4 = 3,
|
||||
BG_BE_OBJECT_BUFF_1 = 4,
|
||||
BG_BE_OBJECT_BUFF_2 = 5,
|
||||
BG_BE_OBJECT_MAX = 6
|
||||
};
|
||||
|
||||
enum BattleGroundBEObjects
|
||||
{
|
||||
BG_BE_OBJECT_TYPE_DOOR_1 = 183971,
|
||||
BG_BE_OBJECT_TYPE_DOOR_2 = 183973,
|
||||
BG_BE_OBJECT_TYPE_DOOR_3 = 183970,
|
||||
BG_BE_OBJECT_TYPE_DOOR_4 = 183972,
|
||||
BG_BE_OBJECT_TYPE_BUFF_1 = 184663,
|
||||
BG_BE_OBJECT_TYPE_BUFF_2 = 184664
|
||||
};
|
||||
|
||||
class BattleGroundBEScore : public BattleGroundScore
|
||||
{
|
||||
public:
|
||||
BattleGroundBEScore() {};
|
||||
virtual ~BattleGroundBEScore() {};
|
||||
};
|
||||
|
||||
class BattleGroundBE : public BattleGround
|
||||
{
|
||||
friend class BattleGroundMgr;
|
||||
|
||||
public:
|
||||
BattleGroundBE();
|
||||
~BattleGroundBE();
|
||||
void Update(uint32 diff);
|
||||
|
||||
/* inherited from BattlegroundClass */
|
||||
virtual void AddPlayer(Player *plr);
|
||||
virtual void StartingEventCloseDoors();
|
||||
virtual void StartingEventOpenDoors();
|
||||
|
||||
void RemovePlayer(Player *plr, uint64 guid);
|
||||
void HandleAreaTrigger(Player *Source, uint32 Trigger);
|
||||
bool SetupBattleGround();
|
||||
virtual void Reset();
|
||||
virtual void FillInitialWorldStates(WorldPacket &d);
|
||||
void HandleKillPlayer(Player* player, Player *killer);
|
||||
bool HandlePlayerUnderMap(Player * plr);
|
||||
|
||||
/* Scorekeeping */
|
||||
void UpdatePlayerScore(Player *Source, uint32 type, uint32 value, bool doAddHonor = true);
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "BattleGround.h"
|
||||
#include "BattleGroundDS.h"
|
||||
#include "Language.h"
|
||||
#include "Player.h"
|
||||
#include "Object.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "WorldPacket.h"
|
||||
|
||||
BattleGroundDS::BattleGroundDS()
|
||||
{
|
||||
m_BgObjects.resize(BG_DS_OBJECT_MAX);
|
||||
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE;
|
||||
//we must set messageIds
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattleGroundDS::~BattleGroundDS()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void BattleGroundDS::Update(uint32 diff)
|
||||
{
|
||||
BattleGround::Update(diff);
|
||||
if (getWaterFallTimer() < diff)
|
||||
{
|
||||
if (isWaterFallActive())
|
||||
{
|
||||
setWaterFallTimer(urand(BG_DS_WATERFALL_TIMER_MIN, BG_DS_WATERFALL_TIMER_MAX));
|
||||
for (uint32 i = BG_DS_OBJECT_WATER_1; i <= BG_DS_OBJECT_WATER_2; ++i)
|
||||
SpawnBGObject(i, getWaterFallTimer());
|
||||
setWaterFallActive(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
setWaterFallTimer(BG_DS_WATERFALL_DURATION);
|
||||
for (uint32 i = BG_DS_OBJECT_WATER_1; i <= BG_DS_OBJECT_WATER_2; ++i)
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
setWaterFallActive(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
setWaterFallTimer(getWaterFallTimer() - diff);
|
||||
}
|
||||
|
||||
void BattleGroundDS::StartingEventCloseDoors()
|
||||
{
|
||||
for (uint32 i = BG_DS_OBJECT_DOOR_1; i <= BG_DS_OBJECT_DOOR_2; ++i)
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
}
|
||||
|
||||
void BattleGroundDS::StartingEventOpenDoors()
|
||||
{
|
||||
for (uint32 i = BG_DS_OBJECT_DOOR_1; i <= BG_DS_OBJECT_DOOR_2; ++i)
|
||||
DoorOpen(i);
|
||||
|
||||
for (uint32 i = BG_DS_OBJECT_BUFF_1; i <= BG_DS_OBJECT_BUFF_2; ++i)
|
||||
SpawnBGObject(i, 60);
|
||||
|
||||
setWaterFallTimer(urand(BG_DS_WATERFALL_TIMER_MIN, BG_DS_WATERFALL_TIMER_MAX));
|
||||
setWaterFallActive(false);
|
||||
|
||||
for (uint32 i = BG_DS_OBJECT_WATER_1; i <= BG_DS_OBJECT_WATER_2; ++i)
|
||||
SpawnBGObject(i, getWaterFallTimer());
|
||||
}
|
||||
|
||||
void BattleGroundDS::AddPlayer(Player *plr)
|
||||
{
|
||||
BattleGround::AddPlayer(plr);
|
||||
//create score and add it to map, default values are set in constructor
|
||||
BattleGroundDSScore* sc = new BattleGroundDSScore;
|
||||
|
||||
m_PlayerScores[plr->GetGUID()] = sc;
|
||||
|
||||
UpdateArenaWorldState();
|
||||
}
|
||||
|
||||
void BattleGroundDS::RemovePlayer(Player * /*plr*/, uint64 /*guid*/)
|
||||
{
|
||||
if (GetStatus() == STATUS_WAIT_LEAVE)
|
||||
return;
|
||||
|
||||
UpdateArenaWorldState();
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
|
||||
void BattleGroundDS::HandleKillPlayer(Player* player, Player* killer)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
if (!killer)
|
||||
{
|
||||
sLog.outError("BattleGroundDS: Killer player not found");
|
||||
return;
|
||||
}
|
||||
|
||||
BattleGround::HandleKillPlayer(player,killer);
|
||||
|
||||
UpdateArenaWorldState();
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
|
||||
void BattleGroundDS::HandleAreaTrigger(Player *Source, uint32 Trigger)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
switch(Trigger)
|
||||
{
|
||||
case 5347:
|
||||
case 5348:
|
||||
break;
|
||||
default:
|
||||
sLog.outError("WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger);
|
||||
Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool BattleGroundDS::HandlePlayerUnderMap(Player *player)
|
||||
{
|
||||
player->TeleportTo(GetMapId(), 1299.046, 784.825, 9.338, 2.422, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
void BattleGroundDS::FillInitialWorldStates(WorldPacket &data)
|
||||
{
|
||||
data << uint32(3610) << uint32(1); // 9 show
|
||||
UpdateArenaWorldState();
|
||||
}
|
||||
|
||||
void BattleGroundDS::Reset()
|
||||
{
|
||||
//call parent's class reset
|
||||
BattleGround::Reset();
|
||||
}
|
||||
|
||||
|
||||
bool BattleGroundDS::SetupBattleGround()
|
||||
{
|
||||
// gates
|
||||
if (!AddObject(BG_DS_OBJECT_DOOR_1, BG_DS_OBJECT_TYPE_DOOR_1, 1350.95, 817.2, 20.8096, 3.15, 0, 0, 0.99627, 0.0862864, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_DS_OBJECT_DOOR_2, BG_DS_OBJECT_TYPE_DOOR_2, 1232.65, 764.913, 20.0729, 6.3, 0, 0, 0.0310211, -0.999519, RESPAWN_IMMEDIATELY)
|
||||
// water
|
||||
|| !AddObject(BG_DS_OBJECT_WATER_1, BG_DS_OBJECT_TYPE_WATER_1, 1291.56, 790.837, 7.1, 3.14238, 0, 0, 0.694215, -0.719768, 120)
|
||||
|| !AddObject(BG_DS_OBJECT_WATER_2, BG_DS_OBJECT_TYPE_WATER_2, 1291.56, 790.837, 7.1, 3.14238, 0, 0, 0.694215, -0.719768, 120)
|
||||
// buffs
|
||||
|| !AddObject(BG_DS_OBJECT_BUFF_1, BG_DS_OBJECT_TYPE_BUFF_1, 1291.7, 813.424, 7.11472, 4.64562, 0, 0, 0.730314, -0.683111, 120)
|
||||
|| !AddObject(BG_DS_OBJECT_BUFF_2, BG_DS_OBJECT_TYPE_BUFF_2, 1291.7, 768.911, 7.11472, 1.55194, 0, 0, 0.700409, 0.713742, 120))
|
||||
{
|
||||
sLog.outErrorDb("BatteGroundDS: Failed to spawn some object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __BATTLEGROUNDDS_H
|
||||
#define __BATTLEGROUNDDS_H
|
||||
|
||||
class BattleGround;
|
||||
|
||||
enum BattleGroundDSObjectTypes
|
||||
{
|
||||
BG_DS_OBJECT_DOOR_1 = 0,
|
||||
BG_DS_OBJECT_DOOR_2 = 1,
|
||||
BG_DS_OBJECT_WATER_1 = 2,
|
||||
BG_DS_OBJECT_WATER_2 = 3,
|
||||
BG_DS_OBJECT_BUFF_1 = 4,
|
||||
BG_DS_OBJECT_BUFF_2 = 5,
|
||||
BG_DS_OBJECT_MAX = 6
|
||||
};
|
||||
|
||||
enum BattleGroundDSObjects
|
||||
{
|
||||
BG_DS_OBJECT_TYPE_DOOR_1 = 192642,
|
||||
BG_DS_OBJECT_TYPE_DOOR_2 = 192643,
|
||||
BG_DS_OBJECT_TYPE_WATER_1 = 194395,
|
||||
BG_DS_OBJECT_TYPE_WATER_2 = 191877,
|
||||
BG_DS_OBJECT_TYPE_BUFF_1 = 184663,
|
||||
BG_DS_OBJECT_TYPE_BUFF_2 = 184664
|
||||
};
|
||||
|
||||
enum BattleGroundDSData
|
||||
{ // These values are NOT blizzlike... need the correct data!
|
||||
BG_DS_WATERFALL_TIMER_MIN = 30000,
|
||||
BG_DS_WATERFALL_TIMER_MAX = 60000,
|
||||
BG_DS_WATERFALL_DURATION = 10000,
|
||||
};
|
||||
|
||||
class BattleGroundDSScore : public BattleGroundScore
|
||||
{
|
||||
public:
|
||||
BattleGroundDSScore() {};
|
||||
virtual ~BattleGroundDSScore() {};
|
||||
//TODO fix me
|
||||
};
|
||||
|
||||
class BattleGroundDS : public BattleGround
|
||||
{
|
||||
friend class BattleGroundMgr;
|
||||
|
||||
public:
|
||||
BattleGroundDS();
|
||||
~BattleGroundDS();
|
||||
void Update(uint32 diff);
|
||||
|
||||
/* inherited from BattlegroundClass */
|
||||
virtual void AddPlayer(Player *plr);
|
||||
virtual void StartingEventCloseDoors();
|
||||
virtual void StartingEventOpenDoors();
|
||||
|
||||
void RemovePlayer(Player *plr, uint64 guid);
|
||||
void HandleAreaTrigger(Player *Source, uint32 Trigger);
|
||||
bool SetupBattleGround();
|
||||
virtual void Reset();
|
||||
virtual void FillInitialWorldStates(WorldPacket &d);
|
||||
void HandleKillPlayer(Player* player, Player *killer);
|
||||
bool HandlePlayerUnderMap(Player * plr);
|
||||
private:
|
||||
uint32 m_waterTimer;
|
||||
bool m_waterfallActive;
|
||||
protected:
|
||||
bool isWaterFallActive() { return m_waterfallActive; };
|
||||
void setWaterFallActive(bool active) { m_waterfallActive = active; };
|
||||
void setWaterFallTimer(uint32 timer) { m_waterTimer = timer; };
|
||||
uint32 getWaterFallTimer() { return m_waterTimer; };
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,938 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "ObjectMgr.h"
|
||||
#include "World.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "BattleGroundMgr.h"
|
||||
#include "BattleGround.h"
|
||||
#include "BattleGroundEY.h"
|
||||
#include "Creature.h"
|
||||
#include "Language.h"
|
||||
#include "Object.h"
|
||||
#include "Player.h"
|
||||
#include "Util.h"
|
||||
|
||||
// these variables aren't used outside of this file, so declare them only here
|
||||
uint32 BG_EY_HonorScoreTicks[BG_HONOR_MODE_NUM] = {
|
||||
330, // normal honor
|
||||
200 // holiday
|
||||
};
|
||||
|
||||
BattleGroundEY::BattleGroundEY()
|
||||
{
|
||||
m_BuffChange = true;
|
||||
m_BgObjects.resize(BG_EY_OBJECT_MAX);
|
||||
m_BgCreatures.resize(BG_EY_CREATURES_MAX);
|
||||
m_Points_Trigger[FEL_REALVER] = TR_FEL_REALVER_BUFF;
|
||||
m_Points_Trigger[BLOOD_ELF] = TR_BLOOD_ELF_BUFF;
|
||||
m_Points_Trigger[DRAENEI_RUINS] = TR_DRAENEI_RUINS_BUFF;
|
||||
m_Points_Trigger[MAGE_TOWER] = TR_MAGE_TOWER_BUFF;
|
||||
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_EY_START_TWO_MINUTES;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_EY_START_ONE_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_EY_START_HALF_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_EY_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattleGroundEY::~BattleGroundEY()
|
||||
{
|
||||
}
|
||||
|
||||
void BattleGroundEY::Update(uint32 diff)
|
||||
{
|
||||
BattleGround::Update(diff);
|
||||
|
||||
if (GetStatus() == STATUS_IN_PROGRESS)
|
||||
{
|
||||
m_PointAddingTimer -= diff;
|
||||
if (m_PointAddingTimer <= 0)
|
||||
{
|
||||
m_PointAddingTimer = BG_EY_FPOINTS_TICK_TIME;
|
||||
if (m_TeamPointsCount[BG_TEAM_ALLIANCE] > 0)
|
||||
AddPoints(ALLIANCE, BG_EY_TickPoints[m_TeamPointsCount[BG_TEAM_ALLIANCE] - 1]);
|
||||
if (m_TeamPointsCount[BG_TEAM_HORDE] > 0)
|
||||
AddPoints(HORDE, BG_EY_TickPoints[m_TeamPointsCount[BG_TEAM_HORDE] - 1]);
|
||||
}
|
||||
|
||||
if (m_FlagState == BG_EY_FLAG_STATE_WAIT_RESPAWN || m_FlagState == BG_EY_FLAG_STATE_ON_GROUND)
|
||||
{
|
||||
m_FlagsTimer -= diff;
|
||||
|
||||
if (m_FlagsTimer < 0)
|
||||
{
|
||||
m_FlagsTimer = 0;
|
||||
if (m_FlagState == BG_EY_FLAG_STATE_WAIT_RESPAWN)
|
||||
RespawnFlag(true);
|
||||
else
|
||||
RespawnFlagAfterDrop();
|
||||
}
|
||||
}
|
||||
|
||||
m_TowerCapCheckTimer -= diff;
|
||||
if (m_TowerCapCheckTimer <= 0)
|
||||
{
|
||||
//check if player joined point
|
||||
/*I used this order of calls, because although we will check if one player is in gameobject's distance 2 times
|
||||
but we can count of players on current point in CheckSomeoneLeftPoint
|
||||
*/
|
||||
this->CheckSomeoneJoinedPoint();
|
||||
//check if player left point
|
||||
this->CheckSomeoneLeftPoint();
|
||||
this->UpdatePointStatuses();
|
||||
m_TowerCapCheckTimer = BG_EY_FPOINTS_TICK_TIME;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BattleGroundEY::StartingEventCloseDoors()
|
||||
{
|
||||
SpawnBGObject(BG_EY_OBJECT_DOOR_A, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(BG_EY_OBJECT_DOOR_H, RESPAWN_IMMEDIATELY);
|
||||
|
||||
for (uint32 i = BG_EY_OBJECT_A_BANNER_FEL_REALVER_CENTER; i < BG_EY_OBJECT_MAX; ++i)
|
||||
SpawnBGObject(i, RESPAWN_ONE_DAY);
|
||||
}
|
||||
|
||||
void BattleGroundEY::StartingEventOpenDoors()
|
||||
{
|
||||
SpawnBGObject(BG_EY_OBJECT_DOOR_A, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(BG_EY_OBJECT_DOOR_H, RESPAWN_ONE_DAY);
|
||||
|
||||
for (uint32 i = BG_EY_OBJECT_N_BANNER_FEL_REALVER_CENTER; i <= BG_EY_OBJECT_FLAG_NETHERSTORM; ++i)
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
for (uint32 i = 0; i < EY_POINTS_MAX; ++i)
|
||||
{
|
||||
//randomly spawn buff
|
||||
uint8 buff = urand(0, 2);
|
||||
SpawnBGObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REALVER + buff + i * 3, RESPAWN_IMMEDIATELY);
|
||||
}
|
||||
}
|
||||
|
||||
void BattleGroundEY::AddPoints(uint32 Team, uint32 Points)
|
||||
{
|
||||
BattleGroundTeamId team_index = GetTeamIndexByTeamId(Team);
|
||||
m_TeamScores[team_index] += Points;
|
||||
m_HonorScoreTics[team_index] += Points;
|
||||
if (m_HonorScoreTics[team_index] >= m_HonorTics)
|
||||
{
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), Team);
|
||||
m_HonorScoreTics[team_index] -= m_HonorTics;
|
||||
}
|
||||
UpdateTeamScore(Team);
|
||||
}
|
||||
|
||||
void BattleGroundEY::CheckSomeoneJoinedPoint()
|
||||
{
|
||||
GameObject *obj = NULL;
|
||||
for (uint8 i = 0; i < EY_POINTS_MAX; ++i)
|
||||
{
|
||||
obj = HashMapHolder<GameObject>::Find(m_BgObjects[BG_EY_OBJECT_TOWER_CAP_FEL_REALVER + i]);
|
||||
if (obj)
|
||||
{
|
||||
uint8 j = 0;
|
||||
while (j < m_PlayersNearPoint[EY_POINTS_MAX].size())
|
||||
{
|
||||
Player *plr = objmgr.GetPlayer(m_PlayersNearPoint[EY_POINTS_MAX][j]);
|
||||
if (!plr)
|
||||
{
|
||||
sLog.outError("BattleGroundEY:CheckSomeoneJoinedPoint: Player (GUID: %u) not found!", GUID_LOPART(m_PlayersNearPoint[EY_POINTS_MAX][j]));
|
||||
++j;
|
||||
continue;
|
||||
}
|
||||
if (plr->CanCaptureTowerPoint() && plr->IsWithinDistInMap(obj, BG_EY_POINT_RADIUS))
|
||||
{
|
||||
//player joined point!
|
||||
//show progress bar
|
||||
UpdateWorldStateForPlayer(PROGRESS_BAR_PERCENT_GREY, BG_EY_PROGRESS_BAR_PERCENT_GREY, plr);
|
||||
UpdateWorldStateForPlayer(PROGRESS_BAR_STATUS, m_PointBarStatus[i], plr);
|
||||
UpdateWorldStateForPlayer(PROGRESS_BAR_SHOW, BG_EY_PROGRESS_BAR_SHOW, plr);
|
||||
//add player to point
|
||||
m_PlayersNearPoint[i].push_back(m_PlayersNearPoint[EY_POINTS_MAX][j]);
|
||||
//remove player from "free space"
|
||||
m_PlayersNearPoint[EY_POINTS_MAX].erase(m_PlayersNearPoint[EY_POINTS_MAX].begin() + j);
|
||||
}
|
||||
else
|
||||
++j;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BattleGroundEY::CheckSomeoneLeftPoint()
|
||||
{
|
||||
//reset current point counts
|
||||
for (uint8 i = 0; i < 2*EY_POINTS_MAX; ++i)
|
||||
m_CurrentPointPlayersCount[i] = 0;
|
||||
GameObject *obj = NULL;
|
||||
for (uint8 i = 0; i < EY_POINTS_MAX; ++i)
|
||||
{
|
||||
obj = HashMapHolder<GameObject>::Find(m_BgObjects[BG_EY_OBJECT_TOWER_CAP_FEL_REALVER + i]);
|
||||
if (obj)
|
||||
{
|
||||
uint8 j = 0;
|
||||
while (j < m_PlayersNearPoint[i].size())
|
||||
{
|
||||
Player *plr = objmgr.GetPlayer(m_PlayersNearPoint[i][j]);
|
||||
if (!plr)
|
||||
{
|
||||
sLog.outError("BattleGroundEY:CheckSomeoneLeftPoint Player (GUID: %u) not found!", GUID_LOPART(m_PlayersNearPoint[i][j]));
|
||||
//move not existed player to "free space" - this will cause many error 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);
|
||||
++j;
|
||||
continue;
|
||||
}
|
||||
if (!plr->CanCaptureTowerPoint() || !plr->IsWithinDistInMap(obj, BG_EY_POINT_RADIUS))
|
||||
//move player out of point (add him to players that are out of points
|
||||
{
|
||||
m_PlayersNearPoint[EY_POINTS_MAX].push_back(m_PlayersNearPoint[i][j]);
|
||||
m_PlayersNearPoint[i].erase(m_PlayersNearPoint[i].begin() + j);
|
||||
this->UpdateWorldStateForPlayer(PROGRESS_BAR_SHOW, BG_EY_PROGRESS_BAR_DONT_SHOW, plr);
|
||||
}
|
||||
else
|
||||
{
|
||||
//player is neat flag, so update count:
|
||||
m_CurrentPointPlayersCount[2 * i + GetTeamIndexByTeamId(plr->GetTeam())]++;
|
||||
++j;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BattleGroundEY::UpdatePointStatuses()
|
||||
{
|
||||
for (uint8 point = 0; point < EY_POINTS_MAX; ++point)
|
||||
{
|
||||
if (m_PlayersNearPoint[point].empty())
|
||||
continue;
|
||||
//count new point bar status:
|
||||
m_PointBarStatus[point] += (m_CurrentPointPlayersCount[2 * point] - m_CurrentPointPlayersCount[2 * point + 1] < BG_EY_POINT_MAX_CAPTURERS_COUNT) ? m_CurrentPointPlayersCount[2 * point] - m_CurrentPointPlayersCount[2 * point + 1] : BG_EY_POINT_MAX_CAPTURERS_COUNT;
|
||||
|
||||
if (m_PointBarStatus[point] > BG_EY_PROGRESS_BAR_ALI_CONTROLLED)
|
||||
//point is fully alliance's
|
||||
m_PointBarStatus[point] = BG_EY_PROGRESS_BAR_ALI_CONTROLLED;
|
||||
if (m_PointBarStatus[point] < BG_EY_PROGRESS_BAR_HORDE_CONTROLLED)
|
||||
//point is fully horde's
|
||||
m_PointBarStatus[point] = BG_EY_PROGRESS_BAR_HORDE_CONTROLLED;
|
||||
|
||||
uint32 pointOwnerTeamId = 0;
|
||||
//find which team should own this point
|
||||
if (m_PointBarStatus[point] <= BG_EY_PROGRESS_BAR_NEUTRAL_LOW)
|
||||
pointOwnerTeamId = HORDE;
|
||||
else if (m_PointBarStatus[point] >= BG_EY_PROGRESS_BAR_NEUTRAL_HIGH)
|
||||
pointOwnerTeamId = ALLIANCE;
|
||||
else
|
||||
pointOwnerTeamId = EY_POINT_NO_OWNER;
|
||||
|
||||
for (uint8 i = 0; i < m_PlayersNearPoint[point].size(); ++i)
|
||||
{
|
||||
Player *plr = objmgr.GetPlayer(m_PlayersNearPoint[point][i]);
|
||||
if (plr)
|
||||
{
|
||||
this->UpdateWorldStateForPlayer(PROGRESS_BAR_STATUS, m_PointBarStatus[point], plr);
|
||||
//if point owner changed we must evoke event!
|
||||
if (pointOwnerTeamId != m_PointOwnedByTeam[point])
|
||||
{
|
||||
//point was uncontrolled and player is from team which captured point
|
||||
if (m_PointState[point] == EY_POINT_STATE_UNCONTROLLED && plr->GetTeam() == pointOwnerTeamId)
|
||||
this->EventTeamCapturedPoint(plr, point);
|
||||
|
||||
//point was under control and player isn't from team which controlled it
|
||||
if (m_PointState[point] == EY_POINT_UNDER_CONTROL && plr->GetTeam() != m_PointOwnedByTeam[point])
|
||||
this->EventTeamLostPoint(plr, point);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BattleGroundEY::UpdateTeamScore(uint32 Team)
|
||||
{
|
||||
uint32 score = GetTeamScore(Team);
|
||||
//TODO there should be some sound played when one team is near victory!! - and define variables
|
||||
/*if (!m_IsInformedNearVictory && score >= BG_EY_WARNING_NEAR_VICTORY_SCORE)
|
||||
{
|
||||
if (Team == ALLIANCE)
|
||||
SendMessageToAll(LANG_BG_EY_A_NEAR_VICTORY, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
else
|
||||
SendMessageToAll(LANG_BG_EY_H_NEAR_VICTORY, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
PlaySoundToAll(BG_EY_SOUND_NEAR_VICTORY);
|
||||
m_IsInformedNearVictory = true;
|
||||
}*/
|
||||
|
||||
if (score >= BG_EY_MAX_TEAM_SCORE)
|
||||
{
|
||||
score = BG_EY_MAX_TEAM_SCORE;
|
||||
EndBattleGround(Team);
|
||||
}
|
||||
|
||||
if (Team == ALLIANCE)
|
||||
UpdateWorldState(EY_ALLIANCE_RESOURCES, score);
|
||||
else
|
||||
UpdateWorldState(EY_HORDE_RESOURCES, score);
|
||||
}
|
||||
|
||||
void BattleGroundEY::EndBattleGround(uint32 winner)
|
||||
{
|
||||
//win reward
|
||||
if (winner == ALLIANCE)
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), ALLIANCE);
|
||||
if (winner == HORDE)
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), HORDE);
|
||||
//complete map reward
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), ALLIANCE);
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), HORDE);
|
||||
|
||||
BattleGround::EndBattleGround(winner);
|
||||
}
|
||||
|
||||
void BattleGroundEY::UpdatePointsCount(uint32 Team)
|
||||
{
|
||||
if (Team == ALLIANCE)
|
||||
UpdateWorldState(EY_ALLIANCE_BASE, m_TeamPointsCount[BG_TEAM_ALLIANCE]);
|
||||
else
|
||||
UpdateWorldState(EY_HORDE_BASE, m_TeamPointsCount[BG_TEAM_HORDE]);
|
||||
}
|
||||
|
||||
void BattleGroundEY::UpdatePointsIcons(uint32 Team, uint32 Point)
|
||||
{
|
||||
//we MUST firstly send 0, after that we can send 1!!!
|
||||
if (m_PointState[Point] == EY_POINT_UNDER_CONTROL)
|
||||
{
|
||||
UpdateWorldState(m_PointsIconStruct[Point].WorldStateControlIndex, 0);
|
||||
if (Team == ALLIANCE)
|
||||
UpdateWorldState(m_PointsIconStruct[Point].WorldStateAllianceControlledIndex, 1);
|
||||
else
|
||||
UpdateWorldState(m_PointsIconStruct[Point].WorldStateHordeControlledIndex, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Team == ALLIANCE)
|
||||
UpdateWorldState(m_PointsIconStruct[Point].WorldStateAllianceControlledIndex, 0);
|
||||
else
|
||||
UpdateWorldState(m_PointsIconStruct[Point].WorldStateHordeControlledIndex, 0);
|
||||
UpdateWorldState(m_PointsIconStruct[Point].WorldStateControlIndex, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void BattleGroundEY::AddPlayer(Player *plr)
|
||||
{
|
||||
BattleGround::AddPlayer(plr);
|
||||
//create score and add it to map
|
||||
BattleGroundEYScore* sc = new BattleGroundEYScore;
|
||||
|
||||
m_PlayersNearPoint[EY_POINTS_MAX].push_back(plr->GetGUID());
|
||||
|
||||
m_PlayerScores[plr->GetGUID()] = sc;
|
||||
}
|
||||
|
||||
void BattleGroundEY::RemovePlayer(Player *plr, uint64 guid)
|
||||
{
|
||||
// sometimes flag aura not removed :(
|
||||
for (int j = EY_POINTS_MAX; j >= 0; --j)
|
||||
{
|
||||
for (size_t i = 0; i < m_PlayersNearPoint[j].size(); ++i)
|
||||
if (m_PlayersNearPoint[j][i] == guid)
|
||||
m_PlayersNearPoint[j].erase(m_PlayersNearPoint[j].begin() + i);
|
||||
}
|
||||
if (IsFlagPickedup())
|
||||
{
|
||||
if (m_FlagKeeper == guid)
|
||||
{
|
||||
if (plr)
|
||||
EventPlayerDroppedFlag(plr);
|
||||
else
|
||||
{
|
||||
SetFlagPicker(0);
|
||||
RespawnFlag(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BattleGroundEY::HandleAreaTrigger(Player *Source, uint32 Trigger)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
if (!Source->isAlive()) //hack code, must be removed later
|
||||
return;
|
||||
|
||||
switch(Trigger)
|
||||
{
|
||||
case TR_BLOOD_ELF_POINT:
|
||||
if (m_PointState[BLOOD_ELF] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[BLOOD_ELF] == Source->GetTeam())
|
||||
if (m_FlagState && GetFlagPickerGUID() == Source->GetGUID())
|
||||
EventPlayerCapturedFlag(Source, BG_EY_OBJECT_FLAG_BLOOD_ELF);
|
||||
break;
|
||||
case TR_FEL_REALVER_POINT:
|
||||
if (m_PointState[FEL_REALVER] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[FEL_REALVER] == Source->GetTeam())
|
||||
if (m_FlagState && GetFlagPickerGUID() == Source->GetGUID())
|
||||
EventPlayerCapturedFlag(Source, BG_EY_OBJECT_FLAG_FEL_REALVER);
|
||||
break;
|
||||
case TR_MAGE_TOWER_POINT:
|
||||
if (m_PointState[MAGE_TOWER] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[MAGE_TOWER] == Source->GetTeam())
|
||||
if (m_FlagState && GetFlagPickerGUID() == Source->GetGUID())
|
||||
EventPlayerCapturedFlag(Source, BG_EY_OBJECT_FLAG_MAGE_TOWER);
|
||||
break;
|
||||
case TR_DRAENEI_RUINS_POINT:
|
||||
if (m_PointState[DRAENEI_RUINS] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[DRAENEI_RUINS] == Source->GetTeam())
|
||||
if (m_FlagState && GetFlagPickerGUID() == Source->GetGUID())
|
||||
EventPlayerCapturedFlag(Source, BG_EY_OBJECT_FLAG_DRAENEI_RUINS);
|
||||
break;
|
||||
case 4512:
|
||||
case 4515:
|
||||
case 4517:
|
||||
case 4519:
|
||||
case 4530:
|
||||
case 4531:
|
||||
case 4568:
|
||||
case 4569:
|
||||
case 4570:
|
||||
case 4571:
|
||||
case 5866:
|
||||
break;
|
||||
default:
|
||||
sLog.outError("WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger);
|
||||
Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool BattleGroundEY::SetupBattleGround()
|
||||
{
|
||||
// doors
|
||||
if (!AddObject(BG_EY_OBJECT_DOOR_A, BG_OBJECT_A_DOOR_EY_ENTRY, 2527.6f, 1596.91f, 1262.13f, -3.12414f, -0.173642f, -0.001515f, 0.98477f, -0.008594f, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_EY_OBJECT_DOOR_H, BG_OBJECT_H_DOOR_EY_ENTRY, 1803.21f, 1539.49f, 1261.09f, 3.14159f, 0.173648f, 0, 0.984808f, 0, RESPAWN_IMMEDIATELY)
|
||||
// banners (alliance)
|
||||
|| !AddObject(BG_EY_OBJECT_A_BANNER_FEL_REALVER_CENTER, BG_OBJECT_A_BANNER_EY_ENTRY, 2057.46f, 1735.07f, 1187.91f, -0.925024f, 0, 0, 0.446198f, -0.894934f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_A_BANNER_FEL_REALVER_LEFT, BG_OBJECT_A_BANNER_EY_ENTRY, 2032.25f, 1729.53f, 1190.33f, 1.8675f, 0, 0, 0.803857f, 0.594823f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_A_BANNER_FEL_REALVER_RIGHT, BG_OBJECT_A_BANNER_EY_ENTRY, 2092.35f, 1775.46f, 1187.08f, -0.401426f, 0, 0, 0.199368f, -0.979925f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_A_BANNER_BLOOD_ELF_CENTER, BG_OBJECT_A_BANNER_EY_ENTRY, 2047.19f, 1349.19f, 1189.0f, -1.62316f, 0, 0, 0.725374f, -0.688354f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_A_BANNER_BLOOD_ELF_LEFT, BG_OBJECT_A_BANNER_EY_ENTRY, 2074.32f, 1385.78f, 1194.72f, 0.488692f, 0, 0, 0.241922f, 0.970296f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_A_BANNER_BLOOD_ELF_RIGHT, BG_OBJECT_A_BANNER_EY_ENTRY, 2025.13f, 1386.12f, 1192.74f, 2.3911f, 0, 0, 0.930418f, 0.366501f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_A_BANNER_DRAENEI_RUINS_CENTER, BG_OBJECT_A_BANNER_EY_ENTRY, 2276.8f, 1400.41f, 1196.33f, 2.44346f, 0, 0, 0.939693f, 0.34202f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_A_BANNER_DRAENEI_RUINS_LEFT, BG_OBJECT_A_BANNER_EY_ENTRY, 2305.78f, 1404.56f, 1199.38f, 1.74533f, 0, 0, 0.766044f, 0.642788f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_A_BANNER_DRAENEI_RUINS_RIGHT, BG_OBJECT_A_BANNER_EY_ENTRY, 2245.4f, 1366.41f, 1195.28f, 2.21657f, 0, 0, 0.894934f, 0.446198f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_A_BANNER_MAGE_TOWER_CENTER, BG_OBJECT_A_BANNER_EY_ENTRY, 2270.84f, 1784.08f, 1186.76f, 2.42601f, 0, 0, 0.936672f, 0.350207f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_A_BANNER_MAGE_TOWER_LEFT, BG_OBJECT_A_BANNER_EY_ENTRY, 2269.13f, 1737.7f, 1186.66f, 0.994838f, 0, 0, 0.477159f, 0.878817f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_A_BANNER_MAGE_TOWER_RIGHT, BG_OBJECT_A_BANNER_EY_ENTRY, 2300.86f, 1741.25f, 1187.7f, -0.785398f, 0, 0, 0.382683f, -0.92388f, RESPAWN_ONE_DAY)
|
||||
// banners (horde)
|
||||
|| !AddObject(BG_EY_OBJECT_H_BANNER_FEL_REALVER_CENTER, BG_OBJECT_H_BANNER_EY_ENTRY, 2057.46f, 1735.07f, 1187.91f, -0.925024f, 0, 0, 0.446198f, -0.894934f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_H_BANNER_FEL_REALVER_LEFT, BG_OBJECT_H_BANNER_EY_ENTRY, 2032.25f, 1729.53f, 1190.33f, 1.8675f, 0, 0, 0.803857f, 0.594823f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_H_BANNER_FEL_REALVER_RIGHT, BG_OBJECT_H_BANNER_EY_ENTRY, 2092.35f, 1775.46f, 1187.08f, -0.401426f, 0, 0, 0.199368f, -0.979925f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_H_BANNER_BLOOD_ELF_CENTER, BG_OBJECT_H_BANNER_EY_ENTRY, 2047.19f, 1349.19f, 1189.0f, -1.62316f, 0, 0, 0.725374f, -0.688354f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_H_BANNER_BLOOD_ELF_LEFT, BG_OBJECT_H_BANNER_EY_ENTRY, 2074.32f, 1385.78f, 1194.72f, 0.488692f, 0, 0, 0.241922f, 0.970296f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_H_BANNER_BLOOD_ELF_RIGHT, BG_OBJECT_H_BANNER_EY_ENTRY, 2025.13f, 1386.12f, 1192.74f, 2.3911f, 0, 0, 0.930418f, 0.366501f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_H_BANNER_DRAENEI_RUINS_CENTER, BG_OBJECT_H_BANNER_EY_ENTRY, 2276.8f, 1400.41f, 1196.33f, 2.44346f, 0, 0, 0.939693f, 0.34202f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_H_BANNER_DRAENEI_RUINS_LEFT, BG_OBJECT_H_BANNER_EY_ENTRY, 2305.78f, 1404.56f, 1199.38f, 1.74533f, 0, 0, 0.766044f, 0.642788f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_H_BANNER_DRAENEI_RUINS_RIGHT, BG_OBJECT_H_BANNER_EY_ENTRY, 2245.4f, 1366.41f, 1195.28f, 2.21657f, 0, 0, 0.894934f, 0.446198f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_H_BANNER_MAGE_TOWER_CENTER, BG_OBJECT_H_BANNER_EY_ENTRY, 2270.84f, 1784.08f, 1186.76f, 2.42601f, 0, 0, 0.936672f, 0.350207f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_H_BANNER_MAGE_TOWER_LEFT, BG_OBJECT_H_BANNER_EY_ENTRY, 2269.13f, 1737.7f, 1186.66f, 0.994838f, 0, 0, 0.477159f, 0.878817f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_H_BANNER_MAGE_TOWER_RIGHT, BG_OBJECT_H_BANNER_EY_ENTRY, 2300.86f, 1741.25f, 1187.7f, -0.785398f, 0, 0, 0.382683f, -0.92388f, RESPAWN_ONE_DAY)
|
||||
// banners (natural)
|
||||
|| !AddObject(BG_EY_OBJECT_N_BANNER_FEL_REALVER_CENTER, BG_OBJECT_N_BANNER_EY_ENTRY, 2057.46f, 1735.07f, 1187.91f, -0.925024f, 0, 0, 0.446198f, -0.894934f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_N_BANNER_FEL_REALVER_LEFT, BG_OBJECT_N_BANNER_EY_ENTRY, 2032.25f, 1729.53f, 1190.33f, 1.8675f, 0, 0, 0.803857f, 0.594823f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_N_BANNER_FEL_REALVER_RIGHT, BG_OBJECT_N_BANNER_EY_ENTRY, 2092.35f, 1775.46f, 1187.08f, -0.401426f, 0, 0, 0.199368f, -0.979925f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_N_BANNER_BLOOD_ELF_CENTER, BG_OBJECT_N_BANNER_EY_ENTRY, 2047.19f, 1349.19f, 1189.0f, -1.62316f, 0, 0, 0.725374f, -0.688354f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_N_BANNER_BLOOD_ELF_LEFT, BG_OBJECT_N_BANNER_EY_ENTRY, 2074.32f, 1385.78f, 1194.72f, 0.488692f, 0, 0, 0.241922f, 0.970296f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_N_BANNER_BLOOD_ELF_RIGHT, BG_OBJECT_N_BANNER_EY_ENTRY, 2025.13f, 1386.12f, 1192.74f, 2.3911f, 0, 0, 0.930418f, 0.366501f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_N_BANNER_DRAENEI_RUINS_CENTER, BG_OBJECT_N_BANNER_EY_ENTRY, 2276.8f, 1400.41f, 1196.33f, 2.44346f, 0, 0, 0.939693f, 0.34202f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_N_BANNER_DRAENEI_RUINS_LEFT, BG_OBJECT_N_BANNER_EY_ENTRY, 2305.78f, 1404.56f, 1199.38f, 1.74533f, 0, 0, 0.766044f, 0.642788f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_N_BANNER_DRAENEI_RUINS_RIGHT, BG_OBJECT_N_BANNER_EY_ENTRY, 2245.4f, 1366.41f, 1195.28f, 2.21657f, 0, 0, 0.894934f, 0.446198f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_N_BANNER_MAGE_TOWER_CENTER, BG_OBJECT_N_BANNER_EY_ENTRY, 2270.84f, 1784.08f, 1186.76f, 2.42601f, 0, 0, 0.936672f, 0.350207f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_N_BANNER_MAGE_TOWER_LEFT, BG_OBJECT_N_BANNER_EY_ENTRY, 2269.13f, 1737.7f, 1186.66f, 0.994838f, 0, 0, 0.477159f, 0.878817f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_N_BANNER_MAGE_TOWER_RIGHT, BG_OBJECT_N_BANNER_EY_ENTRY, 2300.86f, 1741.25f, 1187.7f, -0.785398f, 0, 0, 0.382683f, -0.92388f, RESPAWN_ONE_DAY)
|
||||
// flags
|
||||
|| !AddObject(BG_EY_OBJECT_FLAG_NETHERSTORM, BG_OBJECT_FLAG2_EY_ENTRY, 2174.782227f, 1569.054688f, 1160.361938f, -1.448624f, 0, 0, 0.662620f, -0.748956f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_FLAG_FEL_REALVER, BG_OBJECT_FLAG1_EY_ENTRY, 2044.28f, 1729.68f, 1189.96f, -0.017453f, 0, 0, 0.008727f, -0.999962f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_FLAG_BLOOD_ELF, BG_OBJECT_FLAG1_EY_ENTRY, 2048.83f, 1393.65f, 1194.49f, 0.20944f, 0, 0, 0.104528f, 0.994522f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_FLAG_DRAENEI_RUINS, BG_OBJECT_FLAG1_EY_ENTRY, 2286.56f, 1402.36f, 1197.11f, 3.72381f, 0, 0, 0.957926f, -0.287016f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_FLAG_MAGE_TOWER, BG_OBJECT_FLAG1_EY_ENTRY, 2284.48f, 1731.23f, 1189.99f, 2.89725f, 0, 0, 0.992546f, 0.121869f, RESPAWN_ONE_DAY)
|
||||
// tower cap
|
||||
|| !AddObject(BG_EY_OBJECT_TOWER_CAP_FEL_REALVER, BG_OBJECT_FR_TOWER_CAP_EY_ENTRY, 2024.600708f, 1742.819580f, 1195.157715f, 2.443461f, 0, 0, 0.939693f, 0.342020f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_TOWER_CAP_BLOOD_ELF, BG_OBJECT_BE_TOWER_CAP_EY_ENTRY, 2050.493164f, 1372.235962f, 1194.563477f, 1.710423f, 0, 0, 0.754710f, 0.656059f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_TOWER_CAP_DRAENEI_RUINS, BG_OBJECT_DR_TOWER_CAP_EY_ENTRY, 2301.010498f, 1386.931641f, 1197.183472f, 1.570796f, 0, 0, 0.707107f, 0.707107f, RESPAWN_ONE_DAY)
|
||||
|| !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)
|
||||
)
|
||||
{
|
||||
sLog.outErrorDb("BatteGroundEY: Failed to spawn some object BattleGround not created!");
|
||||
return false;
|
||||
}
|
||||
|
||||
//buffs
|
||||
for (int i = 0; i < EY_POINTS_MAX; ++i)
|
||||
{
|
||||
AreaTriggerEntry const* at = sAreaTriggerStore.LookupEntry(m_Points_Trigger[i]);
|
||||
if (!at)
|
||||
{
|
||||
sLog.outError("BattleGroundEY: Unknown trigger: %u", m_Points_Trigger[i]);
|
||||
continue;
|
||||
}
|
||||
if (!AddObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REALVER + i * 3, Buff_Entries[0], at->x, at->y, at->z, 0.907571f, 0, 0, 0.438371f, 0.898794f, RESPAWN_ONE_DAY)
|
||||
|| !AddObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REALVER + 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_REALVER + i * 3 + 2, Buff_Entries[2], at->x, at->y, at->z, 0.907571f, 0, 0, 0.438371f, 0.898794f, RESPAWN_ONE_DAY)
|
||||
)
|
||||
sLog.outError("BattleGroundEY: Cannot spawn buff");
|
||||
}
|
||||
|
||||
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, ALLIANCE))
|
||||
{
|
||||
sLog.outErrorDb("BatteGroundEY: Failed to spawn spirit guide! BattleGround 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, HORDE))
|
||||
{
|
||||
sLog.outErrorDb("BatteGroundEY: Failed to spawn spirit guide! BattleGround not created!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BattleGroundEY::Reset()
|
||||
{
|
||||
//call parent's class reset
|
||||
BattleGround::Reset();
|
||||
|
||||
m_TeamScores[BG_TEAM_ALLIANCE] = 0;
|
||||
m_TeamScores[BG_TEAM_HORDE] = 0;
|
||||
m_TeamPointsCount[BG_TEAM_ALLIANCE] = 0;
|
||||
m_TeamPointsCount[BG_TEAM_HORDE] = 0;
|
||||
m_HonorScoreTics[BG_TEAM_ALLIANCE] = 0;
|
||||
m_HonorScoreTics[BG_TEAM_HORDE] = 0;
|
||||
m_FlagState = BG_EY_FLAG_STATE_ON_BASE;
|
||||
m_FlagCapturedBgObjectType = 0;
|
||||
m_FlagKeeper = 0;
|
||||
m_DroppedFlagGUID = 0;
|
||||
m_PointAddingTimer = 0;
|
||||
m_TowerCapCheckTimer = 0;
|
||||
bool isBGWeekend = sBattleGroundMgr.IsBGWeekend(GetTypeID());
|
||||
m_HonorTics = (isBGWeekend) ? BG_EY_EYWeekendHonorTicks : BG_EY_NotEYWeekendHonorTicks;
|
||||
|
||||
for (uint8 i = 0; i < EY_POINTS_MAX; ++i)
|
||||
{
|
||||
m_PointOwnedByTeam[i] = EY_POINT_NO_OWNER;
|
||||
m_PointState[i] = EY_POINT_STATE_UNCONTROLLED;
|
||||
m_PointBarStatus[i] = BG_EY_PROGRESS_BAR_STATE_MIDDLE;
|
||||
m_PlayersNearPoint[i].clear();
|
||||
m_PlayersNearPoint[i].reserve(15); //tip size
|
||||
}
|
||||
m_PlayersNearPoint[EY_PLAYERS_OUT_OF_POINTS].clear();
|
||||
m_PlayersNearPoint[EY_PLAYERS_OUT_OF_POINTS].reserve(30);
|
||||
}
|
||||
|
||||
void BattleGroundEY::RespawnFlag(bool send_message)
|
||||
{
|
||||
if (m_FlagCapturedBgObjectType > 0)
|
||||
SpawnBGObject(m_FlagCapturedBgObjectType, RESPAWN_ONE_DAY);
|
||||
|
||||
m_FlagCapturedBgObjectType = 0;
|
||||
m_FlagState = BG_EY_FLAG_STATE_ON_BASE;
|
||||
SpawnBGObject(BG_EY_OBJECT_FLAG_NETHERSTORM, RESPAWN_IMMEDIATELY);
|
||||
|
||||
if (send_message)
|
||||
{
|
||||
SendMessageToAll(LANG_BG_EY_RESETED_FLAG, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
PlaySoundToAll(BG_EY_SOUND_FLAG_RESET); // flags respawned sound...
|
||||
}
|
||||
|
||||
UpdateWorldState(NETHERSTORM_FLAG, 1);
|
||||
}
|
||||
|
||||
void BattleGroundEY::RespawnFlagAfterDrop()
|
||||
{
|
||||
RespawnFlag(true);
|
||||
|
||||
GameObject *obj = HashMapHolder<GameObject>::Find(GetDroppedFlagGUID());
|
||||
if (obj)
|
||||
obj->Delete();
|
||||
else
|
||||
sLog.outError("BattleGroundEY: Unknown dropped flag guid: %u",GUID_LOPART(GetDroppedFlagGUID()));
|
||||
|
||||
SetDroppedFlagGUID(0);
|
||||
}
|
||||
|
||||
void BattleGroundEY::HandleKillPlayer(Player *player, Player *killer)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
BattleGround::HandleKillPlayer(player, killer);
|
||||
EventPlayerDroppedFlag(player);
|
||||
}
|
||||
|
||||
void BattleGroundEY::EventPlayerDroppedFlag(Player *Source)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
{
|
||||
// if not running, do not cast things at the dropper player, neither send unnecessary messages
|
||||
// just take off the aura
|
||||
if (IsFlagPickedup() && GetFlagPickerGUID() == Source->GetGUID())
|
||||
{
|
||||
SetFlagPicker(0);
|
||||
Source->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsFlagPickedup())
|
||||
return;
|
||||
|
||||
if (GetFlagPickerGUID() != Source->GetGUID())
|
||||
return;
|
||||
|
||||
SetFlagPicker(0);
|
||||
Source->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL);
|
||||
m_FlagState = BG_EY_FLAG_STATE_ON_GROUND;
|
||||
m_FlagsTimer = BG_EY_FLAG_RESPAWN_TIME;
|
||||
Source->CastSpell(Source, SPELL_RECENTLY_DROPPED_FLAG, true);
|
||||
Source->CastSpell(Source, BG_EY_PLAYER_DROPPED_FLAG_SPELL, true);
|
||||
//this does not work correctly :((it should remove flag carrier name)
|
||||
UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_WAIT_RESPAWN);
|
||||
UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_WAIT_RESPAWN);
|
||||
|
||||
if (Source->GetTeam() == ALLIANCE)
|
||||
SendMessageToAll(LANG_BG_EY_DROPPED_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, NULL);
|
||||
else
|
||||
SendMessageToAll(LANG_BG_EY_DROPPED_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, NULL);
|
||||
}
|
||||
|
||||
void BattleGroundEY::EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS || IsFlagPickedup() || !Source->IsWithinDistInMap(target_obj, 10))
|
||||
return;
|
||||
|
||||
if (Source->GetTeam() == ALLIANCE)
|
||||
{
|
||||
UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_ON_PLAYER);
|
||||
PlaySoundToAll(BG_EY_SOUND_FLAG_PICKED_UP_ALLIANCE);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_ON_PLAYER);
|
||||
PlaySoundToAll(BG_EY_SOUND_FLAG_PICKED_UP_HORDE);
|
||||
}
|
||||
|
||||
if (m_FlagState == BG_EY_FLAG_STATE_ON_BASE)
|
||||
UpdateWorldState(NETHERSTORM_FLAG, 0);
|
||||
m_FlagState = BG_EY_FLAG_STATE_ON_PLAYER;
|
||||
|
||||
SpawnBGObject(BG_EY_OBJECT_FLAG_NETHERSTORM, RESPAWN_ONE_DAY);
|
||||
SetFlagPicker(Source->GetGUID());
|
||||
//get flag aura on player
|
||||
Source->CastSpell(Source, BG_EY_NETHERSTORM_FLAG_SPELL, true);
|
||||
Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
|
||||
|
||||
if (Source->GetTeam() == ALLIANCE)
|
||||
PSendMessageToAll(LANG_BG_EY_HAS_TAKEN_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, NULL, Source->GetName());
|
||||
else
|
||||
PSendMessageToAll(LANG_BG_EY_HAS_TAKEN_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, NULL, Source->GetName());
|
||||
}
|
||||
|
||||
void BattleGroundEY::EventTeamLostPoint(Player *Source, uint32 Point)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
//Natural point
|
||||
uint32 Team = m_PointOwnedByTeam[Point];
|
||||
|
||||
if (!Team)
|
||||
return;
|
||||
|
||||
if (Team == ALLIANCE)
|
||||
{
|
||||
m_TeamPointsCount[BG_TEAM_ALLIANCE]--;
|
||||
SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeAlliance, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeAlliance + 1, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeAlliance + 2, RESPAWN_ONE_DAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_TeamPointsCount[BG_TEAM_HORDE]--;
|
||||
SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeHorde, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeHorde + 1, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeHorde + 2, RESPAWN_ONE_DAY);
|
||||
}
|
||||
|
||||
SpawnBGObject(m_LoosingPointTypes[Point].SpawnNeutralObjectType, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_LoosingPointTypes[Point].SpawnNeutralObjectType + 1, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_LoosingPointTypes[Point].SpawnNeutralObjectType + 2, RESPAWN_IMMEDIATELY);
|
||||
|
||||
//buff isn't despawned
|
||||
|
||||
m_PointOwnedByTeam[Point] = EY_POINT_NO_OWNER;
|
||||
m_PointState[Point] = EY_POINT_NO_OWNER;
|
||||
|
||||
if (Team == ALLIANCE)
|
||||
SendMessageToAll(m_LoosingPointTypes[Point].MessageIdAlliance,CHAT_MSG_BG_SYSTEM_ALLIANCE, Source);
|
||||
else
|
||||
SendMessageToAll(m_LoosingPointTypes[Point].MessageIdHorde,CHAT_MSG_BG_SYSTEM_HORDE, Source);
|
||||
|
||||
UpdatePointsIcons(Team, Point);
|
||||
UpdatePointsCount(Team);
|
||||
|
||||
//remove bonus honor aura trigger creature when node is lost
|
||||
if (Point < EY_POINTS_MAX)
|
||||
DelCreature(Point + 6);//NULL checks are in DelCreature! 0-5 spirit guides
|
||||
}
|
||||
|
||||
void BattleGroundEY::EventTeamCapturedPoint(Player *Source, uint32 Point)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
uint32 Team = Source->GetTeam();
|
||||
|
||||
SpawnBGObject(m_CapturingPointTypes[Point].DespawnNeutralObjectType, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_CapturingPointTypes[Point].DespawnNeutralObjectType + 1, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_CapturingPointTypes[Point].DespawnNeutralObjectType + 2, RESPAWN_ONE_DAY);
|
||||
|
||||
if (Team == ALLIANCE)
|
||||
{
|
||||
m_TeamPointsCount[BG_TEAM_ALLIANCE]++;
|
||||
SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeAlliance, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeAlliance + 1, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeAlliance + 2, RESPAWN_IMMEDIATELY);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_TeamPointsCount[BG_TEAM_HORDE]++;
|
||||
SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeHorde, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeHorde + 1, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeHorde + 2, RESPAWN_IMMEDIATELY);
|
||||
}
|
||||
|
||||
//buff isn't respawned
|
||||
|
||||
m_PointOwnedByTeam[Point] = Team;
|
||||
m_PointState[Point] = EY_POINT_UNDER_CONTROL;
|
||||
|
||||
if (Team == ALLIANCE)
|
||||
SendMessageToAll(m_CapturingPointTypes[Point].MessageIdAlliance,CHAT_MSG_BG_SYSTEM_ALLIANCE, Source);
|
||||
else
|
||||
SendMessageToAll(m_CapturingPointTypes[Point].MessageIdHorde,CHAT_MSG_BG_SYSTEM_HORDE, Source);
|
||||
|
||||
if (m_BgCreatures[Point])
|
||||
DelCreature(Point);
|
||||
|
||||
WorldSafeLocsEntry const *sg = NULL;
|
||||
sg = sWorldSafeLocsStore.LookupEntry(m_CapturingPointTypes[Point].GraveYardId);
|
||||
if (!sg || !AddSpiritGuide(Point, sg->x, sg->y, sg->z, 3.124139f, Team))
|
||||
sLog.outError("BatteGroundEY: Failed to spawn spirit guide! point: %u, team: %u, graveyard_id: %u",
|
||||
Point, Team, m_CapturingPointTypes[Point].GraveYardId);
|
||||
|
||||
// SpawnBGCreature(Point,RESPAWN_IMMEDIATELY);
|
||||
|
||||
UpdatePointsIcons(Team, Point);
|
||||
UpdatePointsCount(Team);
|
||||
|
||||
if (Point >= EY_POINTS_MAX)
|
||||
return;
|
||||
|
||||
Creature* trigger = GetBGCreature(Point + 6);//0-5 spirit guides
|
||||
if (!trigger)
|
||||
trigger = AddCreature(WORLD_TRIGGER,Point+6,Team,BG_EY_TriggerPositions[Point][0],BG_EY_TriggerPositions[Point][1],BG_EY_TriggerPositions[Point][2],BG_EY_TriggerPositions[Point][3]);
|
||||
|
||||
//add bonus honor aura trigger creature when node is accupied
|
||||
//cast bonus aura (+50% honor in 25yards)
|
||||
//aura should only apply to players who have accupied the node, set correct faction for trigger
|
||||
if (trigger)
|
||||
{
|
||||
trigger->setFaction(Team == ALLIANCE ? 84 : 83);
|
||||
trigger->CastSpell(trigger, SPELL_HONORABLE_DEFENDER_25Y, false);
|
||||
}
|
||||
}
|
||||
|
||||
void BattleGroundEY::EventPlayerCapturedFlag(Player *Source, uint32 BgObjectType)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS || GetFlagPickerGUID() != Source->GetGUID())
|
||||
return;
|
||||
|
||||
SetFlagPicker(0);
|
||||
m_FlagState = BG_EY_FLAG_STATE_WAIT_RESPAWN;
|
||||
Source->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL);
|
||||
|
||||
Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
|
||||
|
||||
if (Source->GetTeam() == ALLIANCE)
|
||||
PlaySoundToAll(BG_EY_SOUND_FLAG_CAPTURED_ALLIANCE);
|
||||
else
|
||||
PlaySoundToAll(BG_EY_SOUND_FLAG_CAPTURED_HORDE);
|
||||
|
||||
SpawnBGObject(BgObjectType, RESPAWN_IMMEDIATELY);
|
||||
|
||||
m_FlagsTimer = BG_EY_FLAG_RESPAWN_TIME;
|
||||
m_FlagCapturedBgObjectType = BgObjectType;
|
||||
|
||||
uint8 team_id = 0;
|
||||
if (Source->GetTeam() == ALLIANCE)
|
||||
{
|
||||
team_id = BG_TEAM_ALLIANCE;
|
||||
SendMessageToAll(LANG_BG_EY_CAPTURED_FLAG_A, CHAT_MSG_BG_SYSTEM_ALLIANCE, Source);
|
||||
}
|
||||
else
|
||||
{
|
||||
team_id = BG_TEAM_HORDE;
|
||||
SendMessageToAll(LANG_BG_EY_CAPTURED_FLAG_H, CHAT_MSG_BG_SYSTEM_HORDE, Source);
|
||||
}
|
||||
|
||||
if (m_TeamPointsCount[team_id] > 0)
|
||||
AddPoints(Source->GetTeam(), BG_EY_FlagPoints[m_TeamPointsCount[team_id] - 1]);
|
||||
|
||||
UpdatePlayerScore(Source, SCORE_FLAG_CAPTURES, 1);
|
||||
}
|
||||
|
||||
void BattleGroundEY::UpdatePlayerScore(Player *Source, uint32 type, uint32 value, bool doAddHonor)
|
||||
{
|
||||
BattleGroundScoreMap::iterator itr = m_PlayerScores.find(Source->GetGUID());
|
||||
if (itr == m_PlayerScores.end()) // player not found
|
||||
return;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case SCORE_FLAG_CAPTURES: // flags captured
|
||||
((BattleGroundEYScore*)itr->second)->FlagCaptures += value;
|
||||
break;
|
||||
default:
|
||||
BattleGround::UpdatePlayerScore(Source, type, value, doAddHonor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void BattleGroundEY::FillInitialWorldStates(WorldPacket& data)
|
||||
{
|
||||
data << uint32(EY_HORDE_BASE) << uint32(m_TeamPointsCount[BG_TEAM_HORDE]);
|
||||
data << uint32(EY_ALLIANCE_BASE) << uint32(m_TeamPointsCount[BG_TEAM_ALLIANCE]);
|
||||
data << uint32(0xab6) << uint32(0x0);
|
||||
data << uint32(0xab5) << uint32(0x0);
|
||||
data << uint32(0xab4) << uint32(0x0);
|
||||
data << uint32(0xab3) << uint32(0x0);
|
||||
data << uint32(0xab2) << uint32(0x0);
|
||||
data << uint32(0xab1) << uint32(0x0);
|
||||
data << uint32(0xab0) << uint32(0x0);
|
||||
data << uint32(0xaaf) << uint32(0x0);
|
||||
|
||||
data << uint32(DRAENEI_RUINS_HORDE_CONTROL) << uint32(m_PointOwnedByTeam[DRAENEI_RUINS] == HORDE && m_PointState[DRAENEI_RUINS] == EY_POINT_UNDER_CONTROL);
|
||||
|
||||
data << uint32(DRAENEI_RUINS_ALLIANCE_CONTROL) << uint32(m_PointOwnedByTeam[DRAENEI_RUINS] == ALLIANCE && m_PointState[DRAENEI_RUINS] == EY_POINT_UNDER_CONTROL);
|
||||
|
||||
data << uint32(DRAENEI_RUINS_UNCONTROL) << uint32(m_PointState[DRAENEI_RUINS] != EY_POINT_UNDER_CONTROL);
|
||||
|
||||
data << uint32(MAGE_TOWER_ALLIANCE_CONTROL) << uint32(m_PointOwnedByTeam[MAGE_TOWER] == ALLIANCE && m_PointState[MAGE_TOWER] == EY_POINT_UNDER_CONTROL);
|
||||
|
||||
data << uint32(MAGE_TOWER_HORDE_CONTROL) << uint32(m_PointOwnedByTeam[MAGE_TOWER] == HORDE && m_PointState[MAGE_TOWER] == EY_POINT_UNDER_CONTROL);
|
||||
|
||||
data << uint32(MAGE_TOWER_UNCONTROL) << uint32(m_PointState[MAGE_TOWER] != EY_POINT_UNDER_CONTROL);
|
||||
|
||||
data << uint32(FEL_REAVER_HORDE_CONTROL) << uint32(m_PointOwnedByTeam[FEL_REALVER] == HORDE && m_PointState[FEL_REALVER] == EY_POINT_UNDER_CONTROL);
|
||||
|
||||
data << uint32(FEL_REAVER_ALLIANCE_CONTROL) << uint32(m_PointOwnedByTeam[FEL_REALVER] == ALLIANCE && m_PointState[FEL_REALVER] == EY_POINT_UNDER_CONTROL);
|
||||
|
||||
data << uint32(FEL_REAVER_UNCONTROL) << uint32(m_PointState[FEL_REALVER] != EY_POINT_UNDER_CONTROL);
|
||||
|
||||
data << uint32(BLOOD_ELF_HORDE_CONTROL) << uint32(m_PointOwnedByTeam[BLOOD_ELF] == HORDE && m_PointState[BLOOD_ELF] == EY_POINT_UNDER_CONTROL);
|
||||
|
||||
data << uint32(BLOOD_ELF_ALLIANCE_CONTROL) << uint32(m_PointOwnedByTeam[BLOOD_ELF] == ALLIANCE && m_PointState[BLOOD_ELF] == EY_POINT_UNDER_CONTROL);
|
||||
|
||||
data << uint32(BLOOD_ELF_UNCONTROL) << uint32(m_PointState[BLOOD_ELF] != EY_POINT_UNDER_CONTROL);
|
||||
|
||||
data << uint32(NETHERSTORM_FLAG) << uint32(m_FlagState == BG_EY_FLAG_STATE_ON_BASE);
|
||||
|
||||
data << uint32(0xad2) << uint32(0x1);
|
||||
data << uint32(0xad1) << uint32(0x1);
|
||||
data << uint32(0xabe) << uint32(GetTeamScore(HORDE));
|
||||
data << uint32(0xabd) << uint32(GetTeamScore(ALLIANCE));
|
||||
data << uint32(0xa05) << uint32(0x8e);
|
||||
data << uint32(0xaa0) << uint32(0x0);
|
||||
data << uint32(0xa9f) << uint32(0x0);
|
||||
data << uint32(0xa9e) << uint32(0x0);
|
||||
data << uint32(0xc0d) << uint32(0x17b);
|
||||
}
|
||||
|
||||
WorldSafeLocsEntry const *BattleGroundEY::GetClosestGraveYard(Player* player)
|
||||
{
|
||||
uint32 g_id = 0;
|
||||
|
||||
switch(player->GetTeam())
|
||||
{
|
||||
case ALLIANCE: g_id = EY_GRAVEYARD_MAIN_ALLIANCE; break;
|
||||
case HORDE: g_id = EY_GRAVEYARD_MAIN_HORDE; break;
|
||||
default: return NULL;
|
||||
}
|
||||
|
||||
float distance, nearestDistance;
|
||||
|
||||
WorldSafeLocsEntry const* entry = NULL;
|
||||
WorldSafeLocsEntry const* nearestEntry = NULL;
|
||||
entry = sWorldSafeLocsStore.LookupEntry(g_id);
|
||||
nearestEntry = entry;
|
||||
|
||||
if (!entry)
|
||||
{
|
||||
sLog.outError("BattleGroundEY: Not found the main team graveyard. Graveyard system isn't working!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
float plr_x = player->GetPositionX();
|
||||
float plr_y = player->GetPositionY();
|
||||
float plr_z = player->GetPositionZ();
|
||||
|
||||
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);
|
||||
nearestDistance = distance;
|
||||
|
||||
for (uint8 i = 0; i < EY_POINTS_MAX; ++i)
|
||||
{
|
||||
if (m_PointOwnedByTeam[i] == player->GetTeam() && m_PointState[i] == EY_POINT_UNDER_CONTROL)
|
||||
{
|
||||
entry = sWorldSafeLocsStore.LookupEntry(m_CapturingPointTypes[i].GraveYardId);
|
||||
if (!entry)
|
||||
sLog.outError("BattleGroundEY: Not found graveyard: %u",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);
|
||||
if (distance < nearestDistance)
|
||||
{
|
||||
nearestDistance = distance;
|
||||
nearestEntry = entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nearestEntry;
|
||||
}
|
||||
|
||||
bool BattleGroundEY::IsAllNodesConrolledByTeam(uint32 team) const
|
||||
{
|
||||
uint32 count = 0;
|
||||
for (int i = 0; i < EY_POINTS_MAX; ++i)
|
||||
if (m_PointOwnedByTeam[i] == team && m_PointState[i] == EY_POINT_UNDER_CONTROL)
|
||||
++count;
|
||||
|
||||
return count == EY_POINTS_MAX;
|
||||
}
|
||||
@@ -0,0 +1,410 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __BATTLEGROUNDEY_H
|
||||
#define __BATTLEGROUNDEY_H
|
||||
|
||||
#include "Language.h"
|
||||
|
||||
class BattleGround;
|
||||
|
||||
#define BG_EY_FLAG_RESPAWN_TIME (8*IN_MILISECONDS) //8 seconds
|
||||
#define BG_EY_FPOINTS_TICK_TIME (2*IN_MILISECONDS) //2 seconds
|
||||
|
||||
enum BG_EY_WorldStates
|
||||
{
|
||||
EY_ALLIANCE_RESOURCES = 2749,
|
||||
EY_HORDE_RESOURCES = 2750,
|
||||
EY_ALLIANCE_BASE = 2752,
|
||||
EY_HORDE_BASE = 2753,
|
||||
DRAENEI_RUINS_HORDE_CONTROL = 2733,
|
||||
DRAENEI_RUINS_ALLIANCE_CONTROL = 2732,
|
||||
DRAENEI_RUINS_UNCONTROL = 2731,
|
||||
MAGE_TOWER_ALLIANCE_CONTROL = 2730,
|
||||
MAGE_TOWER_HORDE_CONTROL = 2729,
|
||||
MAGE_TOWER_UNCONTROL = 2728,
|
||||
FEL_REAVER_HORDE_CONTROL = 2727,
|
||||
FEL_REAVER_ALLIANCE_CONTROL = 2726,
|
||||
FEL_REAVER_UNCONTROL = 2725,
|
||||
BLOOD_ELF_HORDE_CONTROL = 2724,
|
||||
BLOOD_ELF_ALLIANCE_CONTROL = 2723,
|
||||
BLOOD_ELF_UNCONTROL = 2722,
|
||||
PROGRESS_BAR_PERCENT_GREY = 2720, //100 = empty (only grey), 0 = blue|red (no grey)
|
||||
PROGRESS_BAR_STATUS = 2719, //50 init!, 48 ... hordak bere .. 33 .. 0 = full 100% hordacky , 100 = full alliance
|
||||
PROGRESS_BAR_SHOW = 2718, //1 init, 0 druhy send - bez messagu, 1 = controlled aliance
|
||||
NETHERSTORM_FLAG = 2757,
|
||||
//set to 2 when flag is picked up, and to 1 if it is dropped
|
||||
NETHERSTORM_FLAG_STATE_ALLIANCE = 2769,
|
||||
NETHERSTORM_FLAG_STATE_HORDE = 2770
|
||||
};
|
||||
|
||||
enum BG_EY_ProgressBarConsts
|
||||
{
|
||||
BG_EY_POINT_MAX_CAPTURERS_COUNT = 5,
|
||||
BG_EY_POINT_RADIUS = 70,
|
||||
BG_EY_PROGRESS_BAR_DONT_SHOW = 0,
|
||||
BG_EY_PROGRESS_BAR_SHOW = 1,
|
||||
BG_EY_PROGRESS_BAR_PERCENT_GREY = 40,
|
||||
BG_EY_PROGRESS_BAR_STATE_MIDDLE = 50,
|
||||
BG_EY_PROGRESS_BAR_HORDE_CONTROLLED = 0,
|
||||
BG_EY_PROGRESS_BAR_NEUTRAL_LOW = 30,
|
||||
BG_EY_PROGRESS_BAR_NEUTRAL_HIGH = 70,
|
||||
BG_EY_PROGRESS_BAR_ALI_CONTROLLED = 100
|
||||
};
|
||||
|
||||
enum BG_EY_Sounds
|
||||
{
|
||||
//strange ids, but sure about them
|
||||
BG_EY_SOUND_FLAG_PICKED_UP_ALLIANCE = 8212,
|
||||
BG_EY_SOUND_FLAG_CAPTURED_HORDE = 8213,
|
||||
BG_EY_SOUND_FLAG_PICKED_UP_HORDE = 8174,
|
||||
BG_EY_SOUND_FLAG_CAPTURED_ALLIANCE = 8173,
|
||||
BG_EY_SOUND_FLAG_RESET = 8192
|
||||
};
|
||||
|
||||
enum BG_EY_Spells
|
||||
{
|
||||
BG_EY_NETHERSTORM_FLAG_SPELL = 34976,
|
||||
BG_EY_PLAYER_DROPPED_FLAG_SPELL = 34991
|
||||
};
|
||||
|
||||
enum EYBattleGroundObjectEntry
|
||||
{
|
||||
BG_OBJECT_A_DOOR_EY_ENTRY = 184719, //Alliance door
|
||||
BG_OBJECT_H_DOOR_EY_ENTRY = 184720, //Horde door
|
||||
BG_OBJECT_FLAG1_EY_ENTRY = 184493, //Netherstorm flag (generic)
|
||||
BG_OBJECT_FLAG2_EY_ENTRY = 184141, //Netherstorm flag (flagstand)
|
||||
BG_OBJECT_FLAG3_EY_ENTRY = 184142, //Netherstorm flag (flagdrop)
|
||||
BG_OBJECT_A_BANNER_EY_ENTRY = 184381, //Visual Banner (Alliance)
|
||||
BG_OBJECT_H_BANNER_EY_ENTRY = 184380, //Visual Banner (Horde)
|
||||
BG_OBJECT_N_BANNER_EY_ENTRY = 184382, //Visual Banner (Neutral)
|
||||
BG_OBJECT_BE_TOWER_CAP_EY_ENTRY = 184080, //BE Tower Cap Pt
|
||||
BG_OBJECT_FR_TOWER_CAP_EY_ENTRY = 184081, //Fel Reaver Cap Pt
|
||||
BG_OBJECT_HU_TOWER_CAP_EY_ENTRY = 184082, //Human Tower Cap Pt
|
||||
BG_OBJECT_DR_TOWER_CAP_EY_ENTRY = 184083 //Draenei Tower Cap Pt
|
||||
};
|
||||
|
||||
enum EYBattleGroundPointsTrigger
|
||||
{
|
||||
TR_BLOOD_ELF_POINT = 4476,
|
||||
TR_FEL_REALVER_POINT = 4514,
|
||||
TR_MAGE_TOWER_POINT = 4516,
|
||||
TR_DRAENEI_RUINS_POINT = 4518,
|
||||
TR_BLOOD_ELF_BUFF = 4568,
|
||||
TR_FEL_REALVER_BUFF = 4569,
|
||||
TR_MAGE_TOWER_BUFF = 4570,
|
||||
TR_DRAENEI_RUINS_BUFF = 4571
|
||||
};
|
||||
|
||||
enum EYBattleGroundGaveyards
|
||||
{
|
||||
EY_GRAVEYARD_MAIN_ALLIANCE = 1103,
|
||||
EY_GRAVEYARD_MAIN_HORDE = 1104,
|
||||
EY_GRAVEYARD_FEL_REALVER = 1105,
|
||||
EY_GRAVEYARD_BLOOD_ELF = 1106,
|
||||
EY_GRAVEYARD_DRAENEI_RUINS = 1107,
|
||||
EY_GRAVEYARD_MAGE_TOWER = 1108
|
||||
};
|
||||
|
||||
enum EYBattleGroundPoints
|
||||
{
|
||||
FEL_REALVER = 0,
|
||||
BLOOD_ELF = 1,
|
||||
DRAENEI_RUINS = 2,
|
||||
MAGE_TOWER = 3,
|
||||
|
||||
EY_PLAYERS_OUT_OF_POINTS = 4,
|
||||
EY_POINTS_MAX = 4
|
||||
};
|
||||
|
||||
enum EYBattleGroundCreaturesTypes
|
||||
{
|
||||
EY_SPIRIT_FEL_REALVER = 0,
|
||||
EY_SPIRIT_BLOOD_ELF = 1,
|
||||
EY_SPIRIT_DRAENEI_RUINS = 2,
|
||||
EY_SPIRIT_MAGE_TOWER = 3,
|
||||
EY_SPIRIT_MAIN_ALLIANCE = 4,
|
||||
EY_SPIRIT_MAIN_HORDE = 5,
|
||||
|
||||
EY_TRIGGER_FEL_REALVER = 6,
|
||||
EY_TRIGGER_BLOOD_ELF = 7,
|
||||
EY_TRIGGER_DRAENEI_RUINS = 8,
|
||||
EY_TRIGGER_MAGE_TOWER = 9,
|
||||
|
||||
BG_EY_CREATURES_MAX = 10
|
||||
};
|
||||
|
||||
enum EYBattleGroundObjectTypes
|
||||
{
|
||||
BG_EY_OBJECT_DOOR_A = 0,
|
||||
BG_EY_OBJECT_DOOR_H = 1,
|
||||
BG_EY_OBJECT_A_BANNER_FEL_REALVER_CENTER = 2,
|
||||
BG_EY_OBJECT_A_BANNER_FEL_REALVER_LEFT = 3,
|
||||
BG_EY_OBJECT_A_BANNER_FEL_REALVER_RIGHT = 4,
|
||||
BG_EY_OBJECT_A_BANNER_BLOOD_ELF_CENTER = 5,
|
||||
BG_EY_OBJECT_A_BANNER_BLOOD_ELF_LEFT = 6,
|
||||
BG_EY_OBJECT_A_BANNER_BLOOD_ELF_RIGHT = 7,
|
||||
BG_EY_OBJECT_A_BANNER_DRAENEI_RUINS_CENTER = 8,
|
||||
BG_EY_OBJECT_A_BANNER_DRAENEI_RUINS_LEFT = 9,
|
||||
BG_EY_OBJECT_A_BANNER_DRAENEI_RUINS_RIGHT = 10,
|
||||
BG_EY_OBJECT_A_BANNER_MAGE_TOWER_CENTER = 11,
|
||||
BG_EY_OBJECT_A_BANNER_MAGE_TOWER_LEFT = 12,
|
||||
BG_EY_OBJECT_A_BANNER_MAGE_TOWER_RIGHT = 13,
|
||||
BG_EY_OBJECT_H_BANNER_FEL_REALVER_CENTER = 14,
|
||||
BG_EY_OBJECT_H_BANNER_FEL_REALVER_LEFT = 15,
|
||||
BG_EY_OBJECT_H_BANNER_FEL_REALVER_RIGHT = 16,
|
||||
BG_EY_OBJECT_H_BANNER_BLOOD_ELF_CENTER = 17,
|
||||
BG_EY_OBJECT_H_BANNER_BLOOD_ELF_LEFT = 18,
|
||||
BG_EY_OBJECT_H_BANNER_BLOOD_ELF_RIGHT = 19,
|
||||
BG_EY_OBJECT_H_BANNER_DRAENEI_RUINS_CENTER = 20,
|
||||
BG_EY_OBJECT_H_BANNER_DRAENEI_RUINS_LEFT = 21,
|
||||
BG_EY_OBJECT_H_BANNER_DRAENEI_RUINS_RIGHT = 22,
|
||||
BG_EY_OBJECT_H_BANNER_MAGE_TOWER_CENTER = 23,
|
||||
BG_EY_OBJECT_H_BANNER_MAGE_TOWER_LEFT = 24,
|
||||
BG_EY_OBJECT_H_BANNER_MAGE_TOWER_RIGHT = 25,
|
||||
BG_EY_OBJECT_N_BANNER_FEL_REALVER_CENTER = 26,
|
||||
BG_EY_OBJECT_N_BANNER_FEL_REALVER_LEFT = 27,
|
||||
BG_EY_OBJECT_N_BANNER_FEL_REALVER_RIGHT = 28,
|
||||
BG_EY_OBJECT_N_BANNER_BLOOD_ELF_CENTER = 29,
|
||||
BG_EY_OBJECT_N_BANNER_BLOOD_ELF_LEFT = 30,
|
||||
BG_EY_OBJECT_N_BANNER_BLOOD_ELF_RIGHT = 31,
|
||||
BG_EY_OBJECT_N_BANNER_DRAENEI_RUINS_CENTER = 32,
|
||||
BG_EY_OBJECT_N_BANNER_DRAENEI_RUINS_LEFT = 33,
|
||||
BG_EY_OBJECT_N_BANNER_DRAENEI_RUINS_RIGHT = 34,
|
||||
BG_EY_OBJECT_N_BANNER_MAGE_TOWER_CENTER = 35,
|
||||
BG_EY_OBJECT_N_BANNER_MAGE_TOWER_LEFT = 36,
|
||||
BG_EY_OBJECT_N_BANNER_MAGE_TOWER_RIGHT = 37,
|
||||
BG_EY_OBJECT_TOWER_CAP_FEL_REALVER = 38,
|
||||
BG_EY_OBJECT_TOWER_CAP_BLOOD_ELF = 39,
|
||||
BG_EY_OBJECT_TOWER_CAP_DRAENEI_RUINS = 40,
|
||||
BG_EY_OBJECT_TOWER_CAP_MAGE_TOWER = 41,
|
||||
BG_EY_OBJECT_FLAG_NETHERSTORM = 42,
|
||||
BG_EY_OBJECT_FLAG_FEL_REALVER = 43,
|
||||
BG_EY_OBJECT_FLAG_BLOOD_ELF = 44,
|
||||
BG_EY_OBJECT_FLAG_DRAENEI_RUINS = 45,
|
||||
BG_EY_OBJECT_FLAG_MAGE_TOWER = 46,
|
||||
//buffs
|
||||
BG_EY_OBJECT_SPEEDBUFF_FEL_REALVER = 47,
|
||||
BG_EY_OBJECT_REGENBUFF_FEL_REALVER = 48,
|
||||
BG_EY_OBJECT_BERSERKBUFF_FEL_REALVER = 49,
|
||||
BG_EY_OBJECT_SPEEDBUFF_BLOOD_ELF = 50,
|
||||
BG_EY_OBJECT_REGENBUFF_BLOOD_ELF = 51,
|
||||
BG_EY_OBJECT_BERSERKBUFF_BLOOD_ELF = 52,
|
||||
BG_EY_OBJECT_SPEEDBUFF_DRAENEI_RUINS = 53,
|
||||
BG_EY_OBJECT_REGENBUFF_DRAENEI_RUINS = 54,
|
||||
BG_EY_OBJECT_BERSERKBUFF_DRAENEI_RUINS = 55,
|
||||
BG_EY_OBJECT_SPEEDBUFF_MAGE_TOWER = 56,
|
||||
BG_EY_OBJECT_REGENBUFF_MAGE_TOWER = 57,
|
||||
BG_EY_OBJECT_BERSERKBUFF_MAGE_TOWER = 58,
|
||||
BG_EY_OBJECT_MAX = 59
|
||||
};
|
||||
|
||||
#define BG_EY_NotEYWeekendHonorTicks 330
|
||||
#define BG_EY_EYWeekendHonorTicks 200
|
||||
|
||||
enum BG_EY_Score
|
||||
{
|
||||
BG_EY_WARNING_NEAR_VICTORY_SCORE = 1400,
|
||||
BG_EY_MAX_TEAM_SCORE = 1600
|
||||
};
|
||||
|
||||
enum BG_EY_FlagState
|
||||
{
|
||||
BG_EY_FLAG_STATE_ON_BASE = 0,
|
||||
BG_EY_FLAG_STATE_WAIT_RESPAWN = 1,
|
||||
BG_EY_FLAG_STATE_ON_PLAYER = 2,
|
||||
BG_EY_FLAG_STATE_ON_GROUND = 3
|
||||
};
|
||||
|
||||
enum EYBattleGroundPointState
|
||||
{
|
||||
EY_POINT_NO_OWNER = 0,
|
||||
EY_POINT_STATE_UNCONTROLLED = 0,
|
||||
EY_POINT_UNDER_CONTROL = 3
|
||||
};
|
||||
|
||||
struct BattleGroundEYPointIconsStruct
|
||||
{
|
||||
BattleGroundEYPointIconsStruct(uint32 _WorldStateControlIndex, uint32 _WorldStateAllianceControlledIndex, uint32 _WorldStateHordeControlledIndex)
|
||||
: WorldStateControlIndex(_WorldStateControlIndex), WorldStateAllianceControlledIndex(_WorldStateAllianceControlledIndex), WorldStateHordeControlledIndex(_WorldStateHordeControlledIndex) {}
|
||||
uint32 WorldStateControlIndex;
|
||||
uint32 WorldStateAllianceControlledIndex;
|
||||
uint32 WorldStateHordeControlledIndex;
|
||||
};
|
||||
|
||||
// x, y, z, o
|
||||
const float BG_EY_TriggerPositions[EY_POINTS_MAX][4] = {
|
||||
{2044.28f, 1729.68f, 1189.96f, -0.017453f}, // FEL_REALVER center
|
||||
{2048.83f, 1393.65f, 1194.49f, 0.20944f}, // BLOOD_ELF center
|
||||
{2286.56f, 1402.36f, 1197.11f, 3.72381f}, // DRAENEI_RUINS center
|
||||
{2284.48f, 1731.23f, 1189.99f, 2.89725f} // MAGE_TOWER center
|
||||
};
|
||||
|
||||
struct BattleGroundEYLoosingPointStruct
|
||||
{
|
||||
BattleGroundEYLoosingPointStruct(uint32 _SpawnNeutralObjectType, uint32 _DespawnObjectTypeAlliance, uint32 _MessageIdAlliance, uint32 _DespawnObjectTypeHorde, uint32 _MessageIdHorde)
|
||||
: SpawnNeutralObjectType(_SpawnNeutralObjectType),
|
||||
DespawnObjectTypeAlliance(_DespawnObjectTypeAlliance), MessageIdAlliance(_MessageIdAlliance),
|
||||
DespawnObjectTypeHorde(_DespawnObjectTypeHorde), MessageIdHorde(_MessageIdHorde)
|
||||
{}
|
||||
|
||||
uint32 SpawnNeutralObjectType;
|
||||
uint32 DespawnObjectTypeAlliance;
|
||||
uint32 MessageIdAlliance;
|
||||
uint32 DespawnObjectTypeHorde;
|
||||
uint32 MessageIdHorde;
|
||||
};
|
||||
|
||||
struct BattleGroundEYCapturingPointStruct
|
||||
{
|
||||
BattleGroundEYCapturingPointStruct(uint32 _DespawnNeutralObjectType, uint32 _SpawnObjectTypeAlliance, uint32 _MessageIdAlliance, uint32 _SpawnObjectTypeHorde, uint32 _MessageIdHorde, uint32 _GraveYardId)
|
||||
: DespawnNeutralObjectType(_DespawnNeutralObjectType),
|
||||
SpawnObjectTypeAlliance(_SpawnObjectTypeAlliance), MessageIdAlliance(_MessageIdAlliance),
|
||||
SpawnObjectTypeHorde(_SpawnObjectTypeHorde), MessageIdHorde(_MessageIdHorde),
|
||||
GraveYardId(_GraveYardId)
|
||||
{}
|
||||
|
||||
uint32 DespawnNeutralObjectType;
|
||||
uint32 SpawnObjectTypeAlliance;
|
||||
uint32 MessageIdAlliance;
|
||||
uint32 SpawnObjectTypeHorde;
|
||||
uint32 MessageIdHorde;
|
||||
uint32 GraveYardId;
|
||||
};
|
||||
|
||||
const uint8 BG_EY_TickPoints[EY_POINTS_MAX] = {1, 2, 5, 10};
|
||||
const uint32 BG_EY_FlagPoints[EY_POINTS_MAX] = {75, 85, 100, 500};
|
||||
|
||||
//constant arrays:
|
||||
const BattleGroundEYPointIconsStruct m_PointsIconStruct[EY_POINTS_MAX] =
|
||||
{
|
||||
BattleGroundEYPointIconsStruct(FEL_REAVER_UNCONTROL, FEL_REAVER_ALLIANCE_CONTROL, FEL_REAVER_HORDE_CONTROL),
|
||||
BattleGroundEYPointIconsStruct(BLOOD_ELF_UNCONTROL, BLOOD_ELF_ALLIANCE_CONTROL, BLOOD_ELF_HORDE_CONTROL),
|
||||
BattleGroundEYPointIconsStruct(DRAENEI_RUINS_UNCONTROL, DRAENEI_RUINS_ALLIANCE_CONTROL, DRAENEI_RUINS_HORDE_CONTROL),
|
||||
BattleGroundEYPointIconsStruct(MAGE_TOWER_UNCONTROL, MAGE_TOWER_ALLIANCE_CONTROL, MAGE_TOWER_HORDE_CONTROL)
|
||||
};
|
||||
const BattleGroundEYLoosingPointStruct m_LoosingPointTypes[EY_POINTS_MAX] =
|
||||
{
|
||||
BattleGroundEYLoosingPointStruct(BG_EY_OBJECT_N_BANNER_FEL_REALVER_CENTER, BG_EY_OBJECT_A_BANNER_FEL_REALVER_CENTER, LANG_BG_EY_HAS_LOST_A_F_RUINS, BG_EY_OBJECT_H_BANNER_FEL_REALVER_CENTER, LANG_BG_EY_HAS_LOST_H_F_RUINS),
|
||||
BattleGroundEYLoosingPointStruct(BG_EY_OBJECT_N_BANNER_BLOOD_ELF_CENTER, BG_EY_OBJECT_A_BANNER_BLOOD_ELF_CENTER, LANG_BG_EY_HAS_LOST_A_B_TOWER, BG_EY_OBJECT_H_BANNER_BLOOD_ELF_CENTER, LANG_BG_EY_HAS_LOST_H_B_TOWER),
|
||||
BattleGroundEYLoosingPointStruct(BG_EY_OBJECT_N_BANNER_DRAENEI_RUINS_CENTER, BG_EY_OBJECT_A_BANNER_DRAENEI_RUINS_CENTER, LANG_BG_EY_HAS_LOST_A_D_RUINS, BG_EY_OBJECT_H_BANNER_DRAENEI_RUINS_CENTER, LANG_BG_EY_HAS_LOST_H_D_RUINS),
|
||||
BattleGroundEYLoosingPointStruct(BG_EY_OBJECT_N_BANNER_MAGE_TOWER_CENTER, BG_EY_OBJECT_A_BANNER_MAGE_TOWER_CENTER, LANG_BG_EY_HAS_LOST_A_M_TOWER, BG_EY_OBJECT_H_BANNER_MAGE_TOWER_CENTER, LANG_BG_EY_HAS_LOST_H_M_TOWER)
|
||||
};
|
||||
const BattleGroundEYCapturingPointStruct m_CapturingPointTypes[EY_POINTS_MAX] =
|
||||
{
|
||||
BattleGroundEYCapturingPointStruct(BG_EY_OBJECT_N_BANNER_FEL_REALVER_CENTER, BG_EY_OBJECT_A_BANNER_FEL_REALVER_CENTER, LANG_BG_EY_HAS_TAKEN_A_F_RUINS, BG_EY_OBJECT_H_BANNER_FEL_REALVER_CENTER, LANG_BG_EY_HAS_TAKEN_H_F_RUINS, EY_GRAVEYARD_FEL_REALVER),
|
||||
BattleGroundEYCapturingPointStruct(BG_EY_OBJECT_N_BANNER_BLOOD_ELF_CENTER, BG_EY_OBJECT_A_BANNER_BLOOD_ELF_CENTER, LANG_BG_EY_HAS_TAKEN_A_B_TOWER, BG_EY_OBJECT_H_BANNER_BLOOD_ELF_CENTER, LANG_BG_EY_HAS_TAKEN_H_B_TOWER, EY_GRAVEYARD_BLOOD_ELF),
|
||||
BattleGroundEYCapturingPointStruct(BG_EY_OBJECT_N_BANNER_DRAENEI_RUINS_CENTER, BG_EY_OBJECT_A_BANNER_DRAENEI_RUINS_CENTER, LANG_BG_EY_HAS_TAKEN_A_D_RUINS, BG_EY_OBJECT_H_BANNER_DRAENEI_RUINS_CENTER, LANG_BG_EY_HAS_TAKEN_H_D_RUINS, EY_GRAVEYARD_DRAENEI_RUINS),
|
||||
BattleGroundEYCapturingPointStruct(BG_EY_OBJECT_N_BANNER_MAGE_TOWER_CENTER, BG_EY_OBJECT_A_BANNER_MAGE_TOWER_CENTER, LANG_BG_EY_HAS_TAKEN_A_M_TOWER, BG_EY_OBJECT_H_BANNER_MAGE_TOWER_CENTER, LANG_BG_EY_HAS_TAKEN_H_M_TOWER, EY_GRAVEYARD_MAGE_TOWER)
|
||||
};
|
||||
|
||||
class BattleGroundEYScore : public BattleGroundScore
|
||||
{
|
||||
public:
|
||||
BattleGroundEYScore () : FlagCaptures(0) {};
|
||||
virtual ~BattleGroundEYScore() {};
|
||||
uint32 FlagCaptures;
|
||||
};
|
||||
|
||||
class BattleGroundEY : public BattleGround
|
||||
{
|
||||
friend class BattleGroundMgr;
|
||||
|
||||
public:
|
||||
BattleGroundEY();
|
||||
~BattleGroundEY();
|
||||
void Update(uint32 diff);
|
||||
|
||||
/* inherited from BattlegroundClass */
|
||||
virtual void AddPlayer(Player *plr);
|
||||
virtual void StartingEventCloseDoors();
|
||||
virtual void StartingEventOpenDoors();
|
||||
|
||||
/* BG Flags */
|
||||
uint64 GetFlagPickerGUID() const { return m_FlagKeeper; }
|
||||
void SetFlagPicker(uint64 guid) { m_FlagKeeper = guid; }
|
||||
bool IsFlagPickedup() const { return m_FlagKeeper != 0; }
|
||||
uint8 GetFlagState() const { return m_FlagState; }
|
||||
void RespawnFlag(bool send_message);
|
||||
void RespawnFlagAfterDrop();
|
||||
|
||||
void RemovePlayer(Player *plr,uint64 guid);
|
||||
void HandleBuffUse(uint64 const& buff_guid);
|
||||
void HandleAreaTrigger(Player *Source, uint32 Trigger);
|
||||
void HandleKillPlayer(Player *player, Player *killer);
|
||||
virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player);
|
||||
virtual bool SetupBattleGround();
|
||||
virtual void Reset();
|
||||
void UpdateTeamScore(uint32 Team);
|
||||
void EndBattleGround(uint32 winner);
|
||||
void UpdatePlayerScore(Player *Source, uint32 type, uint32 value, bool doAddHonor = true);
|
||||
virtual void FillInitialWorldStates(WorldPacket& data);
|
||||
void SetDroppedFlagGUID(uint64 guid) { m_DroppedFlagGUID = guid;}
|
||||
uint64 GetDroppedFlagGUID() const { return m_DroppedFlagGUID;}
|
||||
|
||||
/* Battleground Events */
|
||||
virtual void EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj);
|
||||
virtual void EventPlayerDroppedFlag(Player *Source);
|
||||
|
||||
/* achievement req. */
|
||||
bool IsAllNodesConrolledByTeam(uint32 team) const;
|
||||
private:
|
||||
void EventPlayerCapturedFlag(Player *Source, uint32 BgObjectType);
|
||||
void EventTeamCapturedPoint(Player *Source, uint32 Point);
|
||||
void EventTeamLostPoint(Player *Source, uint32 Point);
|
||||
void UpdatePointsCount(uint32 Team);
|
||||
void UpdatePointsIcons(uint32 Team, uint32 Point);
|
||||
|
||||
/* Point status updating procedures */
|
||||
void CheckSomeoneLeftPoint();
|
||||
void CheckSomeoneJoinedPoint();
|
||||
void UpdatePointStatuses();
|
||||
|
||||
/* Scorekeeping */
|
||||
uint32 GetTeamScore(uint32 Team) const { return m_TeamScores[GetTeamIndexByTeamId(Team)]; }
|
||||
void AddPoints(uint32 Team, uint32 Points);
|
||||
|
||||
void RemovePoint(uint32 TeamID, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] -= Points; }
|
||||
void SetTeamPoint(uint32 TeamID, uint32 Points = 0) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] = Points; }
|
||||
|
||||
uint32 m_HonorScoreTics[2];
|
||||
uint32 m_TeamPointsCount[2];
|
||||
|
||||
uint32 m_Points_Trigger[EY_POINTS_MAX];
|
||||
|
||||
uint64 m_FlagKeeper; // keepers guid
|
||||
uint64 m_DroppedFlagGUID;
|
||||
uint32 m_FlagCapturedBgObjectType; // type that should be despawned when flag is captured
|
||||
uint8 m_FlagState; // for checking flag state
|
||||
int32 m_FlagsTimer;
|
||||
int32 m_TowerCapCheckTimer;
|
||||
|
||||
uint32 m_PointOwnedByTeam[EY_POINTS_MAX];
|
||||
uint8 m_PointState[EY_POINTS_MAX];
|
||||
int32 m_PointBarStatus[EY_POINTS_MAX];
|
||||
typedef std::vector<uint64> PlayersNearPointType;
|
||||
PlayersNearPointType m_PlayersNearPoint[EY_POINTS_MAX + 1];
|
||||
uint8 m_CurrentPointPlayersCount[2*EY_POINTS_MAX];
|
||||
|
||||
int32 m_PointAddingTimer;
|
||||
uint32 m_HonorTics;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,803 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Common.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
|
||||
#include "ArenaTeam.h"
|
||||
#include "BattleGroundMgr.h"
|
||||
#include "BattleGroundWS.h"
|
||||
#include "BattleGround.h"
|
||||
#include "Chat.h"
|
||||
#include "Language.h"
|
||||
#include "Log.h"
|
||||
#include "Player.h"
|
||||
#include "Object.h"
|
||||
#include "Opcodes.h"
|
||||
|
||||
void WorldSession::HandleBattlemasterHelloOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
uint64 guid;
|
||||
recv_data >> guid;
|
||||
sLog.outDebug("WORLD: Recvd CMSG_BATTLEMASTER_HELLO Message from (GUID: %u TypeId:%u)", GUID_LOPART(guid),GuidHigh2TypeId(GUID_HIPART(guid)));
|
||||
|
||||
Creature *unit = GetPlayer()->GetMap()->GetCreature(guid);
|
||||
if (!unit)
|
||||
return;
|
||||
|
||||
if (!unit->isBattleMaster()) // it's not battlemaster
|
||||
return;
|
||||
|
||||
// Stop the npc if moving
|
||||
unit->StopMoving();
|
||||
|
||||
BattleGroundTypeId bgTypeId = sBattleGroundMgr.GetBattleMasterBG(unit->GetEntry());
|
||||
|
||||
if (!_player->GetBGAccessByLevel(bgTypeId))
|
||||
{
|
||||
// temp, must be gossip message...
|
||||
SendNotification(LANG_YOUR_BG_LEVEL_REQ_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
SendBattlegGroundList(guid, bgTypeId);
|
||||
}
|
||||
|
||||
void WorldSession::SendBattlegGroundList(uint64 guid, BattleGroundTypeId bgTypeId)
|
||||
{
|
||||
WorldPacket data;
|
||||
sBattleGroundMgr.BuildBattleGroundListPacket(&data, guid, _player, bgTypeId, 0);
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
uint64 guid;
|
||||
uint32 bgTypeId_;
|
||||
uint32 instanceId;
|
||||
uint8 joinAsGroup;
|
||||
bool isPremade = false;
|
||||
Group * grp = NULL;
|
||||
|
||||
recv_data >> guid; // battlemaster guid
|
||||
recv_data >> bgTypeId_; // battleground type id (DBC id)
|
||||
recv_data >> instanceId; // instance id, 0 if First Available selected
|
||||
recv_data >> joinAsGroup; // join as group
|
||||
|
||||
if (!sBattlemasterListStore.LookupEntry(bgTypeId_))
|
||||
{
|
||||
sLog.outError("Battleground: invalid bgtype (%u) received. possible cheater? player guid %u",bgTypeId_,_player->GetGUIDLow());
|
||||
return;
|
||||
}
|
||||
|
||||
BattleGroundTypeId bgTypeId = BattleGroundTypeId(bgTypeId_);
|
||||
|
||||
sLog.outDebug("WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from (GUID: %u TypeId:%u)", GUID_LOPART(guid), GuidHigh2TypeId(GUID_HIPART(guid)));
|
||||
|
||||
// can do this, since it's battleground, not arena
|
||||
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, 0);
|
||||
BattleGroundQueueTypeId bgQueueTypeIdRandom = BattleGroundMgr::BGQueueTypeId(BATTLEGROUND_RB, 0);
|
||||
|
||||
// ignore if player is already in BG
|
||||
if (_player->InBattleGround())
|
||||
return;
|
||||
|
||||
// get bg instance or bg template if instance not found
|
||||
BattleGround *bg = NULL;
|
||||
if (instanceId)
|
||||
bg = sBattleGroundMgr.GetBattleGroundThroughClientInstance(instanceId, bgTypeId);
|
||||
|
||||
if (!bg)
|
||||
bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
|
||||
if (!bg)
|
||||
return;
|
||||
|
||||
// expected bracket entry
|
||||
PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(),_player->getLevel());
|
||||
if (!bracketEntry)
|
||||
return;
|
||||
|
||||
GroupJoinBattlegroundResult err;
|
||||
|
||||
// check queue conditions
|
||||
if (!joinAsGroup)
|
||||
{
|
||||
// check Deserter debuff
|
||||
if (!_player->CanJoinToBattleground())
|
||||
{
|
||||
WorldPacket data;
|
||||
sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS);
|
||||
_player->GetSession()->SendPacket(&data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_player->GetBattleGroundQueueIndex(bgQueueTypeIdRandom) < PLAYER_MAX_BATTLEGROUND_QUEUES)
|
||||
{
|
||||
//player is already in random queue
|
||||
WorldPacket data;
|
||||
sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, ERR_IN_RANDOM_BG);
|
||||
_player->GetSession()->SendPacket(&data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_player->InBattleGroundQueue() && bgTypeId == BATTLEGROUND_RB)
|
||||
{
|
||||
//player is already in queue, can't start random queue
|
||||
WorldPacket data;
|
||||
sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, ERR_IN_NON_RANDOM_BG);
|
||||
_player->GetSession()->SendPacket(&data);
|
||||
return;
|
||||
}
|
||||
|
||||
// check if already in queue
|
||||
if (_player->GetBattleGroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES)
|
||||
//player is already in this queue
|
||||
return;
|
||||
|
||||
// check if has free queue slots
|
||||
if (!_player->HasFreeBattleGroundQueueId())
|
||||
{
|
||||
WorldPacket data;
|
||||
sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, ERR_BATTLEGROUND_TOO_MANY_QUEUES);
|
||||
_player->GetSession()->SendPacket(&data);
|
||||
return;
|
||||
}
|
||||
|
||||
BattleGroundQueue& bgQueue = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId];
|
||||
|
||||
GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, bracketEntry, 0, false, isPremade, 0);
|
||||
uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId());
|
||||
// already checked if queueSlot is valid, now just get it
|
||||
uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId);
|
||||
|
||||
WorldPacket data;
|
||||
// send status packet (in queue)
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType);
|
||||
SendPacket(&data);
|
||||
sLog.outDebug("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName());
|
||||
}
|
||||
else
|
||||
{
|
||||
grp = _player->GetGroup();
|
||||
// no group found, error
|
||||
if (!grp)
|
||||
return;
|
||||
if (grp->GetLeaderGUID() != _player->GetGUID())
|
||||
return;
|
||||
err = grp->CanJoinBattleGroundQueue(bg, bgQueueTypeId, 0, bg->GetMaxPlayersPerTeam(), false, 0);
|
||||
isPremade = (grp->GetMembersCount() >= bg->GetMinPlayersPerTeam());
|
||||
|
||||
BattleGroundQueue& bgQueue = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId];
|
||||
GroupQueueInfo * ginfo = NULL;
|
||||
uint32 avgTime = 0;
|
||||
|
||||
if (err > 0)
|
||||
{
|
||||
sLog.outDebug("Battleground: the following players are joining as group:");
|
||||
ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, 0, false, isPremade, 0);
|
||||
avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId());
|
||||
}
|
||||
|
||||
for (GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
{
|
||||
Player *member = itr->getSource();
|
||||
if (!member) continue; // this should never happen
|
||||
|
||||
WorldPacket data;
|
||||
|
||||
if (err <= 0)
|
||||
{
|
||||
sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, err);
|
||||
member->GetSession()->SendPacket(&data);
|
||||
continue;
|
||||
}
|
||||
|
||||
// add to queue
|
||||
uint32 queueSlot = member->AddBattleGroundQueueId(bgQueueTypeId);
|
||||
|
||||
// send status packet (in queue)
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType);
|
||||
member->GetSession()->SendPacket(&data);
|
||||
sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, err);
|
||||
member->GetSession()->SendPacket(&data);
|
||||
sLog.outDebug("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,member->GetGUIDLow(), member->GetName());
|
||||
}
|
||||
sLog.outDebug("Battleground: group end");
|
||||
|
||||
}
|
||||
sBattleGroundMgr.ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
|
||||
}
|
||||
|
||||
void WorldSession::HandleBattleGroundPlayerPositionsOpcode(WorldPacket & /*recv_data*/)
|
||||
{
|
||||
// empty opcode
|
||||
sLog.outDebug("WORLD: Recvd MSG_BATTLEGROUND_PLAYER_POSITIONS Message");
|
||||
|
||||
BattleGround *bg = _player->GetBattleGround();
|
||||
if (!bg) // can't be received if player not in battleground
|
||||
return;
|
||||
|
||||
switch(bg->GetTypeID(true))
|
||||
{
|
||||
case BATTLEGROUND_WS:
|
||||
{
|
||||
uint32 count1 = 0; //always constant zero?
|
||||
uint32 count2 = 0; //count of next fields
|
||||
|
||||
Player *ali_plr = objmgr.GetPlayer(((BattleGroundWS*)bg)->GetAllianceFlagPickerGUID());
|
||||
if (ali_plr)
|
||||
++count2;
|
||||
|
||||
Player *horde_plr = objmgr.GetPlayer(((BattleGroundWS*)bg)->GetHordeFlagPickerGUID());
|
||||
if (horde_plr)
|
||||
++count2;
|
||||
|
||||
WorldPacket data(MSG_BATTLEGROUND_PLAYER_POSITIONS, (4+4+16*count1+16*count2));
|
||||
data << count1; // alliance flag holders count - obsolete, now always 0
|
||||
/*for (uint8 i = 0; i < count1; ++i)
|
||||
{
|
||||
data << uint64(0); // guid
|
||||
data << (float)0; // x
|
||||
data << (float)0; // y
|
||||
}*/
|
||||
data << count2; // horde flag holders count - obsolete, now count of next fields
|
||||
if (ali_plr)
|
||||
{
|
||||
data << (uint64)ali_plr->GetGUID();
|
||||
data << (float)ali_plr->GetPositionX();
|
||||
data << (float)ali_plr->GetPositionY();
|
||||
}
|
||||
if (horde_plr)
|
||||
{
|
||||
data << (uint64)horde_plr->GetGUID();
|
||||
data << (float)horde_plr->GetPositionX();
|
||||
data << (float)horde_plr->GetPositionY();
|
||||
}
|
||||
|
||||
SendPacket(&data);
|
||||
}
|
||||
break;
|
||||
case BATTLEGROUND_EY:
|
||||
//TODO : fix me!
|
||||
break;
|
||||
case BATTLEGROUND_AB:
|
||||
case BATTLEGROUND_AV:
|
||||
{
|
||||
//for other BG types - send default
|
||||
WorldPacket data(MSG_BATTLEGROUND_PLAYER_POSITIONS, (4+4));
|
||||
data << uint32(0);
|
||||
data << uint32(0);
|
||||
SendPacket(&data);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
//maybe it is sent also in arena - do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandlePVPLogDataOpcode(WorldPacket & /*recv_data*/)
|
||||
{
|
||||
sLog.outDebug("WORLD: Recvd MSG_PVP_LOG_DATA Message");
|
||||
|
||||
BattleGround *bg = _player->GetBattleGround();
|
||||
if (!bg)
|
||||
return;
|
||||
|
||||
WorldPacket data;
|
||||
sBattleGroundMgr.BuildPvpLogDataPacket(&data, bg);
|
||||
SendPacket(&data);
|
||||
|
||||
sLog.outDebug("WORLD: Sent MSG_PVP_LOG_DATA Message");
|
||||
}
|
||||
|
||||
void WorldSession::HandleBattlefieldListOpcode(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: Recvd CMSG_BATTLEFIELD_LIST Message");
|
||||
|
||||
uint32 bgTypeId;
|
||||
recv_data >> bgTypeId; // id from DBC
|
||||
|
||||
uint8 fromWhere;
|
||||
recv_data >> fromWhere; // 0 - battlemaster (lua: ShowBattlefieldList), 1 - UI (lua: RequestBattlegroundInstanceInfo)
|
||||
|
||||
uint8 unk1;
|
||||
recv_data >> unk1; // Unknown 3.2.2
|
||||
|
||||
BattlemasterListEntry const* bl = sBattlemasterListStore.LookupEntry(bgTypeId);
|
||||
if (!bl)
|
||||
{
|
||||
sLog.outError("Battleground: invalid bgtype received.");
|
||||
return;
|
||||
}
|
||||
|
||||
WorldPacket data;
|
||||
sBattleGroundMgr.BuildBattleGroundListPacket(&data, 0, _player, BattleGroundTypeId(bgTypeId), fromWhere);
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: Recvd CMSG_BATTLEFIELD_PORT Message");
|
||||
|
||||
uint8 type; // arenatype if arena
|
||||
uint8 unk2; // unk, can be 0x0 (may be if was invited?) and 0x1
|
||||
uint32 bgTypeId_; // type id from dbc
|
||||
uint16 unk; // 0x1F90 constant?
|
||||
uint8 action; // enter battle 0x1, leave queue 0x0
|
||||
|
||||
recv_data >> type >> unk2 >> bgTypeId_ >> unk >> action;
|
||||
|
||||
if (!sBattlemasterListStore.LookupEntry(bgTypeId_))
|
||||
{
|
||||
sLog.outError("BattlegroundHandler: invalid bgtype (%u) received.", bgTypeId_);
|
||||
return;
|
||||
}
|
||||
if (!_player->InBattleGroundQueue())
|
||||
{
|
||||
sLog.outError("BattlegroundHandler: Invalid CMSG_BATTLEFIELD_PORT received from player (%u), he is not in bg_queue.", _player->GetGUIDLow());
|
||||
return;
|
||||
}
|
||||
|
||||
//get GroupQueueInfo from BattleGroundQueue
|
||||
BattleGroundTypeId bgTypeId = BattleGroundTypeId(bgTypeId_);
|
||||
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, type);
|
||||
BattleGroundQueue& bgQueue = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId];
|
||||
//we must use temporary variable, because GroupQueueInfo pointer can be deleted in BattleGroundQueue::RemovePlayer() function
|
||||
GroupQueueInfo ginfo;
|
||||
if (!bgQueue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
|
||||
{
|
||||
sLog.outError("BattlegroundHandler: itrplayerstatus not found.");
|
||||
return;
|
||||
}
|
||||
// if action == 1, then instanceId is required
|
||||
if (!ginfo.IsInvitedToBGInstanceGUID && action == 1)
|
||||
{
|
||||
sLog.outError("BattlegroundHandler: instance not found.");
|
||||
return;
|
||||
}
|
||||
|
||||
BattleGround *bg = sBattleGroundMgr.GetBattleGround(ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
|
||||
|
||||
// bg template might and must be used in case of leaving queue, when instance is not created yet
|
||||
if (!bg && action == 0)
|
||||
bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
|
||||
if (!bg)
|
||||
{
|
||||
sLog.outError("BattlegroundHandler: bg_template not found for type id %u.", bgTypeId);
|
||||
return;
|
||||
}
|
||||
|
||||
// expected bracket entry
|
||||
PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(),_player->getLevel());
|
||||
if (!bracketEntry)
|
||||
return;
|
||||
|
||||
//some checks if player isn't cheating - it is not exactly cheating, but we cannot allow it
|
||||
if (action == 1 && ginfo.ArenaType == 0)
|
||||
{
|
||||
//if player is trying to enter battleground (not arena!) and he has deserter debuff, we must just remove him from queue
|
||||
if (!_player->CanJoinToBattleground())
|
||||
{
|
||||
//send bg command result to show nice message
|
||||
WorldPacket data2;
|
||||
sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data2, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS);
|
||||
_player->GetSession()->SendPacket(&data2);
|
||||
action = 0;
|
||||
sLog.outDebug("Battleground: player %s (%u) has a deserter debuff, do not port him to battleground!", _player->GetName(), _player->GetGUIDLow());
|
||||
}
|
||||
//if player don't match battleground max level, then do not allow him to enter! (this might happen when player leveled up during his waiting in queue
|
||||
if (_player->getLevel() > bg->GetMaxLevel())
|
||||
{
|
||||
sLog.outError("Battleground: Player %s (%u) has level (%u) higher than maxlevel (%u) of battleground (%u)! Do not port him to battleground!",
|
||||
_player->GetName(), _player->GetGUIDLow(), _player->getLevel(), bg->GetMaxLevel(), bg->GetTypeID());
|
||||
action = 0;
|
||||
}
|
||||
}
|
||||
uint32 queueSlot = _player->GetBattleGroundQueueIndex(bgQueueTypeId);
|
||||
WorldPacket data;
|
||||
switch(action)
|
||||
{
|
||||
case 1: // port to battleground
|
||||
if (!_player->IsInvitedForBattleGroundQueueType(bgQueueTypeId))
|
||||
return; // cheating?
|
||||
|
||||
if (!_player->InBattleGround())
|
||||
_player->SetBattleGroundEntryPoint();
|
||||
|
||||
// resurrect the player
|
||||
if (!_player->isAlive())
|
||||
{
|
||||
_player->ResurrectPlayer(1.0f);
|
||||
_player->SpawnCorpseBones();
|
||||
}
|
||||
// stop taxi flight at port
|
||||
if (_player->isInFlight())
|
||||
{
|
||||
_player->GetMotionMaster()->MovementExpired();
|
||||
_player->CleanupAfterTaxiFlight();
|
||||
}
|
||||
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType());
|
||||
_player->GetSession()->SendPacket(&data);
|
||||
// remove battleground queue status from BGmgr
|
||||
bgQueue.RemovePlayer(_player->GetGUID(), false);
|
||||
// this is still needed here if battleground "jumping" shouldn't add deserter debuff
|
||||
// also this is required to prevent stuck at old battleground after SetBattleGroundId set to new
|
||||
if (BattleGround *currentBg = _player->GetBattleGround())
|
||||
currentBg->RemovePlayerAtLeave(_player->GetGUID(), false, true);
|
||||
|
||||
// set the destination instance id
|
||||
_player->SetBattleGroundId(bg->GetInstanceID(), bgTypeId);
|
||||
// set the destination team
|
||||
_player->SetBGTeam(ginfo.Team);
|
||||
// bg->HandleBeforeTeleportToBattleGround(_player);
|
||||
sBattleGroundMgr.SendToBattleGround(_player, ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
|
||||
// add only in HandleMoveWorldPortAck()
|
||||
// bg->AddPlayer(_player,team);
|
||||
sLog.outDebug("Battleground: player %s (%u) joined battle for bg %u, bgtype %u, queue type %u.", _player->GetName(), _player->GetGUIDLow(), bg->GetInstanceID(), bg->GetTypeID(), bgQueueTypeId);
|
||||
break;
|
||||
case 0: // leave queue
|
||||
// if player leaves rated arena match before match start, it is counted as he played but he lost
|
||||
if (ginfo.IsRated)
|
||||
{
|
||||
ArenaTeam * at = objmgr.GetArenaTeamById(ginfo.Team);
|
||||
if (at)
|
||||
{
|
||||
sLog.outDebug("UPDATING memberLost's personal arena rating for %u by opponents rating: %u, because he has left queue!", GUID_LOPART(_player->GetGUID()), ginfo.OpponentsTeamRating);
|
||||
at->MemberLost(_player, ginfo.OpponentsTeamRating);
|
||||
at->SaveToDB();
|
||||
}
|
||||
}
|
||||
_player->RemoveBattleGroundQueueId(bgQueueTypeId); // must be called this way, because if you move this call to queue->removeplayer, it causes bugs
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0);
|
||||
bgQueue.RemovePlayer(_player->GetGUID(), true);
|
||||
// player left queue, we should update it - do not update Arena Queue
|
||||
if (!ginfo.ArenaType)
|
||||
sBattleGroundMgr.ScheduleQueueUpdate(ginfo.ArenaTeamRating, ginfo.ArenaType, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
|
||||
SendPacket(&data);
|
||||
sLog.outDebug("Battleground: player %s (%u) left queue for bgtype %u, queue type %u.", _player->GetName(), _player->GetGUIDLow(), bg->GetTypeID(), bgQueueTypeId);
|
||||
break;
|
||||
default:
|
||||
sLog.outError("Battleground port: unknown action %u", action);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandleLeaveBattlefieldOpcode(WorldPacket& recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: Recvd CMSG_LEAVE_BATTLEFIELD Message");
|
||||
|
||||
recv_data.read_skip<uint8>(); // unk1
|
||||
recv_data.read_skip<uint8>(); // unk2
|
||||
recv_data.read_skip<uint32>(); // BattleGroundTypeId
|
||||
recv_data.read_skip<uint16>(); // unk3
|
||||
|
||||
// not allow leave battleground in combat
|
||||
if (_player->isInCombat())
|
||||
if (BattleGround* bg = _player->GetBattleGround())
|
||||
if (bg->GetStatus() != STATUS_WAIT_LEAVE)
|
||||
return;
|
||||
|
||||
_player->LeaveBattleground();
|
||||
}
|
||||
|
||||
void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recv_data*/)
|
||||
{
|
||||
// empty opcode
|
||||
sLog.outDebug("WORLD: Battleground status");
|
||||
|
||||
WorldPacket data;
|
||||
// we must update all queues here
|
||||
BattleGround *bg = NULL;
|
||||
for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
|
||||
{
|
||||
BattleGroundQueueTypeId bgQueueTypeId = _player->GetBattleGroundQueueTypeId(i);
|
||||
if (!bgQueueTypeId)
|
||||
continue;
|
||||
BattleGroundTypeId bgTypeId = BattleGroundMgr::BGTemplateId(bgQueueTypeId);
|
||||
uint8 arenaType = BattleGroundMgr::BGArenaType(bgQueueTypeId);
|
||||
if (bgTypeId == _player->GetBattleGroundTypeId())
|
||||
{
|
||||
bg = _player->GetBattleGround();
|
||||
//i cannot check any variable from player class because player class doesn't know if player is in 2v2 / 3v3 or 5v5 arena
|
||||
//so i must use bg pointer to get that information
|
||||
if (bg && bg->GetArenaType() == arenaType)
|
||||
{
|
||||
// this line is checked, i only don't know if GetStartTime is changing itself after bg end!
|
||||
// send status in BattleGround
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, i, STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), arenaType);
|
||||
SendPacket(&data);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
//we are sending update to player about queue - he can be invited there!
|
||||
//get GroupQueueInfo for queue status
|
||||
BattleGroundQueue& bgQueue = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId];
|
||||
GroupQueueInfo ginfo;
|
||||
if (!bgQueue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
|
||||
continue;
|
||||
if (ginfo.IsInvitedToBGInstanceGUID)
|
||||
{
|
||||
bg = sBattleGroundMgr.GetBattleGround(ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
|
||||
if (!bg)
|
||||
continue;
|
||||
uint32 remainingTime = getMSTimeDiff(getMSTime(), ginfo.RemoveInviteTime);
|
||||
// send status invited to BattleGround
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, i, STATUS_WAIT_JOIN, remainingTime, 0, arenaType);
|
||||
SendPacket(&data);
|
||||
}
|
||||
else
|
||||
{
|
||||
bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
|
||||
if (!bg)
|
||||
continue;
|
||||
|
||||
// expected bracket entry
|
||||
PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(),_player->getLevel());
|
||||
if (!bracketEntry)
|
||||
continue;
|
||||
|
||||
uint32 avgTime = bgQueue.GetAverageQueueWaitTime(&ginfo, bracketEntry->GetBracketId());
|
||||
// send status in BattleGround Queue
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, i, STATUS_WAIT_QUEUE, avgTime, getMSTimeDiff(ginfo.JoinTime, getMSTime()), arenaType);
|
||||
SendPacket(&data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandleAreaSpiritHealerQueryOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_AREA_SPIRIT_HEALER_QUERY");
|
||||
|
||||
BattleGround *bg = _player->GetBattleGround();
|
||||
|
||||
uint64 guid;
|
||||
recv_data >> guid;
|
||||
|
||||
Creature *unit = GetPlayer()->GetMap()->GetCreature(guid);
|
||||
if (!unit)
|
||||
return;
|
||||
|
||||
if (!unit->isSpiritService()) // it's not spirit service
|
||||
return;
|
||||
|
||||
if (bg)
|
||||
sBattleGroundMgr.SendAreaSpiritHealerQueryOpcode(_player, bg, guid);
|
||||
}
|
||||
|
||||
|
||||
void WorldSession::HandleAreaSpiritHealerQueueOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_AREA_SPIRIT_HEALER_QUEUE");
|
||||
|
||||
BattleGround *bg = _player->GetBattleGround();
|
||||
|
||||
uint64 guid;
|
||||
recv_data >> guid;
|
||||
|
||||
Creature *unit = GetPlayer()->GetMap()->GetCreature(guid);
|
||||
if (!unit)
|
||||
return;
|
||||
|
||||
if (!unit->isSpiritService()) // it's not spirit service
|
||||
return;
|
||||
|
||||
if (bg)
|
||||
bg->AddPlayerToResurrectQueue(guid, _player->GetGUID());
|
||||
}
|
||||
|
||||
|
||||
void WorldSession::HandleBattlemasterJoinArena(WorldPacket & recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_BATTLEMASTER_JOIN_ARENA");
|
||||
//recv_data.hexlike();
|
||||
|
||||
uint64 guid; // arena Battlemaster guid
|
||||
uint8 arenaslot; // 2v2, 3v3 or 5v5
|
||||
uint8 asGroup; // asGroup
|
||||
uint8 isRated; // isRated
|
||||
Group * grp = NULL;
|
||||
|
||||
recv_data >> guid >> arenaslot >> asGroup >> isRated;
|
||||
|
||||
// ignore if we already in BG or BG queue
|
||||
if (_player->InBattleGround())
|
||||
return;
|
||||
|
||||
Creature *unit = GetPlayer()->GetMap()->GetCreature(guid);
|
||||
if (!unit)
|
||||
return;
|
||||
|
||||
if (!unit->isBattleMaster()) // it's not battle master
|
||||
return;
|
||||
|
||||
uint8 arenatype = 0;
|
||||
uint32 arenaRating = 0;
|
||||
|
||||
switch(arenaslot)
|
||||
{
|
||||
case 0:
|
||||
arenatype = ARENA_TYPE_2v2;
|
||||
break;
|
||||
case 1:
|
||||
arenatype = ARENA_TYPE_3v3;
|
||||
break;
|
||||
case 2:
|
||||
arenatype = ARENA_TYPE_5v5;
|
||||
break;
|
||||
default:
|
||||
sLog.outError("Unknown arena slot %u at HandleBattlemasterJoinArena()", arenaslot);
|
||||
return;
|
||||
}
|
||||
|
||||
//check existance
|
||||
BattleGround* bg = sBattleGroundMgr.GetBattleGroundTemplate(BATTLEGROUND_AA);
|
||||
if (!bg)
|
||||
{
|
||||
sLog.outError("Battleground: template bg (all arenas) not found");
|
||||
return;
|
||||
}
|
||||
|
||||
BattleGroundTypeId bgTypeId = bg->GetTypeID();
|
||||
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, arenatype);
|
||||
PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(),_player->getLevel());
|
||||
if (!bracketEntry)
|
||||
return;
|
||||
|
||||
GroupJoinBattlegroundResult err = ERR_GROUP_JOIN_BATTLEGROUND_FAIL;
|
||||
|
||||
if (!asGroup)
|
||||
{
|
||||
// check if already in queue
|
||||
if (_player->GetBattleGroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES)
|
||||
//player is already in this queue
|
||||
return;
|
||||
// check if has free queue slots
|
||||
if (!_player->HasFreeBattleGroundQueueId())
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
grp = _player->GetGroup();
|
||||
// no group found, error
|
||||
if (!grp)
|
||||
return;
|
||||
if (grp->GetLeaderGUID() != _player->GetGUID())
|
||||
return;
|
||||
err = grp->CanJoinBattleGroundQueue(bg, bgQueueTypeId, arenatype, arenatype, (bool)isRated, arenaslot);
|
||||
}
|
||||
|
||||
uint32 ateamId = 0;
|
||||
|
||||
if (isRated)
|
||||
{
|
||||
ateamId = _player->GetArenaTeamId(arenaslot);
|
||||
// check real arenateam existence only here (if it was moved to group->CanJoin .. () then we would ahve to get it twice)
|
||||
ArenaTeam * at = objmgr.GetArenaTeamById(ateamId);
|
||||
if (!at)
|
||||
{
|
||||
_player->GetSession()->SendNotInArenaTeamPacket(arenatype);
|
||||
return;
|
||||
}
|
||||
// get the team rating for queueing
|
||||
arenaRating = at->GetRating();
|
||||
// the arenateam id must match for everyone in the group
|
||||
// get the personal ratings for queueing
|
||||
uint32 avg_pers_rating = 0;
|
||||
for (GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
{
|
||||
Player *member = itr->getSource();
|
||||
|
||||
// calc avg personal rating
|
||||
avg_pers_rating += member->GetArenaPersonalRating(arenaslot);
|
||||
}
|
||||
|
||||
if (arenatype)
|
||||
avg_pers_rating /= arenatype;
|
||||
|
||||
// if avg personal rating is more than 150 points below the teams rating, the team will be queued against an opponent matching or similar to the average personal rating
|
||||
if (avg_pers_rating + 150 < arenaRating)
|
||||
arenaRating = avg_pers_rating;
|
||||
|
||||
if (arenaRating <= 0)
|
||||
arenaRating = 1;
|
||||
}
|
||||
|
||||
BattleGroundQueue &bgQueue = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId];
|
||||
if (asGroup)
|
||||
{
|
||||
uint32 avgTime = 0;
|
||||
|
||||
if (err > 0)
|
||||
{
|
||||
sLog.outDebug("Battleground: arena join as group start");
|
||||
if (isRated)
|
||||
{
|
||||
sLog.outDebug("Battleground: arena team id %u, leader %s queued with rating %u for type %u",_player->GetArenaTeamId(arenaslot),_player->GetName(),arenaRating,arenatype);
|
||||
bg->SetRated(true);
|
||||
}
|
||||
else
|
||||
bg->SetRated(false);
|
||||
|
||||
GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, arenatype, isRated, false, arenaRating, ateamId);
|
||||
avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId());
|
||||
}
|
||||
|
||||
for (GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
{
|
||||
Player *member = itr->getSource();
|
||||
if (!member)
|
||||
continue;
|
||||
|
||||
WorldPacket data;
|
||||
|
||||
if (err <= 0)
|
||||
{
|
||||
sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, err);
|
||||
member->GetSession()->SendPacket(&data);
|
||||
continue;
|
||||
}
|
||||
|
||||
// add to queue
|
||||
uint32 queueSlot = member->AddBattleGroundQueueId(bgQueueTypeId);
|
||||
|
||||
// send status packet (in queue)
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype);
|
||||
member->GetSession()->SendPacket(&data);
|
||||
sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, err);
|
||||
member->GetSession()->SendPacket(&data);
|
||||
sLog.outDebug("Battleground: player joined queue for arena as group bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,member->GetGUIDLow(), member->GetName());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, bracketEntry, arenatype, isRated, false, arenaRating, ateamId);
|
||||
uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId());
|
||||
uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId);
|
||||
|
||||
WorldPacket data;
|
||||
// send status packet (in queue)
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype);
|
||||
SendPacket(&data);
|
||||
sLog.outDebug("Battleground: player joined queue for arena, skirmish, bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName());
|
||||
}
|
||||
sBattleGroundMgr.ScheduleQueueUpdate(arenaRating, arenatype, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
|
||||
}
|
||||
|
||||
void WorldSession::HandleReportPvPAFK(WorldPacket & recv_data)
|
||||
{
|
||||
uint64 playerGuid;
|
||||
recv_data >> playerGuid;
|
||||
Player *reportedPlayer = objmgr.GetPlayer(playerGuid);
|
||||
|
||||
if (!reportedPlayer)
|
||||
{
|
||||
sLog.outDebug("WorldSession::HandleReportPvPAFK: player not found");
|
||||
return;
|
||||
}
|
||||
|
||||
sLog.outDebug("WorldSession::HandleReportPvPAFK: %s reported %s", _player->GetName(), reportedPlayer->GetName());
|
||||
|
||||
reportedPlayer->ReportedAfkBy(_player);
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Player.h"
|
||||
#include "BattleGround.h"
|
||||
#include "BattleGroundIC.h"
|
||||
#include "Language.h"
|
||||
|
||||
BattleGroundIC::BattleGroundIC()
|
||||
{
|
||||
m_BgCreatures.resize(2);
|
||||
m_BgObjects.resize(5);
|
||||
//TODO FIX ME!
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_WS_START_TWO_MINUTES;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_WS_START_ONE_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_WS_START_HALF_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_WS_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattleGroundIC::~BattleGroundIC()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void BattleGroundIC::Update(uint32 diff)
|
||||
{
|
||||
BattleGround::Update(diff);
|
||||
}
|
||||
|
||||
void BattleGroundIC::StartingEventCloseDoors()
|
||||
{
|
||||
}
|
||||
|
||||
void BattleGroundIC::StartingEventOpenDoors()
|
||||
{
|
||||
}
|
||||
|
||||
void BattleGroundIC::AddPlayer(Player *plr)
|
||||
{
|
||||
BattleGround::AddPlayer(plr);
|
||||
//create score and add it to map, default values are set in constructor
|
||||
BattleGroundICScore* sc = new BattleGroundICScore;
|
||||
|
||||
m_PlayerScores[plr->GetGUID()] = sc;
|
||||
}
|
||||
|
||||
void BattleGroundIC::RemovePlayer(Player* /*plr*/,uint64 /*guid*/)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void BattleGroundIC::HandleAreaTrigger(Player * /*Source*/, uint32 /*Trigger*/)
|
||||
{
|
||||
// this is wrong way to implement these things. On official it done by gameobject spell cast.
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
}
|
||||
|
||||
void BattleGroundIC::UpdatePlayerScore(Player* Source, uint32 type, uint32 value, bool doAddHonor)
|
||||
{
|
||||
|
||||
std::map<uint64, BattleGroundScore*>::iterator itr = m_PlayerScores.find(Source->GetGUID());
|
||||
|
||||
if (itr == m_PlayerScores.end()) // player not found...
|
||||
return;
|
||||
|
||||
BattleGround::UpdatePlayerScore(Source,type,value, doAddHonor);
|
||||
}
|
||||
|
||||
bool BattleGroundIC::SetupBattleGround()
|
||||
{
|
||||
AddObject(0, 195157, 459.72f, -419.93f, 42.55f, 0, 0, 0, 0.9996573f, 0.02617699f, 10*MINUTE);
|
||||
AddObject(1, 195158, 797.72f, -1009.48f, 138.52f, 0, 0, 0, 0.9996573f, 0.02617699f, 10*MINUTE);
|
||||
AddObject(2, 195338, 418.98f, -838.33f, 51.09f, 0, 0, 0, 0.9996573f, 0.02617699f, 10*MINUTE);
|
||||
AddObject(3, 195343, 1267.45f, -390.88f, 24.23f, 0, 0, 0, 0.9996573f, 0.02617699f, 10*MINUTE);
|
||||
AddObject(4, 195333, 769.27f, -833.53f, 9.57f, 0, 0, 0, 0.9996573f, 0.02617699f, 10*MINUTE);
|
||||
SpawnLeader(ALLIANCE);
|
||||
SpawnLeader(HORDE);
|
||||
return true;
|
||||
}
|
||||
|
||||
void BattleGroundIC::SpawnLeader(uint32 teamid)
|
||||
{
|
||||
if (teamid == ALLIANCE)
|
||||
AddCreature(34924, 0, ALLIANCE, 307.03f, -833.04f, 48.91f, 6.23f, 10*MINUTE);
|
||||
else
|
||||
AddCreature(34922, 1, HORDE, 1264.42f, -766.80f, 48.91f, 3.28f, 10*MINUTE);
|
||||
}
|
||||
|
||||
void BattleGroundIC::HandleKillUnit(Creature *unit, Player * /*killer*/)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
uint32 entry = unit->GetEntry();
|
||||
if (entry == 34924)
|
||||
{
|
||||
RewardHonorToTeam(500,HORDE);
|
||||
EndBattleGround(HORDE);
|
||||
}
|
||||
else if (entry == 34922)
|
||||
{
|
||||
RewardHonorToTeam(500,ALLIANCE);
|
||||
EndBattleGround(ALLIANCE);
|
||||
}
|
||||
}
|
||||
|
||||
void BattleGroundIC::EndBattleGround(uint32 winner)
|
||||
{
|
||||
BattleGround::EndBattleGround(winner);
|
||||
}
|
||||
|
||||
void BattleGroundIC::EventPlayerClickedOnFlag(Player * /*source*/, GameObject* /*target_obj*/)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __BATTLEGROUNDIC_H
|
||||
#define __BATTLEGROUNDIC_H
|
||||
|
||||
class BattleGround;
|
||||
|
||||
enum Buffs
|
||||
{
|
||||
OIL_REFINERY = 68719,
|
||||
QUARRY = 68720
|
||||
};
|
||||
|
||||
class BattleGroundICScore : public BattleGroundScore
|
||||
{
|
||||
public:
|
||||
BattleGroundICScore() {};
|
||||
virtual ~BattleGroundICScore() {};
|
||||
};
|
||||
|
||||
class BattleGroundIC : public BattleGround
|
||||
{
|
||||
friend class BattleGroundMgr;
|
||||
|
||||
public:
|
||||
BattleGroundIC();
|
||||
~BattleGroundIC();
|
||||
void Update(uint32 diff);
|
||||
|
||||
/* inherited from BattlegroundClass */
|
||||
virtual void AddPlayer(Player *plr);
|
||||
virtual void StartingEventCloseDoors();
|
||||
virtual void StartingEventOpenDoors();
|
||||
|
||||
void RemovePlayer(Player *plr,uint64 guid);
|
||||
void HandleAreaTrigger(Player *Source, uint32 Trigger);
|
||||
bool SetupBattleGround();
|
||||
void SpawnLeader(uint32 teamid);
|
||||
void HandleKillUnit(Creature *unit, Player *killer);
|
||||
void EndBattleGround(uint32 winner);
|
||||
void EventPlayerClickedOnFlag(Player *source, GameObject* /*target_obj*/);
|
||||
|
||||
/* Scorekeeping */
|
||||
void UpdatePlayerScore(Player *Source, uint32 type, uint32 value, bool doAddHonor = true);
|
||||
|
||||
private:
|
||||
};
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,276 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __BATTLEGROUNDMGR_H
|
||||
#define __BATTLEGROUNDMGR_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "Policies/Singleton.h"
|
||||
|
||||
#include "DBCEnums.h"
|
||||
#include "BattleGround.h"
|
||||
|
||||
typedef std::map<uint32, BattleGround*> BattleGroundSet;
|
||||
|
||||
//this container can't be deque, because deque doesn't like removing the last element - if you remove it, it invalidates next iterator and crash appears
|
||||
typedef std::list<BattleGround*> BGFreeSlotQueueType;
|
||||
|
||||
typedef UNORDERED_MAP<uint32, BattleGroundTypeId> BattleMastersMap;
|
||||
|
||||
#define BATTLEGROUND_ARENA_POINT_DISTRIBUTION_DAY 86400 // seconds in a day
|
||||
#define COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME 10
|
||||
#define WS_ARENA_DISTRIBUTION_TIME 20001 // Custom worldstate
|
||||
|
||||
struct GroupQueueInfo; // type predefinition
|
||||
struct PlayerQueueInfo // stores information for players in queue
|
||||
{
|
||||
uint32 LastOnlineTime; // for tracking and removing offline players from queue after 5 minutes
|
||||
GroupQueueInfo * GroupInfo; // pointer to the associated groupqueueinfo
|
||||
};
|
||||
|
||||
struct GroupQueueInfo // stores information about the group in queue (also used when joined as solo!)
|
||||
{
|
||||
std::map<uint64, PlayerQueueInfo*> Players; // player queue info map
|
||||
uint32 Team; // Player team (ALLIANCE/HORDE)
|
||||
BattleGroundTypeId BgTypeId; // battleground type id
|
||||
bool IsRated; // rated
|
||||
uint8 ArenaType; // 2v2, 3v3, 5v5 or 0 when BG
|
||||
uint32 ArenaTeamId; // team id if rated match
|
||||
uint32 JoinTime; // time when group was added
|
||||
uint32 RemoveInviteTime; // time when we will remove invite for players in group
|
||||
uint32 IsInvitedToBGInstanceGUID; // was invited to certain BG
|
||||
uint32 ArenaTeamRating; // if rated match, inited to the rating of the team
|
||||
uint32 OpponentsTeamRating; // for rated arena matches
|
||||
};
|
||||
|
||||
enum BattleGroundQueueGroupTypes
|
||||
{
|
||||
BG_QUEUE_PREMADE_ALLIANCE = 0,
|
||||
BG_QUEUE_PREMADE_HORDE = 1,
|
||||
BG_QUEUE_NORMAL_ALLIANCE = 2,
|
||||
BG_QUEUE_NORMAL_HORDE = 3
|
||||
};
|
||||
#define BG_QUEUE_GROUP_TYPES_COUNT 4
|
||||
|
||||
class BattleGround;
|
||||
class BattleGroundQueue
|
||||
{
|
||||
public:
|
||||
BattleGroundQueue();
|
||||
~BattleGroundQueue();
|
||||
|
||||
void Update(BattleGroundTypeId bgTypeId, BattleGroundBracketId bracket_id, uint8 arenaType = 0, bool isRated = false, uint32 minRating = 0);
|
||||
|
||||
void FillPlayersToBG(BattleGround* bg, BattleGroundBracketId bracket_id);
|
||||
bool CheckPremadeMatch(BattleGroundBracketId bracket_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam);
|
||||
bool CheckNormalMatch(BattleGround* bg_template, BattleGroundBracketId bracket_id, uint32 minPlayers, uint32 maxPlayers);
|
||||
bool CheckSkirmishForSameFaction(BattleGroundBracketId bracket_id, uint32 minPlayersPerTeam);
|
||||
GroupQueueInfo * AddGroup(Player* leader, Group* group, BattleGroundTypeId bgTypeId, PvPDifficultyEntry const* backetEntry, uint8 ArenaType, bool isRated, bool isPremade, uint32 ArenaRating, uint32 ArenaTeamId = 0);
|
||||
void RemovePlayer(const uint64& guid, bool decreaseInvitedCount);
|
||||
bool IsPlayerInvited(const uint64& pl_guid, const uint32 bgInstanceGuid, const uint32 removeTime);
|
||||
bool GetPlayerGroupInfoData(const uint64& guid, GroupQueueInfo* ginfo);
|
||||
void PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, BattleGroundBracketId bracket_id);
|
||||
uint32 GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BattleGroundBracketId bracket_id);
|
||||
|
||||
typedef std::map<uint64, PlayerQueueInfo> QueuedPlayersMap;
|
||||
QueuedPlayersMap m_QueuedPlayers;
|
||||
|
||||
//we need constant add to begin and constant remove / add from the end, therefore deque suits our problem well
|
||||
typedef std::list<GroupQueueInfo*> GroupsQueueType;
|
||||
|
||||
/*
|
||||
This two dimensional array is used to store All queued groups
|
||||
First dimension specifies the bgTypeId
|
||||
Second dimension specifies the player's group types -
|
||||
BG_QUEUE_PREMADE_ALLIANCE is used for premade alliance groups and alliance rated arena teams
|
||||
BG_QUEUE_PREMADE_HORDE is used for premade horde groups and horde rated arena teams
|
||||
BG_QUEUE_NORMAL_ALLIANCE is used for normal (or small) alliance groups or non-rated arena matches
|
||||
BG_QUEUE_NORMAL_HORDE is used for normal (or small) horde groups or non-rated arena matches
|
||||
*/
|
||||
GroupsQueueType m_QueuedGroups[MAX_BATTLEGROUND_BRACKETS][BG_QUEUE_GROUP_TYPES_COUNT];
|
||||
|
||||
// class to select and invite groups to bg
|
||||
class SelectionPool
|
||||
{
|
||||
public:
|
||||
void Init();
|
||||
bool AddGroup(GroupQueueInfo *ginfo, uint32 desiredCount);
|
||||
bool KickGroup(uint32 size);
|
||||
uint32 GetPlayerCount() const {return PlayerCount;}
|
||||
public:
|
||||
GroupsQueueType SelectedGroups;
|
||||
private:
|
||||
uint32 PlayerCount;
|
||||
};
|
||||
|
||||
//one selection pool for horde, other one for alliance
|
||||
SelectionPool m_SelectionPools[BG_TEAMS_COUNT];
|
||||
|
||||
private:
|
||||
|
||||
bool InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * bg, uint32 side);
|
||||
uint32 m_WaitTimes[BG_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME];
|
||||
uint32 m_WaitTimeLastPlayer[BG_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS];
|
||||
uint32 m_SumOfWaitTimes[BG_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS];
|
||||
};
|
||||
|
||||
/*
|
||||
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
|
||||
{
|
||||
public:
|
||||
BGQueueInviteEvent(const uint64& pl_guid, uint32 BgInstanceGUID, BattleGroundTypeId BgTypeId, uint8 arenaType, uint32 removeTime) :
|
||||
m_PlayerGuid(pl_guid), m_BgInstanceGUID(BgInstanceGUID), m_BgTypeId(BgTypeId), m_ArenaType(arenaType), m_RemoveTime(removeTime)
|
||||
{
|
||||
};
|
||||
virtual ~BGQueueInviteEvent() {};
|
||||
|
||||
virtual bool Execute(uint64 e_time, uint32 p_time);
|
||||
virtual void Abort(uint64 e_time);
|
||||
private:
|
||||
uint64 m_PlayerGuid;
|
||||
uint32 m_BgInstanceGUID;
|
||||
BattleGroundTypeId m_BgTypeId;
|
||||
uint8 m_ArenaType;
|
||||
uint32 m_RemoveTime;
|
||||
};
|
||||
|
||||
/*
|
||||
This class is used to remove player from BG queue after 1 minute 20 seconds from first invitation
|
||||
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
|
||||
{
|
||||
public:
|
||||
BGQueueRemoveEvent(const uint64& pl_guid, uint32 bgInstanceGUID, BattleGroundTypeId BgTypeId, BattleGroundQueueTypeId bgQueueTypeId, uint32 removeTime)
|
||||
: m_PlayerGuid(pl_guid), m_BgInstanceGUID(bgInstanceGUID), m_RemoveTime(removeTime), m_BgTypeId(BgTypeId), m_BgQueueTypeId(bgQueueTypeId)
|
||||
{}
|
||||
|
||||
virtual ~BGQueueRemoveEvent() {}
|
||||
|
||||
virtual bool Execute(uint64 e_time, uint32 p_time);
|
||||
virtual void Abort(uint64 e_time);
|
||||
private:
|
||||
uint64 m_PlayerGuid;
|
||||
uint32 m_BgInstanceGUID;
|
||||
uint32 m_RemoveTime;
|
||||
BattleGroundTypeId m_BgTypeId;
|
||||
BattleGroundQueueTypeId m_BgQueueTypeId;
|
||||
};
|
||||
|
||||
class BattleGroundMgr
|
||||
{
|
||||
public:
|
||||
/* Construction */
|
||||
BattleGroundMgr();
|
||||
~BattleGroundMgr();
|
||||
void Update(uint32 diff);
|
||||
|
||||
/* Packet Building */
|
||||
void BuildPlayerJoinedBattleGroundPacket(WorldPacket *data, Player *plr);
|
||||
void BuildPlayerLeftBattleGroundPacket(WorldPacket *data, const uint64& guid);
|
||||
void BuildBattleGroundListPacket(WorldPacket *data, const uint64& guid, Player *plr, BattleGroundTypeId bgTypeId, uint8 fromWhere);
|
||||
void BuildGroupJoinedBattlegroundPacket(WorldPacket *data, GroupJoinBattlegroundResult result);
|
||||
void BuildUpdateWorldStatePacket(WorldPacket *data, uint32 field, uint32 value);
|
||||
void BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg);
|
||||
void BuildBattleGroundStatusPacket(WorldPacket *data, BattleGround *bg, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint8 arenatype);
|
||||
void BuildPlaySoundPacket(WorldPacket *data, uint32 soundid);
|
||||
void SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround *bg, const uint64& guid);
|
||||
|
||||
/* Battlegrounds */
|
||||
BattleGround* GetBattleGroundThroughClientInstance(uint32 instanceId, BattleGroundTypeId bgTypeId);
|
||||
BattleGround* GetBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId); //there must be uint32 because MAX_BATTLEGROUND_TYPE_ID means unknown
|
||||
|
||||
BattleGround* GetBattleGroundTemplate(BattleGroundTypeId bgTypeId);
|
||||
BattleGround* CreateNewBattleGround(BattleGroundTypeId bgTypeId, PvPDifficultyEntry const* bracketEntry, uint8 arenaType, bool isRated);
|
||||
|
||||
uint32 CreateBattleGround(BattleGroundTypeId bgTypeId, bool IsArena, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam, uint32 LevelMin, uint32 LevelMax, char* BattleGroundName, uint32 MapID, float Team1StartLocX, float Team1StartLocY, float Team1StartLocZ, float Team1StartLocO, float Team2StartLocX, float Team2StartLocY, float Team2StartLocZ, float Team2StartLocO);
|
||||
|
||||
void AddBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId, BattleGround* BG) { m_BattleGrounds[bgTypeId][InstanceID] = BG; };
|
||||
void RemoveBattleGround(uint32 instanceID, BattleGroundTypeId bgTypeId) { m_BattleGrounds[bgTypeId].erase(instanceID); }
|
||||
uint32 CreateClientVisibleInstanceId(BattleGroundTypeId bgTypeId, BattleGroundBracketId bracket_id);
|
||||
|
||||
void CreateInitialBattleGrounds();
|
||||
void DeleteAllBattleGrounds();
|
||||
|
||||
void SendToBattleGround(Player *pl, uint32 InstanceID, BattleGroundTypeId bgTypeId);
|
||||
|
||||
/* Battleground queues */
|
||||
//these queues are instantiated when creating BattlegroundMrg
|
||||
BattleGroundQueue m_BattleGroundQueues[MAX_BATTLEGROUND_QUEUE_TYPES]; // public, because we need to access them in BG handler code
|
||||
|
||||
BGFreeSlotQueueType BGFreeSlotQueue[MAX_BATTLEGROUND_TYPE_ID];
|
||||
|
||||
void ScheduleQueueUpdate(uint32 arenaRating, uint8 arenaType, BattleGroundQueueTypeId bgQueueTypeId, BattleGroundTypeId bgTypeId, BattleGroundBracketId bracket_id);
|
||||
uint32 GetMaxRatingDifference() const;
|
||||
uint32 GetRatingDiscardTimer() const;
|
||||
uint32 GetPrematureFinishTime() const;
|
||||
|
||||
void InitAutomaticArenaPointDistribution();
|
||||
void DistributeArenaPoints();
|
||||
void ToggleArenaTesting();
|
||||
void ToggleTesting();
|
||||
|
||||
void SetHolidayWeekends(uint32 mask);
|
||||
void LoadBattleMastersEntry();
|
||||
BattleGroundTypeId GetBattleMasterBG(uint32 entry) const
|
||||
{
|
||||
BattleMastersMap::const_iterator itr = mBattleMastersMap.find(entry);
|
||||
if (itr != mBattleMastersMap.end())
|
||||
return itr->second;
|
||||
return BATTLEGROUND_WS;
|
||||
}
|
||||
|
||||
bool isArenaTesting() const { return m_ArenaTesting; }
|
||||
bool isTesting() const { return m_Testing; }
|
||||
|
||||
static bool IsArenaType(BattleGroundTypeId bgTypeId);
|
||||
static bool IsBattleGroundType(BattleGroundTypeId bgTypeId) { return !BattleGroundMgr::IsArenaType(bgTypeId); }
|
||||
static BattleGroundQueueTypeId BGQueueTypeId(BattleGroundTypeId bgTypeId, uint8 arenaType);
|
||||
static BattleGroundTypeId BGTemplateId(BattleGroundQueueTypeId bgQueueTypeId);
|
||||
static uint8 BGArenaType(BattleGroundQueueTypeId bgQueueTypeId);
|
||||
|
||||
static HolidayIds BGTypeToWeekendHolidayId(BattleGroundTypeId bgTypeId);
|
||||
static BattleGroundTypeId WeekendHolidayIdToBGType(HolidayIds holiday);
|
||||
static bool IsBGWeekend(BattleGroundTypeId bgTypeId);
|
||||
void DoCompleteAchievement(uint32 achievement, Player * player = NULL);
|
||||
private:
|
||||
BattleMastersMap mBattleMastersMap;
|
||||
|
||||
typedef std::vector<BattleGroundTypeId> BattleGroundTypeIdList;
|
||||
/* Battlegrounds */
|
||||
BattleGroundSet m_BattleGrounds[MAX_BATTLEGROUND_TYPE_ID];
|
||||
BattleGroundTypeIdList m_EnabledArenas;
|
||||
BattleGroundTypeIdList m_EnabledBGs;
|
||||
std::vector<uint64> m_QueueUpdateScheduler;
|
||||
std::set<uint32> m_ClientBattleGroundIds[MAX_BATTLEGROUND_TYPE_ID][MAX_BATTLEGROUND_BRACKETS]; //the instanceids just visible for the client
|
||||
uint32 m_NextRatingDiscardUpdate;
|
||||
time_t m_NextAutoDistributionTime;
|
||||
uint32 m_AutoDistributionTimeChecker;
|
||||
bool m_ArenaTesting;
|
||||
bool m_Testing;
|
||||
};
|
||||
|
||||
#define sBattleGroundMgr Trinity::Singleton<BattleGroundMgr>::Instance()
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "BattleGround.h"
|
||||
#include "BattleGroundNA.h"
|
||||
#include "Language.h"
|
||||
#include "Object.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Player.h"
|
||||
#include "WorldPacket.h"
|
||||
|
||||
BattleGroundNA::BattleGroundNA()
|
||||
{
|
||||
m_BgObjects.resize(BG_NA_OBJECT_MAX);
|
||||
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE;
|
||||
//we must set messageIds
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattleGroundNA::~BattleGroundNA()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void BattleGroundNA::Update(uint32 diff)
|
||||
{
|
||||
BattleGround::Update(diff);
|
||||
|
||||
/*if (GetStatus() == STATUS_IN_PROGRESS)
|
||||
{
|
||||
// update something
|
||||
}*/
|
||||
}
|
||||
|
||||
void BattleGroundNA::StartingEventCloseDoors()
|
||||
{
|
||||
for (uint32 i = BG_NA_OBJECT_DOOR_1; i <= BG_NA_OBJECT_DOOR_4; ++i)
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
}
|
||||
|
||||
void BattleGroundNA::StartingEventOpenDoors()
|
||||
{
|
||||
for (uint32 i = BG_NA_OBJECT_DOOR_1; i <= BG_NA_OBJECT_DOOR_2; ++i)
|
||||
DoorOpen(i);
|
||||
|
||||
for (uint32 i = BG_NA_OBJECT_BUFF_1; i <= BG_NA_OBJECT_BUFF_2; ++i)
|
||||
SpawnBGObject(i, 60);
|
||||
}
|
||||
|
||||
void BattleGroundNA::AddPlayer(Player *plr)
|
||||
{
|
||||
BattleGround::AddPlayer(plr);
|
||||
//create score and add it to map, default values are set in constructor
|
||||
BattleGroundNAScore* sc = new BattleGroundNAScore;
|
||||
|
||||
m_PlayerScores[plr->GetGUID()] = sc;
|
||||
|
||||
UpdateArenaWorldState();
|
||||
}
|
||||
|
||||
void BattleGroundNA::RemovePlayer(Player* /*plr*/, uint64 /*guid*/)
|
||||
{
|
||||
if (GetStatus() == STATUS_WAIT_LEAVE)
|
||||
return;
|
||||
|
||||
UpdateArenaWorldState();
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
|
||||
void BattleGroundNA::HandleKillPlayer(Player *player, Player *killer)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
if (!killer)
|
||||
{
|
||||
sLog.outError("BattleGroundNA: Killer player not found");
|
||||
return;
|
||||
}
|
||||
|
||||
BattleGround::HandleKillPlayer(player,killer);
|
||||
|
||||
UpdateArenaWorldState();
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
|
||||
bool BattleGroundNA::HandlePlayerUnderMap(Player *player)
|
||||
{
|
||||
player->TeleportTo(GetMapId(),4055.504395,2919.660645,13.611241,player->GetOrientation(),false);
|
||||
return true;
|
||||
}
|
||||
|
||||
void BattleGroundNA::HandleAreaTrigger(Player *Source, uint32 Trigger)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
//uint32 SpellId = 0;
|
||||
//uint64 buff_guid = 0;
|
||||
switch(Trigger)
|
||||
{
|
||||
case 4536: // buff trigger?
|
||||
case 4537: // buff trigger?
|
||||
break;
|
||||
default:
|
||||
sLog.outError("WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger);
|
||||
Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger);
|
||||
break;
|
||||
}
|
||||
|
||||
//if (buff_guid)
|
||||
// HandleTriggerBuff(buff_guid,Source);
|
||||
}
|
||||
|
||||
void BattleGroundNA::FillInitialWorldStates(WorldPacket &data)
|
||||
{
|
||||
data << uint32(0xa11) << uint32(1); // 9
|
||||
UpdateArenaWorldState();
|
||||
}
|
||||
|
||||
void BattleGroundNA::Reset()
|
||||
{
|
||||
//call parent's class reset
|
||||
BattleGround::Reset();
|
||||
}
|
||||
|
||||
bool BattleGroundNA::SetupBattleGround()
|
||||
{
|
||||
// gates
|
||||
if (!AddObject(BG_NA_OBJECT_DOOR_1, BG_NA_OBJECT_TYPE_DOOR_1, 4031.854, 2966.833, 12.6462, -2.648788, 0, 0, 0.9697962, -0.2439165, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_NA_OBJECT_DOOR_2, BG_NA_OBJECT_TYPE_DOOR_2, 4081.179, 2874.97, 12.39171, 0.4928045, 0, 0, 0.2439165, 0.9697962, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_NA_OBJECT_DOOR_3, BG_NA_OBJECT_TYPE_DOOR_3, 4023.709, 2981.777, 10.70117, -2.648788, 0, 0, 0.9697962, -0.2439165, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_NA_OBJECT_DOOR_4, BG_NA_OBJECT_TYPE_DOOR_4, 4090.064, 2858.438, 10.23631, 0.4928045, 0, 0, 0.2439165, 0.9697962, RESPAWN_IMMEDIATELY)
|
||||
// buffs
|
||||
|| !AddObject(BG_NA_OBJECT_BUFF_1, BG_NA_OBJECT_TYPE_BUFF_1, 4009.189941, 2895.250000, 13.052700, -1.448624, 0, 0, 0.6626201, -0.7489557, 120)
|
||||
|| !AddObject(BG_NA_OBJECT_BUFF_2, BG_NA_OBJECT_TYPE_BUFF_2, 4103.330078, 2946.350098, 13.051300, -0.06981307, 0, 0, 0.03489945, -0.9993908, 120))
|
||||
{
|
||||
sLog.outErrorDb("BatteGroundNA: Failed to spawn some object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
20:12:14 id:036668 [S2C] SMSG_INIT_WORLD_STATES (706 = 0x02C2) len: 86
|
||||
0000: 2f 02 00 00 72 0e 00 00 00 00 00 00 09 00 11 0a | /...r...........
|
||||
0010: 00 00 01 00 00 00 0f 0a 00 00 00 00 00 00 10 0a | ................
|
||||
0020: 00 00 00 00 00 00 d4 08 00 00 00 00 00 00 d8 08 | ................
|
||||
0030: 00 00 00 00 00 00 d7 08 00 00 00 00 00 00 d6 08 | ................
|
||||
0040: 00 00 00 00 00 00 d5 08 00 00 00 00 00 00 d3 08 | ................
|
||||
0050: 00 00 00 00 00 00 | ......
|
||||
*/
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __BATTLEGROUNDNA_H
|
||||
#define __BATTLEGROUNDNA_H
|
||||
|
||||
class BattleGround;
|
||||
|
||||
enum BattleGroundNAObjectTypes
|
||||
{
|
||||
BG_NA_OBJECT_DOOR_1 = 0,
|
||||
BG_NA_OBJECT_DOOR_2 = 1,
|
||||
BG_NA_OBJECT_DOOR_3 = 2,
|
||||
BG_NA_OBJECT_DOOR_4 = 3,
|
||||
BG_NA_OBJECT_BUFF_1 = 4,
|
||||
BG_NA_OBJECT_BUFF_2 = 5,
|
||||
BG_NA_OBJECT_MAX = 6
|
||||
};
|
||||
|
||||
enum BattleGroundNAObjects
|
||||
{
|
||||
BG_NA_OBJECT_TYPE_DOOR_1 = 183978,
|
||||
BG_NA_OBJECT_TYPE_DOOR_2 = 183980,
|
||||
BG_NA_OBJECT_TYPE_DOOR_3 = 183977,
|
||||
BG_NA_OBJECT_TYPE_DOOR_4 = 183979,
|
||||
BG_NA_OBJECT_TYPE_BUFF_1 = 184663,
|
||||
BG_NA_OBJECT_TYPE_BUFF_2 = 184664
|
||||
};
|
||||
|
||||
class BattleGroundNAScore : public BattleGroundScore
|
||||
{
|
||||
public:
|
||||
BattleGroundNAScore() {};
|
||||
virtual ~BattleGroundNAScore() {};
|
||||
//TODO fix me
|
||||
};
|
||||
|
||||
class BattleGroundNA : public BattleGround
|
||||
{
|
||||
friend class BattleGroundMgr;
|
||||
|
||||
public:
|
||||
BattleGroundNA();
|
||||
~BattleGroundNA();
|
||||
void Update(uint32 diff);
|
||||
|
||||
/* inherited from BattlegroundClass */
|
||||
virtual void AddPlayer(Player *plr);
|
||||
virtual void StartingEventCloseDoors();
|
||||
virtual void StartingEventOpenDoors();
|
||||
|
||||
void RemovePlayer(Player *plr, uint64 guid);
|
||||
void HandleAreaTrigger(Player *Source, uint32 Trigger);
|
||||
bool SetupBattleGround();
|
||||
virtual void Reset();
|
||||
virtual void FillInitialWorldStates(WorldPacket &d);
|
||||
void HandleKillPlayer(Player* player, Player *killer);
|
||||
bool HandlePlayerUnderMap(Player * plr);
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Player.h"
|
||||
#include "BattleGround.h"
|
||||
#include "BattleGroundRB.h"
|
||||
#include "Language.h"
|
||||
|
||||
BattleGroundRB::BattleGroundRB()
|
||||
{
|
||||
//TODO FIX ME!
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = 0;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_WS_START_ONE_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_WS_START_HALF_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_WS_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattleGroundRB::~BattleGroundRB()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void BattleGroundRB::Update(uint32 diff)
|
||||
{
|
||||
BattleGround::Update(diff);
|
||||
}
|
||||
|
||||
void BattleGroundRB::StartingEventCloseDoors()
|
||||
{
|
||||
}
|
||||
|
||||
void BattleGroundRB::StartingEventOpenDoors()
|
||||
{
|
||||
}
|
||||
|
||||
void BattleGroundRB::AddPlayer(Player *plr)
|
||||
{
|
||||
BattleGround::AddPlayer(plr);
|
||||
//create score and add it to map, default values are set in constructor
|
||||
BattleGroundRBScore* sc = new BattleGroundRBScore;
|
||||
|
||||
m_PlayerScores[plr->GetGUID()] = sc;
|
||||
}
|
||||
|
||||
void BattleGroundRB::RemovePlayer(Player* /*plr*/,uint64 /*guid*/)
|
||||
{
|
||||
}
|
||||
|
||||
void BattleGroundRB::HandleAreaTrigger(Player * /*Source*/, uint32 /*Trigger*/)
|
||||
{
|
||||
// this is wrong way to implement these things. On official it done by gameobject spell cast.
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
}
|
||||
|
||||
void BattleGroundRB::UpdatePlayerScore(Player* Source, uint32 type, uint32 value, bool doAddHonor)
|
||||
{
|
||||
std::map<uint64, BattleGroundScore*>::iterator itr = m_PlayerScores.find(Source->GetGUID());
|
||||
|
||||
if (itr == m_PlayerScores.end()) // player not found...
|
||||
return;
|
||||
|
||||
BattleGround::UpdatePlayerScore(Source,type,value, doAddHonor);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __BATTLEGROUNDRB_H
|
||||
#define __BATTLEGROUNDRB_H
|
||||
|
||||
class BattleGround;
|
||||
|
||||
class BattleGroundRBScore : public BattleGroundScore
|
||||
{
|
||||
public:
|
||||
BattleGroundRBScore() {};
|
||||
virtual ~BattleGroundRBScore() {};
|
||||
};
|
||||
|
||||
class BattleGroundRB : public BattleGround
|
||||
{
|
||||
friend class BattleGroundMgr;
|
||||
|
||||
public:
|
||||
BattleGroundRB();
|
||||
~BattleGroundRB();
|
||||
void Update(uint32 diff);
|
||||
|
||||
virtual void AddPlayer(Player *plr);
|
||||
virtual void StartingEventCloseDoors();
|
||||
virtual void StartingEventOpenDoors();
|
||||
|
||||
void RemovePlayer(Player *plr,uint64 guid);
|
||||
void HandleAreaTrigger(Player *Source, uint32 Trigger);
|
||||
|
||||
/* Scorekeeping */
|
||||
void UpdatePlayerScore(Player *Source, uint32 type, uint32 value, bool doAddHonor = true);
|
||||
|
||||
private:
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "BattleGround.h"
|
||||
#include "BattleGroundRL.h"
|
||||
#include "Language.h"
|
||||
#include "Object.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Player.h"
|
||||
#include "WorldPacket.h"
|
||||
|
||||
BattleGroundRL::BattleGroundRL()
|
||||
{
|
||||
m_BgObjects.resize(BG_RL_OBJECT_MAX);
|
||||
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE;
|
||||
//we must set messageIds
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattleGroundRL::~BattleGroundRL()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void BattleGroundRL::Update(uint32 diff)
|
||||
{
|
||||
BattleGround::Update(diff);
|
||||
|
||||
/*if (GetStatus() == STATUS_IN_PROGRESS)
|
||||
{
|
||||
// update something
|
||||
}*/
|
||||
}
|
||||
|
||||
void BattleGroundRL::StartingEventCloseDoors()
|
||||
{
|
||||
for (uint32 i = BG_RL_OBJECT_DOOR_1; i <= BG_RL_OBJECT_DOOR_2; ++i)
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
}
|
||||
|
||||
void BattleGroundRL::StartingEventOpenDoors()
|
||||
{
|
||||
for (uint32 i = BG_RL_OBJECT_DOOR_1; i <= BG_RL_OBJECT_DOOR_2; ++i)
|
||||
DoorOpen(i);
|
||||
|
||||
for (uint32 i = BG_RL_OBJECT_BUFF_1; i <= BG_RL_OBJECT_BUFF_2; ++i)
|
||||
SpawnBGObject(i, 60);
|
||||
}
|
||||
|
||||
void BattleGroundRL::AddPlayer(Player *plr)
|
||||
{
|
||||
BattleGround::AddPlayer(plr);
|
||||
//create score and add it to map, default values are set in constructor
|
||||
BattleGroundRLScore* sc = new BattleGroundRLScore;
|
||||
|
||||
m_PlayerScores[plr->GetGUID()] = sc;
|
||||
|
||||
UpdateArenaWorldState();
|
||||
}
|
||||
|
||||
void BattleGroundRL::RemovePlayer(Player* /*plr*/, uint64 /*guid*/)
|
||||
{
|
||||
if (GetStatus() == STATUS_WAIT_LEAVE)
|
||||
return;
|
||||
|
||||
UpdateArenaWorldState();
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
|
||||
void BattleGroundRL::HandleKillPlayer(Player *player, Player *killer)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
if (!killer)
|
||||
{
|
||||
sLog.outError("Killer player not found");
|
||||
return;
|
||||
}
|
||||
|
||||
BattleGround::HandleKillPlayer(player,killer);
|
||||
|
||||
UpdateArenaWorldState();
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
|
||||
bool BattleGroundRL::HandlePlayerUnderMap(Player *player)
|
||||
{
|
||||
player->TeleportTo(GetMapId(),1285.810547,1667.896851,39.957642,player->GetOrientation(),false);
|
||||
return true;
|
||||
}
|
||||
|
||||
void BattleGroundRL::HandleAreaTrigger(Player *Source, uint32 Trigger)
|
||||
{
|
||||
// this is wrong way to implement these things. On official it done by gameobject spell cast.
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
//uint32 SpellId = 0;
|
||||
//uint64 buff_guid = 0;
|
||||
switch(Trigger)
|
||||
{
|
||||
case 4696: // buff trigger?
|
||||
case 4697: // buff trigger?
|
||||
break;
|
||||
default:
|
||||
sLog.outError("WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger);
|
||||
Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger);
|
||||
break;
|
||||
}
|
||||
|
||||
//if (buff_guid)
|
||||
// HandleTriggerBuff(buff_guid,Source);
|
||||
}
|
||||
|
||||
void BattleGroundRL::FillInitialWorldStates(WorldPacket &data)
|
||||
{
|
||||
data << uint32(0xbba) << uint32(1); // 9
|
||||
UpdateArenaWorldState();
|
||||
}
|
||||
|
||||
void BattleGroundRL::Reset()
|
||||
{
|
||||
//call parent's reset
|
||||
BattleGround::Reset();
|
||||
}
|
||||
|
||||
bool BattleGroundRL::SetupBattleGround()
|
||||
{
|
||||
// gates
|
||||
if (!AddObject(BG_RL_OBJECT_DOOR_1, BG_RL_OBJECT_TYPE_DOOR_1, 1293.561, 1601.938, 31.60557, -1.457349, 0, 0, -0.6658813, 0.7460576, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_RL_OBJECT_DOOR_2, BG_RL_OBJECT_TYPE_DOOR_2, 1278.648, 1730.557, 31.60557, 1.684245, 0, 0, 0.7460582, 0.6658807, RESPAWN_IMMEDIATELY)
|
||||
// buffs
|
||||
|| !AddObject(BG_RL_OBJECT_BUFF_1, BG_RL_OBJECT_TYPE_BUFF_1, 1328.719971, 1632.719971, 36.730400, -1.448624, 0, 0, 0.6626201, -0.7489557, 120)
|
||||
|| !AddObject(BG_RL_OBJECT_BUFF_2, BG_RL_OBJECT_TYPE_BUFF_2, 1243.300049, 1699.170044, 34.872601, -0.06981307, 0, 0, 0.03489945, -0.9993908, 120))
|
||||
{
|
||||
sLog.outErrorDb("BatteGroundRL: Failed to spawn some object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
Packet S->C, id 600, SMSG_INIT_WORLD_STATES (706), len 86
|
||||
0000: 3C 02 00 00 80 0F 00 00 00 00 00 00 09 00 BA 0B | <...............
|
||||
0010: 00 00 01 00 00 00 B9 0B 00 00 02 00 00 00 B8 0B | ................
|
||||
0020: 00 00 00 00 00 00 D8 08 00 00 00 00 00 00 D7 08 | ................
|
||||
0030: 00 00 00 00 00 00 D6 08 00 00 00 00 00 00 D5 08 | ................
|
||||
0040: 00 00 00 00 00 00 D3 08 00 00 00 00 00 00 D4 08 | ................
|
||||
0050: 00 00 00 00 00 00 | ......
|
||||
*/
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __BATTLEGROUNDRL_H
|
||||
#define __BATTLEGROUNDRL_H
|
||||
|
||||
class BattleGround;
|
||||
|
||||
enum BattleGroundRLObjectTypes
|
||||
{
|
||||
BG_RL_OBJECT_DOOR_1 = 0,
|
||||
BG_RL_OBJECT_DOOR_2 = 1,
|
||||
BG_RL_OBJECT_BUFF_1 = 2,
|
||||
BG_RL_OBJECT_BUFF_2 = 3,
|
||||
BG_RL_OBJECT_MAX = 4
|
||||
};
|
||||
|
||||
enum BattleGroundRLObjects
|
||||
{
|
||||
BG_RL_OBJECT_TYPE_DOOR_1 = 185918,
|
||||
BG_RL_OBJECT_TYPE_DOOR_2 = 185917,
|
||||
BG_RL_OBJECT_TYPE_BUFF_1 = 184663,
|
||||
BG_RL_OBJECT_TYPE_BUFF_2 = 184664
|
||||
};
|
||||
|
||||
class BattleGroundRLScore : public BattleGroundScore
|
||||
{
|
||||
public:
|
||||
BattleGroundRLScore() {};
|
||||
virtual ~BattleGroundRLScore() {};
|
||||
//TODO fix me
|
||||
};
|
||||
|
||||
class BattleGroundRL : public BattleGround
|
||||
{
|
||||
friend class BattleGroundMgr;
|
||||
|
||||
public:
|
||||
BattleGroundRL();
|
||||
~BattleGroundRL();
|
||||
void Update(uint32 diff);
|
||||
|
||||
/* inherited from BattlegroundClass */
|
||||
virtual void AddPlayer(Player *plr);
|
||||
virtual void Reset();
|
||||
virtual void FillInitialWorldStates(WorldPacket &d);
|
||||
virtual void StartingEventCloseDoors();
|
||||
virtual void StartingEventOpenDoors();
|
||||
|
||||
void RemovePlayer(Player *plr, uint64 guid);
|
||||
void HandleAreaTrigger(Player *Source, uint32 Trigger);
|
||||
bool SetupBattleGround();
|
||||
void HandleKillPlayer(Player* player, Player *killer);
|
||||
bool HandlePlayerUnderMap(Player * plr);
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "BattleGround.h"
|
||||
#include "BattleGroundRV.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Language.h"
|
||||
#include "Player.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "GameObject.h"
|
||||
|
||||
BattleGroundRV::BattleGroundRV()
|
||||
{
|
||||
m_BgObjects.resize(BG_RV_OBJECT_MAX);
|
||||
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
|
||||
m_StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE;
|
||||
//we must set messageIds
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattleGroundRV::~BattleGroundRV()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void BattleGroundRV::Update(uint32 diff)
|
||||
{
|
||||
BattleGround::Update(diff);
|
||||
|
||||
if (getTimer() < diff)
|
||||
{
|
||||
uint32 i;
|
||||
switch(getState())
|
||||
{
|
||||
case BG_RV_STATE_OPEN_FENCES:
|
||||
{
|
||||
setTimer(BG_RV_PILAR_TO_FIRE_TIMER);
|
||||
setState(BG_RV_STATE_CLOSE_FIRE);
|
||||
break;
|
||||
}
|
||||
case BG_RV_STATE_CLOSE_FIRE:
|
||||
for (i = BG_RV_OBJECT_FIRE_1; i <= BG_RV_OBJECT_FIREDOOR_2; ++i)
|
||||
DoorClose(i);
|
||||
setTimer(BG_RV_FIRE_TO_PILAR_TIMER);
|
||||
setState(BG_RV_STATE_OPEN_PILARS);
|
||||
break;
|
||||
case BG_RV_STATE_OPEN_PILARS:
|
||||
for (i = BG_RV_OBJECT_PILAR_1; i <= BG_RV_OBJECT_PULLEY_2; ++i)
|
||||
DoorOpen(i);
|
||||
setTimer(BG_RV_PILAR_TO_FIRE_TIMER);
|
||||
setState(BG_RV_STATE_OPEN_FIRE);
|
||||
break;
|
||||
case BG_RV_STATE_OPEN_FIRE:
|
||||
for (i = BG_RV_OBJECT_FIRE_1; i <= BG_RV_OBJECT_FIREDOOR_2; ++i)
|
||||
DoorOpen(i);
|
||||
setTimer(BG_RV_FIRE_TO_PILAR_TIMER);
|
||||
setState(BG_RV_STATE_CLOSE_PILARS);
|
||||
break;
|
||||
case BG_RV_STATE_CLOSE_PILARS:
|
||||
uint32 i;
|
||||
for (i = BG_RV_OBJECT_PILAR_1; i <= BG_RV_OBJECT_PULLEY_2; ++i)
|
||||
DoorOpen(i);
|
||||
setTimer(BG_RV_PILAR_TO_FIRE_TIMER);
|
||||
setState(BG_RV_STATE_CLOSE_FIRE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
setTimer(getTimer() - diff);
|
||||
}
|
||||
|
||||
void BattleGroundRV::StartingEventCloseDoors()
|
||||
{
|
||||
}
|
||||
|
||||
void BattleGroundRV::StartingEventOpenDoors()
|
||||
{
|
||||
// Buff respawn
|
||||
SpawnBGObject(BG_RV_OBJECT_BUFF_1, 90);
|
||||
SpawnBGObject(BG_RV_OBJECT_BUFF_2, 90);
|
||||
// Open fences
|
||||
DoorOpen(BG_RV_OBJECT_FENCE_1);
|
||||
DoorOpen(BG_RV_OBJECT_FENCE_2);
|
||||
// Elevators
|
||||
DoorOpen(BG_RV_OBJECT_ELEVATOR_1);
|
||||
DoorOpen(BG_RV_OBJECT_ELEVATOR_2);
|
||||
|
||||
setState(BG_RV_STATE_OPEN_FENCES);
|
||||
setTimer(BG_RV_FIRST_TIMER);
|
||||
}
|
||||
|
||||
void BattleGroundRV::AddPlayer(Player *plr)
|
||||
{
|
||||
BattleGround::AddPlayer(plr);
|
||||
//create score and add it to map, default values are set in constructor
|
||||
BattleGroundRVScore* sc = new BattleGroundRVScore;
|
||||
|
||||
m_PlayerScores[plr->GetGUID()] = sc;
|
||||
|
||||
UpdateWorldState(BG_RV_WORLD_STATE_A, GetAlivePlayersCountByTeam(ALLIANCE));
|
||||
UpdateWorldState(BG_RV_WORLD_STATE_H, GetAlivePlayersCountByTeam(HORDE));
|
||||
}
|
||||
|
||||
void BattleGroundRV::RemovePlayer(Player * /*plr*/, uint64 /*guid*/)
|
||||
{
|
||||
if (GetStatus() == STATUS_WAIT_LEAVE)
|
||||
return;
|
||||
|
||||
UpdateWorldState(BG_RV_WORLD_STATE_A, GetAlivePlayersCountByTeam(ALLIANCE));
|
||||
UpdateWorldState(BG_RV_WORLD_STATE_H, GetAlivePlayersCountByTeam(HORDE));
|
||||
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
|
||||
void BattleGroundRV::HandleKillPlayer(Player *player, Player *killer)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
if (!killer)
|
||||
{
|
||||
sLog.outError("BattleGroundRV: Killer player not found");
|
||||
return;
|
||||
}
|
||||
|
||||
BattleGround::HandleKillPlayer(player, killer);
|
||||
|
||||
UpdateWorldState(BG_RV_WORLD_STATE_A, GetAlivePlayersCountByTeam(ALLIANCE));
|
||||
UpdateWorldState(BG_RV_WORLD_STATE_H, GetAlivePlayersCountByTeam(HORDE));
|
||||
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
|
||||
bool BattleGroundRV::HandlePlayerUnderMap(Player *player)
|
||||
{
|
||||
player->TeleportTo(GetMapId(), 763.5, -284, 28.276, 2.422, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void BattleGroundRV::HandleAreaTrigger(Player *Source, uint32 Trigger)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
switch(Trigger)
|
||||
{
|
||||
case 5224:
|
||||
case 5226:
|
||||
break;
|
||||
default:
|
||||
sLog.outError("WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger);
|
||||
Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void BattleGroundRV::FillInitialWorldStates(WorldPacket &data)
|
||||
{
|
||||
data << uint32(BG_RV_WORLD_STATE_A) << uint32(GetAlivePlayersCountByTeam(ALLIANCE));
|
||||
data << uint32(BG_RV_WORLD_STATE_H) << uint32(GetAlivePlayersCountByTeam(HORDE));
|
||||
data << uint32(BG_RV_WORLD_STATE) << uint32(1);
|
||||
}
|
||||
|
||||
void BattleGroundRV::Reset()
|
||||
{
|
||||
//call parent's class reset
|
||||
BattleGround::Reset();
|
||||
}
|
||||
|
||||
bool BattleGroundRV::SetupBattleGround()
|
||||
{
|
||||
// Fence
|
||||
if (!AddObject(BG_RV_OBJECT_FENCE_1, BG_RV_OBJECT_TYPE_FENCE_1, 763.432373, -274.058197, 28.276695, 3.141593, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_RV_OBJECT_FENCE_2, BG_RV_OBJECT_TYPE_FENCE_2, 763.432373, -294.419464, 28.276684, 3.141593, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
// elevators
|
||||
|| !AddObject(BG_RV_OBJECT_ELEVATOR_1, BG_RV_OBJECT_TYPE_ELEVATOR_1, 763.536377, -294.535767, 0.505383, 3.141593, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_RV_OBJECT_ELEVATOR_2, BG_RV_OBJECT_TYPE_ELEVATOR_2, 763.506348, -273.873352, 0.505383, 0.000000, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
// buffs
|
||||
|| !AddObject(BG_RV_OBJECT_BUFF_1, BG_RV_OBJECT_TYPE_BUFF_1, 735.551819, -284.794678, 28.276682, 0.034906, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_RV_OBJECT_BUFF_2, BG_RV_OBJECT_TYPE_BUFF_2, 791.224487, -284.794464, 28.276682, 2.600535, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
// fire
|
||||
|| !AddObject(BG_RV_OBJECT_FIRE_1, BG_RV_OBJECT_TYPE_FIRE_1, 743.543457, -283.799469, 28.286655, 3.141593, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_RV_OBJECT_FIRE_2, BG_RV_OBJECT_TYPE_FIRE_2, 782.971802, -283.799469, 28.286655, 3.141593, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_RV_OBJECT_FIREDOOR_1, BG_RV_OBJECT_TYPE_FIREDOOR_1, 743.711060, -284.099609, 27.542587, 3.141593, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_RV_OBJECT_FIREDOOR_2, BG_RV_OBJECT_TYPE_FIREDOOR_2, 783.221252, -284.133362, 27.535686, 0.000000, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
// Gear
|
||||
|| !AddObject(BG_RV_OBJECT_GEAR_1, BG_RV_OBJECT_TYPE_GEAR_1, 763.664551, -261.872986, 26.686588, 0.000000, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_RV_OBJECT_GEAR_2, BG_RV_OBJECT_TYPE_GEAR_2, 763.578979, -306.146149, 26.665222, 3.141593, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
// Pulley
|
||||
|| !AddObject(BG_RV_OBJECT_PULLEY_1, BG_RV_OBJECT_TYPE_PULLEY_1, 700.722290, -283.990662, 39.517582, 3.141593, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_RV_OBJECT_PULLEY_2, BG_RV_OBJECT_TYPE_PULLEY_2, 826.303833, -283.996429, 39.517582, 0.000000, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
// Pilars
|
||||
|| !AddObject(BG_RV_OBJECT_PILAR_1, BG_RV_OBJECT_TYPE_PILAR_1, 763.632385, -306.162384, 25.909504, 3.141593, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_RV_OBJECT_PILAR_2, BG_RV_OBJECT_TYPE_PILAR_2, 723.644287, -284.493256, 24.648525, 3.141593, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_RV_OBJECT_PILAR_3, BG_RV_OBJECT_TYPE_PILAR_3, 763.611145, -261.856750, 25.909504, 0.000000, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_RV_OBJECT_PILAR_4, BG_RV_OBJECT_TYPE_PILAR_4, 802.211609, -284.493256, 24.648525, 0.000000, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
/*
|
||||
// Pilars Collision - Fixme: Use the collision pilars - should make u break LoS
|
||||
|| !AddObject(BG_RV_OBJECT_PILAR_COLLISION_1, BG_RV_OBJECT_TYPE_PILAR_COLLISION_1, 763.632385, -306.162384, 30.639660, 3.141593, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_RV_OBJECT_PILAR_COLLISION_2, BG_RV_OBJECT_TYPE_PILAR_COLLISION_2, 723.644287, -284.493256, 32.382710, 0.000000, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_RV_OBJECT_PILAR_COLLISION_3, BG_RV_OBJECT_TYPE_PILAR_COLLISION_3, 763.611145, -261.856750, 30.639660, 0.000000, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_RV_OBJECT_PILAR_COLLISION_4, BG_RV_OBJECT_TYPE_PILAR_COLLISION_4, 802.211609, -284.493256, 32.382710, 3.141593, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
*/
|
||||
)
|
||||
{
|
||||
sLog.outErrorDb("BatteGroundRV: Failed to spawn some object!");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __BATTLEGROUNDRV_H
|
||||
#define __BATTLEGROUNDRV_H
|
||||
|
||||
class BattleGround;
|
||||
|
||||
enum BattleGroundRVObjectTypes
|
||||
{
|
||||
BG_RV_OBJECT_BUFF_1,
|
||||
BG_RV_OBJECT_BUFF_2,
|
||||
BG_RV_OBJECT_FIRE_1,
|
||||
BG_RV_OBJECT_FIRE_2,
|
||||
BG_RV_OBJECT_FIREDOOR_1,
|
||||
BG_RV_OBJECT_FIREDOOR_2,
|
||||
|
||||
BG_RV_OBJECT_PILAR_1,
|
||||
BG_RV_OBJECT_PILAR_3,
|
||||
BG_RV_OBJECT_GEAR_1,
|
||||
BG_RV_OBJECT_GEAR_2,
|
||||
|
||||
BG_RV_OBJECT_PILAR_2,
|
||||
BG_RV_OBJECT_PILAR_4,
|
||||
BG_RV_OBJECT_PULLEY_1,
|
||||
BG_RV_OBJECT_PULLEY_2,
|
||||
/*
|
||||
BG_RV_OBJECT_PILAR_COLLISION_1,
|
||||
BG_RV_OBJECT_PILAR_COLLISION_2,
|
||||
BG_RV_OBJECT_PILAR_COLLISION_3,
|
||||
BG_RV_OBJECT_PILAR_COLLISION_4,
|
||||
*/
|
||||
BG_RV_OBJECT_ELEVATOR_1,
|
||||
BG_RV_OBJECT_ELEVATOR_2,
|
||||
BG_RV_OBJECT_FENCE_1,
|
||||
BG_RV_OBJECT_FENCE_2,
|
||||
BG_RV_OBJECT_MAX,
|
||||
};
|
||||
|
||||
enum BattleGroundRVObjects
|
||||
{
|
||||
BG_RV_OBJECT_TYPE_BUFF_1 = 184663,
|
||||
BG_RV_OBJECT_TYPE_BUFF_2 = 184664,
|
||||
BG_RV_OBJECT_TYPE_FIRE_1 = 192704,
|
||||
BG_RV_OBJECT_TYPE_FIRE_2 = 192705,
|
||||
|
||||
BG_RV_OBJECT_TYPE_FIREDOOR_2 = 192387,
|
||||
BG_RV_OBJECT_TYPE_FIREDOOR_1 = 192388,
|
||||
BG_RV_OBJECT_TYPE_PULLEY_1 = 192389,
|
||||
BG_RV_OBJECT_TYPE_PULLEY_2 = 192390,
|
||||
BG_RV_OBJECT_TYPE_FENCE_1 = 192391,
|
||||
BG_RV_OBJECT_TYPE_FENCE_2 = 192392,
|
||||
BG_RV_OBJECT_TYPE_GEAR_1 = 192393,
|
||||
BG_RV_OBJECT_TYPE_GEAR_2 = 192394,
|
||||
BG_RV_OBJECT_TYPE_ELEVATOR_1 = 194582,
|
||||
BG_RV_OBJECT_TYPE_ELEVATOR_2 = 194586,
|
||||
/*
|
||||
BG_RV_OBJECT_TYPE_PILAR_COLLISION_1 = 194580, // axe
|
||||
BG_RV_OBJECT_TYPE_PILAR_COLLISION_2 = 194579, // arena
|
||||
BG_RV_OBJECT_TYPE_PILAR_COLLISION_3 = 194581, // lightning
|
||||
BG_RV_OBJECT_TYPE_PILAR_COLLISION_4 = 194578, // ivory
|
||||
*/
|
||||
BG_RV_OBJECT_TYPE_PILAR_1 = 194583, // axe
|
||||
BG_RV_OBJECT_TYPE_PILAR_2 = 194584, // arena
|
||||
BG_RV_OBJECT_TYPE_PILAR_3 = 194585, // lightning
|
||||
BG_RV_OBJECT_TYPE_PILAR_4 = 194587, // ivory
|
||||
};
|
||||
|
||||
enum BattleGroundRVData
|
||||
{
|
||||
BG_RV_STATE_OPEN_FENCES,
|
||||
BG_RV_STATE_OPEN_PILARS,
|
||||
BG_RV_STATE_CLOSE_PILARS,
|
||||
BG_RV_STATE_OPEN_FIRE,
|
||||
BG_RV_STATE_CLOSE_FIRE,
|
||||
BG_RV_FIRE_TO_PILAR_TIMER = 20000,
|
||||
BG_RV_PILAR_TO_FIRE_TIMER = 5000,
|
||||
BG_RV_FIRST_TIMER = 20133,
|
||||
BG_RV_WORLD_STATE_A = 0xe10,
|
||||
BG_RV_WORLD_STATE_H = 0xe11,
|
||||
BG_RV_WORLD_STATE = 0xe1a,
|
||||
};
|
||||
|
||||
class BattleGroundRVScore : public BattleGroundScore
|
||||
{
|
||||
public:
|
||||
BattleGroundRVScore() {};
|
||||
virtual ~BattleGroundRVScore() {};
|
||||
};
|
||||
|
||||
class BattleGroundRV : public BattleGround
|
||||
{
|
||||
friend class BattleGroundMgr;
|
||||
|
||||
public:
|
||||
BattleGroundRV();
|
||||
~BattleGroundRV();
|
||||
void Update(uint32 diff);
|
||||
|
||||
/* inherited from BattlegroundClass */
|
||||
virtual void AddPlayer(Player *plr);
|
||||
virtual void StartingEventCloseDoors();
|
||||
virtual void StartingEventOpenDoors();
|
||||
virtual void Reset();
|
||||
virtual void FillInitialWorldStates(WorldPacket &d);
|
||||
|
||||
void RemovePlayer(Player *plr, uint64 guid);
|
||||
void HandleAreaTrigger(Player *Source, uint32 Trigger);
|
||||
bool SetupBattleGround();
|
||||
void HandleKillPlayer(Player* player, Player *killer);
|
||||
bool HandlePlayerUnderMap(Player * plr);
|
||||
|
||||
private:
|
||||
uint32 Timer;
|
||||
uint32 State;
|
||||
|
||||
protected:
|
||||
uint32 getTimer() { return Timer; };
|
||||
void setTimer(uint32 timer) { Timer = timer; };
|
||||
|
||||
uint32 getState() { return State; };
|
||||
void setState(uint32 state) { State = state; };
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,822 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "BattleGround.h"
|
||||
#include "BattleGroundSA.h"
|
||||
#include "Language.h"
|
||||
#include "Player.h"
|
||||
#include "GameObject.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "WorldPacket.h"
|
||||
|
||||
|
||||
BattleGroundSA::BattleGroundSA()
|
||||
{
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_SA_START_TWO_MINUTES;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_SA_START_ONE_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_SA_START_HALF_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_SA_HAS_BEGUN;
|
||||
m_BgObjects.resize(BG_SA_MAXOBJ);
|
||||
m_BgCreatures.resize(BG_SA_MAXNPC + BG_SA_MAX_GY);
|
||||
TimerEnabled = false;
|
||||
UpdateWaitTimer = 0;
|
||||
SignaledRoundTwo = false;
|
||||
SignaledRoundTwoHalfMin = false;
|
||||
InitSecondRound = false;
|
||||
}
|
||||
|
||||
BattleGroundSA::~BattleGroundSA()
|
||||
{
|
||||
}
|
||||
|
||||
void BattleGroundSA::Reset()
|
||||
{
|
||||
TotalTime = 0;
|
||||
attackers = ((urand(0,1)) ? TEAM_ALLIANCE : TEAM_HORDE);
|
||||
for (uint8 i = 0; i <= 5; i++)
|
||||
GateStatus[i] = BG_SA_GATE_OK;
|
||||
ShipsStarted = false;
|
||||
status = BG_SA_WARMUP;
|
||||
}
|
||||
|
||||
bool BattleGroundSA::SetupBattleGround()
|
||||
{
|
||||
return ResetObjs();
|
||||
}
|
||||
|
||||
bool BattleGroundSA::ResetObjs()
|
||||
{
|
||||
uint32 atF = BG_SA_Factions[attackers];
|
||||
uint32 defF = BG_SA_Factions[attackers ? TEAM_ALLIANCE : TEAM_HORDE];
|
||||
|
||||
|
||||
for (uint8 i = 0; i <BG_SA_MAXOBJ; i++)
|
||||
DelObject(i);
|
||||
|
||||
for (uint8 i = 0; i < BG_SA_MAXNPC; i++)
|
||||
DelCreature(i);
|
||||
|
||||
for (uint8 i = BG_SA_MAXNPC; i < BG_SA_MAXNPC + BG_SA_MAX_GY; i++)
|
||||
DelCreature(i);
|
||||
|
||||
for (uint8 i = 0; i < 6; i++)
|
||||
GateStatus[i] = BG_SA_GATE_OK;
|
||||
|
||||
for (uint8 i = 0; i < BG_SA_CENTRAL_FLAG; i++)
|
||||
{
|
||||
if (!AddObject(i,BG_SA_ObjEntries[i],
|
||||
BG_SA_ObjSpawnlocs[i][0],BG_SA_ObjSpawnlocs[i][1],
|
||||
BG_SA_ObjSpawnlocs[i][2],BG_SA_ObjSpawnlocs[i][3],
|
||||
0,0,0,0,RESPAWN_ONE_DAY))
|
||||
return false;
|
||||
}
|
||||
|
||||
//Cannons and demolishers - NPCs are spawned
|
||||
//By capturing GYs.
|
||||
for (uint8 i = 0; i < BG_SA_NPC_SPARKLIGHT; i++)
|
||||
{
|
||||
if (!AddCreature(BG_SA_NpcEntries[i], i, (attackers == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE),
|
||||
BG_SA_NpcSpawnlocs[i][0],BG_SA_NpcSpawnlocs[i][1],
|
||||
BG_SA_NpcSpawnlocs[i][2],BG_SA_NpcSpawnlocs[i][3],600))
|
||||
return false;
|
||||
}
|
||||
|
||||
OverrideGunFaction();
|
||||
DemolisherStartState(true);
|
||||
|
||||
for (uint8 i = 0; i <= BG_SA_TITAN_RELIC; i++)
|
||||
{
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
GetBGObject(i)->SetUInt32Value(GAMEOBJECT_FACTION, defF);
|
||||
}
|
||||
|
||||
GetBGObject(BG_SA_TITAN_RELIC)->SetUInt32Value(GAMEOBJECT_FACTION, atF);
|
||||
GetBGObject(BG_SA_TITAN_RELIC)->Refresh();
|
||||
|
||||
for (uint8 i = 0; i <= 5; i++)
|
||||
GateStatus[i] = BG_SA_GATE_OK;
|
||||
|
||||
// MAD props for Kiper for discovering those values - 4 hours of his work.
|
||||
GetBGObject(BG_SA_BOAT_ONE)->UpdateRotationFields(1.0f, 0.0002f);
|
||||
GetBGObject(BG_SA_BOAT_TWO)->UpdateRotationFields(1.0f, 0.00001f);
|
||||
SpawnBGObject(BG_SA_BOAT_ONE, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(BG_SA_BOAT_TWO, RESPAWN_IMMEDIATELY);
|
||||
|
||||
TotalTime = 0;
|
||||
ShipsStarted = false;
|
||||
|
||||
//Graveyards!
|
||||
for (uint8 i = 0;i < BG_SA_MAX_GY; i++)
|
||||
{
|
||||
WorldSafeLocsEntry const *sg = NULL;
|
||||
sg = sWorldSafeLocsStore.LookupEntry(BG_SA_GYEntries[i]);
|
||||
|
||||
if (!sg)
|
||||
{
|
||||
sLog.outError("SOTA: Can't find GY entry %u",BG_SA_GYEntries[i]);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (i == BG_SA_BEACH_GY)
|
||||
{
|
||||
GraveyardStatus[i] = attackers;
|
||||
AddSpiritGuide(i + BG_SA_MAXNPC, sg->x, sg->y, sg->z, BG_SA_GYOrientation[i], ((attackers == TEAM_HORDE)? HORDE : ALLIANCE));
|
||||
}
|
||||
else
|
||||
{
|
||||
GraveyardStatus[i] = ((attackers == TEAM_HORDE)? TEAM_ALLIANCE : TEAM_HORDE);
|
||||
if (!AddSpiritGuide(i + BG_SA_MAXNPC, sg->x, sg->y, sg->z, BG_SA_GYOrientation[i], ((attackers == TEAM_HORDE)? ALLIANCE : HORDE)))
|
||||
sLog.outError("SOTA: couldn't spawn GY: %u",i);
|
||||
}
|
||||
}
|
||||
|
||||
//GY capture points
|
||||
for (uint8 i = BG_SA_CENTRAL_FLAG; i < BG_SA_MAXOBJ; i++)
|
||||
{
|
||||
AddObject(i, BG_SA_ObjEntries[(i + (attackers == TEAM_ALLIANCE ? 3:0))],
|
||||
BG_SA_ObjSpawnlocs[i][0], BG_SA_ObjSpawnlocs[i][1],
|
||||
BG_SA_ObjSpawnlocs[i][2], BG_SA_ObjSpawnlocs[i][3],
|
||||
0,0,0,0,RESPAWN_ONE_DAY);
|
||||
GetBGObject(i)->SetUInt32Value(GAMEOBJECT_FACTION, atF);
|
||||
}
|
||||
|
||||
//Player may enter BEFORE we set up bG - lets update his worldstates anyway...
|
||||
UpdateWorldState(BG_SA_RIGHT_GY_HORDE , GraveyardStatus[BG_SA_RIGHT_CAPTURABLE_GY] == TEAM_HORDE?1:0);
|
||||
UpdateWorldState(BG_SA_LEFT_GY_HORDE , GraveyardStatus[BG_SA_LEFT_CAPTURABLE_GY] == TEAM_HORDE?1:0);
|
||||
UpdateWorldState(BG_SA_CENTER_GY_HORDE , GraveyardStatus[BG_SA_CENTRAL_CAPTURABLE_GY] == TEAM_HORDE?1:0);
|
||||
|
||||
UpdateWorldState(BG_SA_RIGHT_GY_ALLIANCE , GraveyardStatus[BG_SA_RIGHT_CAPTURABLE_GY] == TEAM_ALLIANCE?1:0);
|
||||
UpdateWorldState(BG_SA_LEFT_GY_ALLIANCE , GraveyardStatus[BG_SA_LEFT_CAPTURABLE_GY] == TEAM_ALLIANCE?1:0);
|
||||
UpdateWorldState(BG_SA_CENTER_GY_ALLIANCE , GraveyardStatus[BG_SA_CENTRAL_CAPTURABLE_GY] == TEAM_ALLIANCE?1:0);
|
||||
|
||||
if (attackers == TEAM_ALLIANCE)
|
||||
{
|
||||
UpdateWorldState(BG_SA_ALLY_ATTACKS, 1);
|
||||
UpdateWorldState(BG_SA_HORDE_ATTACKS, 0);
|
||||
|
||||
UpdateWorldState(BG_SA_RIGHT_ATT_TOKEN_ALL, 1);
|
||||
UpdateWorldState(BG_SA_LEFT_ATT_TOKEN_ALL, 1);
|
||||
UpdateWorldState(BG_SA_RIGHT_ATT_TOKEN_HRD, 0);
|
||||
UpdateWorldState(BG_SA_LEFT_ATT_TOKEN_HRD, 0);
|
||||
|
||||
UpdateWorldState(BG_SA_HORDE_DEFENCE_TOKEN,1);
|
||||
UpdateWorldState(BG_SA_ALLIANCE_DEFENCE_TOKEN,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateWorldState(BG_SA_HORDE_ATTACKS, 1);
|
||||
UpdateWorldState(BG_SA_ALLY_ATTACKS, 0);
|
||||
|
||||
UpdateWorldState(BG_SA_RIGHT_ATT_TOKEN_ALL, 0);
|
||||
UpdateWorldState(BG_SA_LEFT_ATT_TOKEN_ALL, 0);
|
||||
UpdateWorldState(BG_SA_RIGHT_ATT_TOKEN_HRD, 1);
|
||||
UpdateWorldState(BG_SA_LEFT_ATT_TOKEN_HRD, 1);
|
||||
|
||||
UpdateWorldState(BG_SA_HORDE_DEFENCE_TOKEN,0);
|
||||
UpdateWorldState(BG_SA_ALLIANCE_DEFENCE_TOKEN,1);
|
||||
}
|
||||
|
||||
UpdateWorldState(BG_SA_PURPLE_GATEWS, 1);
|
||||
UpdateWorldState(BG_SA_RED_GATEWS, 1);
|
||||
UpdateWorldState(BG_SA_BLUE_GATEWS, 1);
|
||||
UpdateWorldState(BG_SA_GREEN_GATEWS, 1);
|
||||
UpdateWorldState(BG_SA_YELLOW_GATEWS, 1);
|
||||
UpdateWorldState(BG_SA_ANCIENT_GATEWS, 1);
|
||||
|
||||
TeleportPlayers();
|
||||
return true;
|
||||
}
|
||||
|
||||
void BattleGroundSA::StartShips()
|
||||
{
|
||||
if (ShipsStarted)
|
||||
return;
|
||||
|
||||
DoorOpen(BG_SA_BOAT_ONE);
|
||||
DoorOpen(BG_SA_BOAT_TWO);
|
||||
|
||||
for (int i = BG_SA_BOAT_ONE; i <= BG_SA_BOAT_TWO; i++)
|
||||
{
|
||||
for (BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end();itr++)
|
||||
{
|
||||
if (Player* p = objmgr.GetPlayer(itr->first))
|
||||
{
|
||||
if (p->GetTeamId() != attackers)
|
||||
continue;
|
||||
|
||||
UpdateData data;
|
||||
WorldPacket pkt;
|
||||
GetBGObject(i)->BuildValuesUpdateBlockForPlayer(&data, p);
|
||||
data.BuildPacket(&pkt);
|
||||
p->GetSession()->SendPacket(&pkt);
|
||||
}
|
||||
}
|
||||
}
|
||||
ShipsStarted = true;
|
||||
}
|
||||
|
||||
void BattleGroundSA::Update(uint32 diff)
|
||||
{
|
||||
if (InitSecondRound)
|
||||
{
|
||||
if (UpdateWaitTimer < diff)
|
||||
{
|
||||
if (!SignaledRoundTwo)
|
||||
{
|
||||
SignaledRoundTwo = true;
|
||||
InitSecondRound = false;
|
||||
SendMessageToAll(LANG_BG_SA_ROUND_TWO_ONE_MINUTE, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
}
|
||||
}else
|
||||
{
|
||||
UpdateWaitTimer -= diff;
|
||||
return;
|
||||
}
|
||||
}
|
||||
BattleGround::Update(diff);
|
||||
TotalTime += diff;
|
||||
|
||||
if (status == BG_SA_WARMUP )
|
||||
{
|
||||
BG_SA_ENDROUNDTIME = BG_SA_ROUNDLENGTH;
|
||||
if (TotalTime >= BG_SA_WARMUPLENGTH)
|
||||
{
|
||||
TotalTime = 0;
|
||||
ToggleTimer();
|
||||
DemolisherStartState(false);
|
||||
status = BG_SA_ROUND_ONE;
|
||||
}
|
||||
if (TotalTime >= BG_SA_BOAT_START)
|
||||
StartShips();
|
||||
return;
|
||||
}
|
||||
else if (status == BG_SA_SECOND_WARMUP)
|
||||
{
|
||||
if (RoundScores[0].time<BG_SA_ROUNDLENGTH)
|
||||
BG_SA_ENDROUNDTIME = RoundScores[0].time;
|
||||
else
|
||||
BG_SA_ENDROUNDTIME = BG_SA_ROUNDLENGTH;
|
||||
|
||||
if (TotalTime >= 60000)
|
||||
{
|
||||
SendWarningToAll(LANG_BG_SA_HAS_BEGUN);
|
||||
TotalTime = 0;
|
||||
ToggleTimer();
|
||||
DemolisherStartState(false);
|
||||
status = BG_SA_ROUND_TWO;
|
||||
}
|
||||
if (TotalTime >= 30000)
|
||||
{
|
||||
if (!SignaledRoundTwoHalfMin)
|
||||
{
|
||||
SignaledRoundTwoHalfMin = true;
|
||||
SendMessageToAll(LANG_BG_SA_ROUND_TWO_START_HALF_MINUTE, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
}
|
||||
}
|
||||
StartShips();
|
||||
return;
|
||||
}
|
||||
else if (GetStatus() == STATUS_IN_PROGRESS)
|
||||
{
|
||||
if (status == BG_SA_ROUND_ONE)
|
||||
{
|
||||
if (TotalTime >= BG_SA_ROUNDLENGTH)
|
||||
{
|
||||
RoundScores[0].winner = attackers;
|
||||
RoundScores[0].time = BG_SA_ROUNDLENGTH;
|
||||
TotalTime = 0;
|
||||
status = BG_SA_SECOND_WARMUP;
|
||||
attackers = (attackers == TEAM_ALLIANCE) ? TEAM_HORDE : TEAM_ALLIANCE;
|
||||
status = BG_SA_SECOND_WARMUP;
|
||||
ToggleTimer();
|
||||
ResetObjs();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (status == BG_SA_ROUND_TWO)
|
||||
{
|
||||
if (TotalTime >= BG_SA_ENDROUNDTIME)
|
||||
{
|
||||
RoundScores[1].time = BG_SA_ROUNDLENGTH;
|
||||
RoundScores[1].winner = (attackers == TEAM_ALLIANCE) ? TEAM_HORDE : TEAM_ALLIANCE;
|
||||
|
||||
if (RoundScores[0].time == RoundScores[1].time)
|
||||
EndBattleGround(NULL);
|
||||
else if (RoundScores[0].time < RoundScores[1].time)
|
||||
EndBattleGround(RoundScores[0].winner == TEAM_ALLIANCE ? ALLIANCE : HORDE);
|
||||
else
|
||||
EndBattleGround(RoundScores[1].winner == TEAM_ALLIANCE ? ALLIANCE : HORDE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (status == BG_SA_ROUND_ONE || status == BG_SA_ROUND_TWO)
|
||||
{
|
||||
SendTime();
|
||||
UpdateDemolisherSpawns();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BattleGroundSA::StartingEventCloseDoors()
|
||||
{
|
||||
}
|
||||
|
||||
void BattleGroundSA::StartingEventOpenDoors()
|
||||
{
|
||||
}
|
||||
|
||||
void BattleGroundSA::FillInitialWorldStates(WorldPacket& data)
|
||||
{
|
||||
uint32 ally_attacks = uint32(attackers == TEAM_ALLIANCE ? 1 : 0);
|
||||
uint32 horde_attacks = uint32(attackers == TEAM_HORDE ? 1 : 0);
|
||||
|
||||
data << uint32(BG_SA_ANCIENT_GATEWS) << uint32(GateStatus[BG_SA_ANCIENT_GATE]);
|
||||
data << uint32(BG_SA_YELLOW_GATEWS) << uint32(GateStatus[BG_SA_YELLOW_GATE]);
|
||||
data << uint32(BG_SA_GREEN_GATEWS) << uint32(GateStatus[BG_SA_GREEN_GATE]);
|
||||
data << uint32(BG_SA_BLUE_GATEWS) << uint32(GateStatus[BG_SA_BLUE_GATE]);
|
||||
data << uint32(BG_SA_RED_GATEWS) << uint32(GateStatus[BG_SA_RED_GATE]);
|
||||
data << uint32(BG_SA_PURPLE_GATEWS) << uint32(GateStatus[BG_SA_PURPLE_GATE]);
|
||||
|
||||
data << uint32(BG_SA_BONUS_TIMER) << uint32(0);
|
||||
|
||||
data << uint32(BG_SA_HORDE_ATTACKS)<< horde_attacks;
|
||||
data << uint32(BG_SA_ALLY_ATTACKS) << ally_attacks;
|
||||
|
||||
//Time will be sent on first update...
|
||||
data << uint32(BG_SA_ENABLE_TIMER) << ((TimerEnabled) ? uint32(1) : uint32(0));
|
||||
data << uint32(BG_SA_TIMER_MINS) << uint32(0);
|
||||
data << uint32(BG_SA_TIMER_SEC_TENS) << uint32(0);
|
||||
data << uint32(BG_SA_TIMER_SEC_DECS) << uint32(0);
|
||||
|
||||
data << uint32(BG_SA_RIGHT_GY_HORDE) << uint32(GraveyardStatus[BG_SA_RIGHT_CAPTURABLE_GY] == TEAM_HORDE?1:0);
|
||||
data << uint32(BG_SA_LEFT_GY_HORDE) << uint32(GraveyardStatus[BG_SA_LEFT_CAPTURABLE_GY] == TEAM_HORDE?1:0);
|
||||
data << uint32(BG_SA_CENTER_GY_HORDE) << uint32(GraveyardStatus[BG_SA_CENTRAL_CAPTURABLE_GY] == TEAM_HORDE?1:0);
|
||||
|
||||
data << uint32(BG_SA_RIGHT_GY_ALLIANCE) << uint32(GraveyardStatus[BG_SA_RIGHT_CAPTURABLE_GY] == TEAM_ALLIANCE?1:0);
|
||||
data << uint32(BG_SA_LEFT_GY_ALLIANCE) << uint32(GraveyardStatus[BG_SA_LEFT_CAPTURABLE_GY] == TEAM_ALLIANCE?1:0);
|
||||
data << uint32(BG_SA_CENTER_GY_ALLIANCE) << uint32(GraveyardStatus[BG_SA_CENTRAL_CAPTURABLE_GY] == TEAM_ALLIANCE?1:0);
|
||||
|
||||
data << uint32(BG_SA_HORDE_DEFENCE_TOKEN) << ally_attacks;
|
||||
data << uint32(BG_SA_ALLIANCE_DEFENCE_TOKEN) << horde_attacks;
|
||||
|
||||
data << uint32(BG_SA_LEFT_ATT_TOKEN_HRD) << horde_attacks;
|
||||
data << uint32(BG_SA_RIGHT_ATT_TOKEN_HRD) << horde_attacks;
|
||||
data << uint32(BG_SA_RIGHT_ATT_TOKEN_ALL) << ally_attacks;
|
||||
data << uint32(BG_SA_LEFT_ATT_TOKEN_ALL) << ally_attacks;
|
||||
}
|
||||
|
||||
void BattleGroundSA::AddPlayer(Player *plr)
|
||||
{
|
||||
BattleGround::AddPlayer(plr);
|
||||
//create score and add it to map, default values are set in constructor
|
||||
BattleGroundSAScore* sc = new BattleGroundSAScore;
|
||||
|
||||
if (!ShipsStarted)
|
||||
{
|
||||
if (plr->GetTeamId() == attackers)
|
||||
{
|
||||
plr->CastSpell(plr,12438,true);//Without this player falls before boat loads...
|
||||
|
||||
if (urand(0,1))
|
||||
plr->TeleportTo(607, 2682.936f, -830.368f, 50.0f, 2.895f, 0);
|
||||
else
|
||||
plr->TeleportTo(607, 2577.003f, 980.261f, 50.0f, 0.807f, 0);
|
||||
|
||||
}
|
||||
else
|
||||
plr->TeleportTo(607, 1209.7f, -65.16f, 70.1f, 0.0f, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (plr->GetTeamId() == attackers)
|
||||
plr->TeleportTo(607, 1600.381f, -106.263f, 8.8745f, 3.78f, 0);
|
||||
else
|
||||
plr->TeleportTo(607, 1209.7f, -65.16f, 70.1f, 0.0f, 0);
|
||||
}
|
||||
|
||||
m_PlayerScores[plr->GetGUID()] = sc;
|
||||
}
|
||||
|
||||
void BattleGroundSA::RemovePlayer(Player* /*plr*/,uint64 /*guid*/)
|
||||
{
|
||||
}
|
||||
|
||||
void BattleGroundSA::HandleAreaTrigger(Player * /*Source*/, uint32 /*Trigger*/)
|
||||
{
|
||||
// this is wrong way to implement these things. On official it done by gameobject spell cast.
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
}
|
||||
|
||||
void BattleGroundSA::UpdatePlayerScore(Player* Source, uint32 type, uint32 value, bool doAddHonor)
|
||||
{
|
||||
BattleGroundScoreMap::iterator itr = m_PlayerScores.find(Source->GetGUID());
|
||||
if (itr == m_PlayerScores.end()) // player not found...
|
||||
return;
|
||||
|
||||
if (type == SCORE_DESTROYED_DEMOLISHER)
|
||||
((BattleGroundSAScore*)itr->second)->demolishers_destroyed += value;
|
||||
else if (type == SCORE_DESTROYED_WALL)
|
||||
((BattleGroundSAScore*)itr->second)->gates_destroyed += value;
|
||||
else
|
||||
BattleGround::UpdatePlayerScore(Source,type,value, doAddHonor);
|
||||
}
|
||||
|
||||
void BattleGroundSA::TeleportPlayers()
|
||||
{
|
||||
for (BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
|
||||
{
|
||||
if (Player *plr = objmgr.GetPlayer(itr->first))
|
||||
{
|
||||
// should remove spirit of redemption
|
||||
if (plr->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION))
|
||||
plr->RemoveAurasByType(SPELL_AURA_MOD_SHAPESHIFT);
|
||||
|
||||
if (!plr->isAlive())
|
||||
{
|
||||
plr->ResurrectPlayer(1.0f);
|
||||
plr->SpawnCorpseBones();
|
||||
}
|
||||
|
||||
plr->SetHealth(plr->GetMaxHealth());
|
||||
plr->SetPower(POWER_MANA, plr->GetMaxPower(POWER_MANA));
|
||||
plr->CombatStopWithPets(true);
|
||||
|
||||
if (plr->GetTeamId() == attackers)
|
||||
{
|
||||
plr->CastSpell(plr,12438,true); //Without this player falls before boat loads...
|
||||
|
||||
if (urand(0,1))
|
||||
plr->TeleportTo(607, 2682.936f, -830.368f, 50.0f, 2.895f, 0);
|
||||
else
|
||||
plr->TeleportTo(607, 2577.003f, 980.261f, 50.0f, 0.807f, 0);
|
||||
}
|
||||
else
|
||||
plr->TeleportTo(607, 1209.7f, -65.16f, 70.1f, 0.0f, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BattleGroundSA::EventPlayerDamagedGO(Player* plr, GameObject* go, uint8 hitType, uint32 destroyedEvent)
|
||||
{
|
||||
if (!go || !go->GetGOInfo())
|
||||
return;
|
||||
|
||||
switch(hitType)
|
||||
{
|
||||
case BG_OBJECT_DMG_HIT_TYPE_JUST_DAMAGED://under attack
|
||||
SendWarningToAll(LANG_BG_SA_IS_UNDER_ATTACK, go->GetGOInfo()->name);
|
||||
break;
|
||||
case BG_OBJECT_DMG_HIT_TYPE_DAMAGED:
|
||||
break;
|
||||
case BG_OBJECT_DMG_HIT_TYPE_JUST_HIGH_DAMAGED:
|
||||
{
|
||||
uint32 i = GetGateIDFromDestroyEventID(destroyedEvent);
|
||||
GateStatus[i] = BG_SA_GATE_DAMAGED;
|
||||
uint32 uws = GetWorldStateFromGateID(i);
|
||||
if (uws)
|
||||
UpdateWorldState(uws, GateStatus[i]);
|
||||
break;
|
||||
}
|
||||
case BG_OBJECT_DMG_HIT_TYPE_HIGH_DAMAGED:
|
||||
break;
|
||||
case BG_OBJECT_DMG_HIT_TYPE_JUST_DESTROYED://handled at DestroyGate()
|
||||
if (destroyedEvent == 19837)
|
||||
SendWarningToAll(LANG_BG_SA_CHAMBER_BREACHED);
|
||||
else
|
||||
SendWarningToAll(LANG_BG_SA_WAS_DESTROYED, go->GetGOInfo()->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void BattleGroundSA::HandleKillUnit(Creature* unit, Player* killer)
|
||||
{
|
||||
if (!unit)
|
||||
return;
|
||||
|
||||
if (unit->GetEntry() == 28781) //Demolisher
|
||||
UpdatePlayerScore(killer, SCORE_DESTROYED_DEMOLISHER, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
You may ask what the fuck does it do?
|
||||
Prevents owner overwriting guns faction with own.
|
||||
*/
|
||||
void BattleGroundSA::OverrideGunFaction()
|
||||
{
|
||||
if (!m_BgCreatures[0])
|
||||
return;
|
||||
|
||||
for (uint8 i = BG_SA_GUN_1; i <= BG_SA_GUN_10;i++)
|
||||
{
|
||||
if (Creature* gun = GetBGCreature(i))
|
||||
gun->setFaction(BG_SA_Factions[attackers? TEAM_ALLIANCE : TEAM_HORDE]);
|
||||
}
|
||||
|
||||
for (uint8 i = BG_SA_DEMOLISHER_1; i <= BG_SA_DEMOLISHER_4;i++)
|
||||
{
|
||||
if (Creature* dem = GetBGCreature(i))
|
||||
dem->setFaction(BG_SA_Factions[attackers]);
|
||||
}
|
||||
}
|
||||
|
||||
void BattleGroundSA::DemolisherStartState(bool start)
|
||||
{
|
||||
if (!m_BgCreatures[0])
|
||||
return;
|
||||
|
||||
for (uint8 i = BG_SA_DEMOLISHER_1; i <= BG_SA_DEMOLISHER_4; i++)
|
||||
{
|
||||
if (Creature* dem = GetBGCreature(i))
|
||||
{
|
||||
if (start)
|
||||
dem->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
|
||||
else
|
||||
dem->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BattleGroundSA::DestroyGate(Player* pl, GameObject* /*go*/, uint32 destroyedEvent)
|
||||
{
|
||||
uint32 i = GetGateIDFromDestroyEventID(destroyedEvent);
|
||||
if (!GateStatus[i])
|
||||
return;
|
||||
|
||||
if (GameObject* g = GetBGObject(i))
|
||||
{
|
||||
if (g->GetGOValue()->building.health == 0)
|
||||
{
|
||||
GateStatus[i] = BG_SA_GATE_DESTROYED;
|
||||
uint32 uws = GetWorldStateFromGateID(i);
|
||||
if (uws)
|
||||
UpdateWorldState(uws, GateStatus[i]);
|
||||
bool rewardHonor = true;
|
||||
switch(i)
|
||||
{
|
||||
case BG_SA_GREEN_GATE:
|
||||
if (GateStatus[BG_SA_BLUE_GATE] == BG_SA_GATE_DESTROYED)
|
||||
rewardHonor = false;
|
||||
break;
|
||||
case BG_SA_BLUE_GATE:
|
||||
if (GateStatus[BG_SA_GREEN_GATE] == BG_SA_GATE_DESTROYED)
|
||||
rewardHonor = false;
|
||||
break;
|
||||
case BG_SA_RED_GATE:
|
||||
if (GateStatus[BG_SA_PURPLE_GATE] == BG_SA_GATE_DESTROYED)
|
||||
rewardHonor = false;
|
||||
break;
|
||||
case BG_SA_PURPLE_GATE:
|
||||
if (GateStatus[BG_SA_RED_GATE] == BG_SA_GATE_DESTROYED)
|
||||
rewardHonor = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < 5)
|
||||
DelObject(i+9);
|
||||
UpdatePlayerScore(pl,SCORE_DESTROYED_WALL, 1);
|
||||
if (rewardHonor)
|
||||
UpdatePlayerScore(pl,SCORE_BONUS_HONOR,(GetBonusHonorFromKill(1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WorldSafeLocsEntry const* BattleGroundSA::GetClosestGraveYard(Player* player)
|
||||
{
|
||||
uint32 safeloc = 0;
|
||||
WorldSafeLocsEntry const* ret;
|
||||
WorldSafeLocsEntry const* closest;
|
||||
float dist, nearest;
|
||||
float x,y,z;
|
||||
|
||||
player->GetPosition(x,y,z);
|
||||
|
||||
if (player->GetTeamId() == attackers)
|
||||
safeloc = BG_SA_GYEntries[BG_SA_BEACH_GY];
|
||||
else
|
||||
safeloc = BG_SA_GYEntries[BG_SA_DEFENDER_LAST_GY];
|
||||
|
||||
closest = sWorldSafeLocsStore.LookupEntry(safeloc);
|
||||
nearest = sqrt((closest->x - x)*(closest->x - x) + (closest->y - y)*(closest->y - y)+(closest->z - z)*(closest->z - z));
|
||||
|
||||
for (uint8 i = BG_SA_RIGHT_CAPTURABLE_GY; i < BG_SA_MAX_GY; i++)
|
||||
{
|
||||
if (GraveyardStatus[i] != player->GetTeamId())
|
||||
continue;
|
||||
|
||||
ret = sWorldSafeLocsStore.LookupEntry(BG_SA_GYEntries[i]);
|
||||
dist = sqrt((ret->x - x)*(ret->x - x) + (ret->y - y)*(ret->y - y)+(ret->z - z)*(ret->z - z));
|
||||
if (dist < nearest)
|
||||
{
|
||||
closest = ret;
|
||||
nearest = dist;
|
||||
}
|
||||
}
|
||||
|
||||
return closest;
|
||||
}
|
||||
|
||||
void BattleGroundSA::SendTime()
|
||||
{
|
||||
uint32 end_of_round = (BG_SA_ENDROUNDTIME - TotalTime);
|
||||
UpdateWorldState(BG_SA_TIMER_MINS, end_of_round/60000);
|
||||
UpdateWorldState(BG_SA_TIMER_SEC_TENS, (end_of_round%60000)/10000);
|
||||
UpdateWorldState(BG_SA_TIMER_SEC_DECS, ((end_of_round%60000)%10000)/1000);
|
||||
}
|
||||
|
||||
void BattleGroundSA::EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj)
|
||||
{
|
||||
switch(target_obj->GetEntry())
|
||||
{
|
||||
case 191307:
|
||||
case 191308:
|
||||
if (GateStatus[BG_SA_GREEN_GATE] == BG_SA_GATE_DESTROYED || GateStatus[BG_SA_BLUE_GATE] == BG_SA_GATE_DESTROYED)
|
||||
CaptureGraveyard(BG_SA_LEFT_CAPTURABLE_GY, Source);
|
||||
break;
|
||||
case 191305:
|
||||
case 191306:
|
||||
if (GateStatus[BG_SA_GREEN_GATE] == BG_SA_GATE_DESTROYED || GateStatus[BG_SA_BLUE_GATE] == BG_SA_GATE_DESTROYED)
|
||||
CaptureGraveyard(BG_SA_RIGHT_CAPTURABLE_GY, Source);
|
||||
break;
|
||||
case 191310:
|
||||
case 191309:
|
||||
if ((GateStatus[BG_SA_GREEN_GATE] == BG_SA_GATE_DESTROYED || GateStatus[BG_SA_BLUE_GATE] == BG_SA_GATE_DESTROYED) && (GateStatus[BG_SA_RED_GATE] == BG_SA_GATE_DESTROYED || GateStatus[BG_SA_PURPLE_GATE] == BG_SA_GATE_DESTROYED))
|
||||
CaptureGraveyard(BG_SA_CENTRAL_CAPTURABLE_GY, Source);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
void BattleGroundSA::CaptureGraveyard(BG_SA_Graveyards i, Player *Source)
|
||||
{
|
||||
DelCreature(BG_SA_MAXNPC + i);
|
||||
GraveyardStatus[i] = Source->GetTeamId();
|
||||
WorldSafeLocsEntry const *sg = NULL;
|
||||
sg = sWorldSafeLocsStore.LookupEntry(BG_SA_GYEntries[i]);
|
||||
AddSpiritGuide(i + BG_SA_MAXNPC, sg->x, sg->y, sg->z, BG_SA_GYOrientation[i], (GraveyardStatus[i] == TEAM_ALLIANCE? ALLIANCE : HORDE));
|
||||
uint32 npc = 0;
|
||||
uint32 flag = 0;
|
||||
|
||||
switch(i)
|
||||
{
|
||||
case BG_SA_LEFT_CAPTURABLE_GY:
|
||||
flag = BG_SA_LEFT_FLAG;
|
||||
DelObject(flag);
|
||||
AddObject(flag,BG_SA_ObjEntries[(flag + (Source->GetTeamId() == TEAM_ALLIANCE ? 0:3))],
|
||||
BG_SA_ObjSpawnlocs[flag][0],BG_SA_ObjSpawnlocs[flag][1],
|
||||
BG_SA_ObjSpawnlocs[flag][2],BG_SA_ObjSpawnlocs[flag][3],0,0,0,0,RESPAWN_ONE_DAY);
|
||||
|
||||
npc = BG_SA_NPC_RIGSPARK;
|
||||
AddCreature(BG_SA_NpcEntries[npc], npc, attackers,
|
||||
BG_SA_NpcSpawnlocs[npc][0], BG_SA_NpcSpawnlocs[npc][1],
|
||||
BG_SA_NpcSpawnlocs[npc][2], BG_SA_NpcSpawnlocs[npc][3]);
|
||||
|
||||
UpdateWorldState(BG_SA_LEFT_GY_ALLIANCE, (GraveyardStatus[i] == TEAM_ALLIANCE? 1:0));
|
||||
UpdateWorldState(BG_SA_LEFT_GY_HORDE, (GraveyardStatus[i] == TEAM_ALLIANCE? 0:1));
|
||||
if (Source->GetTeamId() == TEAM_ALLIANCE)
|
||||
SendWarningToAll(LANG_BG_SA_A_GY_WEST);
|
||||
else
|
||||
SendWarningToAll(LANG_BG_SA_H_GY_WEST);
|
||||
break;
|
||||
case BG_SA_RIGHT_CAPTURABLE_GY:
|
||||
flag = BG_SA_RIGHT_FLAG;
|
||||
DelObject(flag);
|
||||
AddObject(flag,BG_SA_ObjEntries[(flag + (Source->GetTeamId() == TEAM_ALLIANCE ? 0:3))],
|
||||
BG_SA_ObjSpawnlocs[flag][0],BG_SA_ObjSpawnlocs[flag][1],
|
||||
BG_SA_ObjSpawnlocs[flag][2],BG_SA_ObjSpawnlocs[flag][3],0,0,0,0,RESPAWN_ONE_DAY);
|
||||
|
||||
npc = BG_SA_NPC_SPARKLIGHT;
|
||||
AddCreature(BG_SA_NpcEntries[npc], npc, attackers,
|
||||
BG_SA_NpcSpawnlocs[npc][0], BG_SA_NpcSpawnlocs[npc][1],
|
||||
BG_SA_NpcSpawnlocs[npc][2], BG_SA_NpcSpawnlocs[npc][3]);
|
||||
|
||||
UpdateWorldState(BG_SA_RIGHT_GY_ALLIANCE, (GraveyardStatus[i] == TEAM_ALLIANCE? 1:0));
|
||||
UpdateWorldState(BG_SA_RIGHT_GY_HORDE, (GraveyardStatus[i] == TEAM_ALLIANCE? 0:1));
|
||||
if (Source->GetTeamId() == TEAM_ALLIANCE)
|
||||
SendWarningToAll(LANG_BG_SA_A_GY_EAST);
|
||||
else
|
||||
SendWarningToAll(LANG_BG_SA_H_GY_EAST);
|
||||
break;
|
||||
case BG_SA_CENTRAL_CAPTURABLE_GY:
|
||||
flag = BG_SA_CENTRAL_FLAG;
|
||||
DelObject(flag);
|
||||
AddObject(flag,BG_SA_ObjEntries[(flag + (Source->GetTeamId() == TEAM_ALLIANCE ? 0:3))],
|
||||
BG_SA_ObjSpawnlocs[flag][0],BG_SA_ObjSpawnlocs[flag][1],
|
||||
BG_SA_ObjSpawnlocs[flag][2],BG_SA_ObjSpawnlocs[flag][3],0,0,0,0,RESPAWN_ONE_DAY);
|
||||
|
||||
UpdateWorldState(BG_SA_CENTER_GY_ALLIANCE, (GraveyardStatus[i] == TEAM_ALLIANCE? 1:0));
|
||||
UpdateWorldState(BG_SA_CENTER_GY_HORDE, (GraveyardStatus[i] == TEAM_ALLIANCE? 0:1));
|
||||
if (Source->GetTeamId() == TEAM_ALLIANCE)
|
||||
SendWarningToAll(LANG_BG_SA_A_GY_SOUTH);
|
||||
else
|
||||
SendWarningToAll(LANG_BG_SA_H_GY_SOUTH);
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
void BattleGroundSA::EventPlayerUsedGO(Player* Source, GameObject* object)
|
||||
{
|
||||
if (object->GetEntry() == BG_SA_ObjEntries[BG_SA_TITAN_RELIC] && GateStatus[BG_SA_ANCIENT_GATE] == BG_SA_GATE_DESTROYED)
|
||||
{
|
||||
if (Source->GetTeamId() == attackers)
|
||||
{
|
||||
if (Source->GetTeamId() == ALLIANCE)
|
||||
SendMessageToAll(LANG_BG_SA_ALLIANCE_CAPTURED_RELIC, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
else SendMessageToAll(LANG_BG_SA_HORDE_CAPTURED_RELIC, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
|
||||
if (status == BG_SA_ROUND_ONE)
|
||||
{
|
||||
RoundScores[0].winner = attackers;
|
||||
RoundScores[0].time = TotalTime;
|
||||
attackers = (attackers == TEAM_ALLIANCE) ? TEAM_HORDE : TEAM_ALLIANCE;
|
||||
status = BG_SA_SECOND_WARMUP;
|
||||
TotalTime = 0;
|
||||
ToggleTimer();
|
||||
SendWarningToAll(LANG_BG_SA_ROUND_ONE_END);
|
||||
UpdateWaitTimer = 5000;
|
||||
SignaledRoundTwo = false;
|
||||
SignaledRoundTwoHalfMin = false;
|
||||
InitSecondRound = true;
|
||||
ResetObjs();
|
||||
}
|
||||
else if (status == BG_SA_ROUND_TWO)
|
||||
{
|
||||
RoundScores[1].winner = attackers;
|
||||
RoundScores[1].time = TotalTime;ToggleTimer();
|
||||
if (RoundScores[0].time == RoundScores[1].time)
|
||||
EndBattleGround(NULL);
|
||||
else if (RoundScores[0].time < RoundScores[1].time)
|
||||
EndBattleGround(RoundScores[0].winner == TEAM_ALLIANCE ? ALLIANCE : HORDE);
|
||||
else
|
||||
EndBattleGround(RoundScores[1].winner == TEAM_ALLIANCE ? ALLIANCE : HORDE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BattleGroundSA::ToggleTimer()
|
||||
{
|
||||
TimerEnabled = !TimerEnabled;
|
||||
UpdateWorldState(BG_SA_ENABLE_TIMER, (TimerEnabled) ? 1 : 0);
|
||||
}
|
||||
|
||||
void BattleGroundSA::EndBattleGround(uint32 winner)
|
||||
{
|
||||
//honor reward for winning
|
||||
if (winner == ALLIANCE)
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), ALLIANCE);
|
||||
else if (winner == HORDE)
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), HORDE);
|
||||
|
||||
//complete map_end rewards (even if no team wins)
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(2), ALLIANCE);
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(2), HORDE);
|
||||
|
||||
BattleGround::EndBattleGround(winner);
|
||||
}
|
||||
|
||||
void BattleGroundSA::UpdateDemolisherSpawns()
|
||||
{
|
||||
for (uint8 i = BG_SA_DEMOLISHER_1; i <= BG_SA_DEMOLISHER_4; i++)
|
||||
{
|
||||
if (m_BgCreatures[i])
|
||||
{
|
||||
if (Creature *Demolisher = GetBGCreature(i))
|
||||
{
|
||||
if (Demolisher->isDead())
|
||||
{
|
||||
uint8 gy = (i >= BG_SA_DEMOLISHER_3 ? 3 : 2);
|
||||
if (GraveyardStatus[gy] == attackers)
|
||||
Demolisher->Relocate(BG_SA_NpcSpawnlocs[i + 6][0], BG_SA_NpcSpawnlocs[i + 6][1],
|
||||
BG_SA_NpcSpawnlocs[i + 6][2], BG_SA_NpcSpawnlocs[i + 6][3]);
|
||||
else
|
||||
Demolisher->Relocate(BG_SA_NpcSpawnlocs[i][0], BG_SA_NpcSpawnlocs[i][1],
|
||||
BG_SA_NpcSpawnlocs[i][2], BG_SA_NpcSpawnlocs[i][3]);
|
||||
|
||||
Demolisher->Respawn();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,384 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __BATTLEGROUNDSA_H
|
||||
#define __BATTLEGROUNDSA_H
|
||||
|
||||
class BattleGround;
|
||||
|
||||
class BattleGroundSAScore : public BattleGroundScore
|
||||
{
|
||||
public:
|
||||
BattleGroundSAScore(): demolishers_destroyed(0), gates_destroyed(0) {};
|
||||
virtual ~BattleGroundSAScore() {};
|
||||
uint8 demolishers_destroyed;
|
||||
uint8 gates_destroyed;
|
||||
};
|
||||
|
||||
#define BG_SA_FLAG_AMOUNT 3
|
||||
#define BG_SA_DEMOLISHER_AMOUNT 4
|
||||
|
||||
enum BG_SA_Status
|
||||
{
|
||||
BG_SA_NOTSTARTED = 0,
|
||||
BG_SA_WARMUP,
|
||||
BG_SA_ROUND_ONE,
|
||||
BG_SA_SECOND_WARMUP,
|
||||
BG_SA_ROUND_TWO,
|
||||
BG_SA_BONUS_ROUND
|
||||
};
|
||||
|
||||
enum BG_SA_GateState
|
||||
{
|
||||
BG_SA_GATE_OK = 1,
|
||||
BG_SA_GATE_DAMAGED = 2,
|
||||
BG_SA_GATE_DESTROYED = 3
|
||||
};
|
||||
|
||||
enum BG_SA_Timers
|
||||
{
|
||||
BG_SA_BOAT_START = 60000,
|
||||
BG_SA_WARMUPLENGTH = 120000,
|
||||
BG_SA_ROUNDLENGTH = 600000
|
||||
};
|
||||
|
||||
enum BG_SA_WorldStates
|
||||
{
|
||||
BG_SA_TIMER_MINS = 3559,
|
||||
BG_SA_TIMER_SEC_TENS = 3560,
|
||||
BG_SA_TIMER_SEC_DECS = 3561,
|
||||
BG_SA_ALLY_ATTACKS = 4352,
|
||||
BG_SA_HORDE_ATTACKS = 4353,
|
||||
|
||||
BG_SA_PURPLE_GATEWS = 3614,
|
||||
BG_SA_RED_GATEWS = 3617,
|
||||
BG_SA_BLUE_GATEWS = 3620,
|
||||
BG_SA_GREEN_GATEWS = 3623,
|
||||
BG_SA_YELLOW_GATEWS = 3638,
|
||||
BG_SA_ANCIENT_GATEWS = 3849,
|
||||
|
||||
|
||||
BG_SA_LEFT_GY_ALLIANCE = 3635,
|
||||
BG_SA_RIGHT_GY_ALLIANCE = 3636,
|
||||
BG_SA_CENTER_GY_ALLIANCE = 3637,
|
||||
|
||||
BG_SA_RIGHT_ATT_TOKEN_ALL = 3627,
|
||||
BG_SA_LEFT_ATT_TOKEN_ALL = 3626,
|
||||
|
||||
BG_SA_LEFT_ATT_TOKEN_HRD = 3629,
|
||||
BG_SA_RIGHT_ATT_TOKEN_HRD = 3628,
|
||||
|
||||
BG_SA_HORDE_DEFENCE_TOKEN = 3631,
|
||||
BG_SA_ALLIANCE_DEFENCE_TOKEN = 3630,
|
||||
|
||||
BG_SA_RIGHT_GY_HORDE = 3632,
|
||||
BG_SA_LEFT_GY_HORDE = 3633,
|
||||
BG_SA_CENTER_GY_HORDE = 3634,
|
||||
|
||||
BG_SA_BONUS_TIMER = 0xdf3,
|
||||
BG_SA_ENABLE_TIMER = 3564,
|
||||
};
|
||||
|
||||
enum BG_SA_NPCs
|
||||
{
|
||||
BG_SA_GUN_1 = 0,
|
||||
BG_SA_GUN_2,
|
||||
BG_SA_GUN_3,
|
||||
BG_SA_GUN_4,
|
||||
BG_SA_GUN_5,
|
||||
BG_SA_GUN_6,
|
||||
BG_SA_GUN_7,
|
||||
BG_SA_GUN_8,
|
||||
BG_SA_GUN_9,
|
||||
BG_SA_GUN_10,
|
||||
BG_SA_DEMOLISHER_1,
|
||||
BG_SA_DEMOLISHER_2,
|
||||
BG_SA_DEMOLISHER_3,
|
||||
BG_SA_DEMOLISHER_4,
|
||||
BG_SA_NPC_SPARKLIGHT,
|
||||
BG_SA_NPC_RIGSPARK,
|
||||
BG_SA_MAXNPC
|
||||
};
|
||||
|
||||
const uint32 BG_SA_NpcEntries[BG_SA_MAXNPC] =
|
||||
{
|
||||
27894,
|
||||
27894,
|
||||
27894,
|
||||
27894,
|
||||
27894,
|
||||
27894,
|
||||
27894,
|
||||
27894,
|
||||
27894,
|
||||
27894,
|
||||
//4 beach demolishers
|
||||
28781,
|
||||
28781,
|
||||
28781,
|
||||
28781,
|
||||
//Fizzle Sparklight, or whatever his name was
|
||||
29260,
|
||||
29262,
|
||||
};
|
||||
|
||||
const float BG_SA_NpcSpawnlocs[BG_SA_MAXNPC + BG_SA_DEMOLISHER_AMOUNT][4] =
|
||||
{
|
||||
//Cannons
|
||||
{ 1436.429f, 110.05f, 41.407f, 5.4f },
|
||||
{ 1404.9023f, 84.758f, 41.183f, 5.46f },
|
||||
{ 1068.693f, -86.951f, 93.81f, 0.02f },
|
||||
{ 1068.83f, -127.56f, 96.45f, 0.0912f },
|
||||
{ 1422.115f, -196.433f, 42.1825f, 1.0222f },
|
||||
{ 1454.887f, -220.454f, 41.956f, 0.9627f },
|
||||
{ 1232.345f, -187.517f, 66.945f, 0.45f },
|
||||
{ 1249.634f, -224.189f, 66.72f, 0.635f },
|
||||
{ 1236.213f, 92.287f, 64.965f, 5.751f },
|
||||
{ 1215.11f, 57.772f, 64.739f, 5.78f } ,
|
||||
//Demolishers
|
||||
{ 1611.597656,-117.270073,8.719355,2.513274},
|
||||
{ 1575.562500,-158.421875,5.024450,2.129302},
|
||||
{ 1618.047729,61.424641,7.248210,3.979351},
|
||||
{ 1575.103149,98.873344,2.830360,3.752458},
|
||||
//Npcs
|
||||
{ 1348.644165, -298.786469, 31.080130, 1.710423},
|
||||
{ 1358.191040, 195.527786, 31.018187, 4.171337},
|
||||
//Demolishers2
|
||||
{ 1371.055786, -317.071136, 35.007359, 1.947460},
|
||||
{ 1424.034912, -260.195190, 31.084425, 2.820013},
|
||||
{ 1353.139893, 223.745438, 35.265411, 4.343684},
|
||||
{ 1404.809570, 197.027237, 32.046032, 3.605401},
|
||||
};
|
||||
|
||||
enum BG_SA_Objects
|
||||
{
|
||||
BG_SA_GREEN_GATE = 0,
|
||||
BG_SA_YELLOW_GATE,
|
||||
BG_SA_BLUE_GATE,
|
||||
BG_SA_RED_GATE,
|
||||
BG_SA_PURPLE_GATE,
|
||||
BG_SA_ANCIENT_GATE,
|
||||
BG_SA_TITAN_RELIC,
|
||||
BG_SA_BOAT_ONE,
|
||||
BG_SA_BOAT_TWO,
|
||||
BG_SA_SIGIL_1,
|
||||
BG_SA_SIGIL_2,
|
||||
BG_SA_SIGIL_3,
|
||||
BG_SA_SIGIL_4,
|
||||
BG_SA_SIGIL_5,
|
||||
BG_SA_CENTRAL_FLAGPOLE,
|
||||
BG_SA_RIGHT_FLAGPOLE,
|
||||
BG_SA_LEFT_FLAGPOLE,
|
||||
BG_SA_CENTRAL_FLAG,
|
||||
BG_SA_RIGHT_FLAG,
|
||||
BG_SA_LEFT_FLAG,
|
||||
BG_SA_MAXOBJ
|
||||
};
|
||||
|
||||
const float BG_SA_ObjSpawnlocs[BG_SA_MAXOBJ][4] =
|
||||
{
|
||||
{ 1411.57f, 108.163f, 28.692f, 5.441f },
|
||||
{ 1055.452f, -108.1f, 82.134f, 0.034f },
|
||||
{ 1431.3413f, -219.437f, 30.893f, 0.9736f },
|
||||
{ 1227.667f, -212.555f, 55.372f, 0.5023f },
|
||||
{ 1214.681f, 81.21f, 53.413f, 5.745f },
|
||||
{ 878.555f, -108.989f, 119.835f, 0.0565f },
|
||||
{ 836.5f, -108.8f, 120.219f, 0.0f },
|
||||
//Ships
|
||||
{ 2679.696777, -826.891235, 3.712860, 5.78367f}, //rot2 1 rot3 0.0002
|
||||
{ 2574.003662, 981.261475, 2.603424, 0.807696},
|
||||
//Sigils
|
||||
{ 1414.054f, 106.72f, 41.442f, 5.441f },
|
||||
{ 1060.63f, -107.8f, 94.7f, 0.034f },
|
||||
{ 1433.383f, -216.4f, 43.642f, 0.9736f },
|
||||
{ 1230.75f, -210.724f, 67.611f, 0.5023f },
|
||||
{ 1217.8f, 79.532f, 66.58f, 5.745f },
|
||||
//Flagpoles
|
||||
{ 1215.114258,-65.711861,70.084267,-3.124123},
|
||||
{1338.863892,-153.336533,30.895121,-2.530723},
|
||||
{1309.124268,9.410645,30.893402,-1.623156},
|
||||
//Flags
|
||||
{ 1215.108032,-65.715767,70.084267,-3.124123},
|
||||
{ 1338.859253,-153.327316,30.895077,-2.530723},
|
||||
{ 1309.192017,9.416233,30.893402,1.518436},
|
||||
};
|
||||
|
||||
/* Ships:
|
||||
* 193182 - ally
|
||||
* 193183 - horde
|
||||
* 193184 - horde
|
||||
* 193185 - ally
|
||||
* Banners:
|
||||
* 191308 - left one,
|
||||
* 191306 - right one,
|
||||
* 191310 - central,
|
||||
* Ally ones, substract 1
|
||||
* to get horde ones.
|
||||
*/
|
||||
|
||||
const uint32 BG_SA_ObjEntries[BG_SA_MAXOBJ + BG_SA_FLAG_AMOUNT] =
|
||||
{
|
||||
190722,
|
||||
190727,
|
||||
190724,
|
||||
190726,
|
||||
190723,
|
||||
192549,
|
||||
192834,
|
||||
193182,
|
||||
193185,
|
||||
192687,
|
||||
192685,
|
||||
192689,
|
||||
192690,
|
||||
192691,
|
||||
191311,
|
||||
191311,
|
||||
191311,
|
||||
191310,
|
||||
191306,
|
||||
191308,
|
||||
191309,
|
||||
191305,
|
||||
191307,
|
||||
};
|
||||
|
||||
const uint32 BG_SA_Factions[2] =
|
||||
{
|
||||
1732,
|
||||
1735,
|
||||
};
|
||||
|
||||
enum BG_SA_Graveyards
|
||||
{
|
||||
BG_SA_BEACH_GY = 0,
|
||||
BG_SA_DEFENDER_LAST_GY,
|
||||
BG_SA_RIGHT_CAPTURABLE_GY,
|
||||
BG_SA_LEFT_CAPTURABLE_GY,
|
||||
BG_SA_CENTRAL_CAPTURABLE_GY,
|
||||
BG_SA_MAX_GY
|
||||
};
|
||||
|
||||
const uint32 BG_SA_GYEntries[BG_SA_MAX_GY] =
|
||||
{
|
||||
1350,
|
||||
1349,
|
||||
1347,
|
||||
1346,
|
||||
1348,
|
||||
};
|
||||
|
||||
const float BG_SA_GYOrientation[BG_SA_MAX_GY] =
|
||||
{
|
||||
6.202f,
|
||||
1.926f, //right capturable GY
|
||||
3.917f, //left capturable GY
|
||||
3.104f, //center, capturable
|
||||
6.148f, //defender last GY
|
||||
};
|
||||
|
||||
struct BG_SA_RoundScore
|
||||
{
|
||||
TeamId winner;
|
||||
uint32 time;
|
||||
};
|
||||
|
||||
class BattleGroundSA : public BattleGround
|
||||
{
|
||||
friend class BattleGroundMgr;
|
||||
|
||||
public:
|
||||
BattleGroundSA();
|
||||
~BattleGroundSA();
|
||||
void Update(uint32 diff);
|
||||
|
||||
/* inherited from BattlegroundClass */
|
||||
virtual void AddPlayer(Player *plr);
|
||||
virtual void StartingEventCloseDoors();
|
||||
virtual void StartingEventOpenDoors();
|
||||
virtual bool SetupBattleGround();
|
||||
virtual void Reset();
|
||||
virtual void FillInitialWorldStates(WorldPacket& data);
|
||||
virtual void EventPlayerDamagedGO(Player* plr, GameObject* go, uint8 hitType, uint32 destroyedEvent);
|
||||
virtual void HandleKillUnit(Creature* unit, Player* killer);
|
||||
virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player);
|
||||
virtual void EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj);
|
||||
virtual void EventPlayerUsedGO(Player* Source, GameObject* object);
|
||||
uint32 GetGateIDFromDestroyEventID(uint32 id)
|
||||
{
|
||||
uint32 i = 0;
|
||||
switch(id)
|
||||
{
|
||||
case 19046: i = BG_SA_GREEN_GATE; break; //Green gate destroyed
|
||||
case 19045: i = BG_SA_BLUE_GATE; break; //blue gate
|
||||
case 19047: i = BG_SA_RED_GATE; break; //red gate
|
||||
case 19048: i = BG_SA_PURPLE_GATE; break; //purple gate
|
||||
case 19049: i = BG_SA_YELLOW_GATE; break; //yellow gate
|
||||
case 19837: i = BG_SA_ANCIENT_GATE; break; //ancient gate
|
||||
}
|
||||
return i;
|
||||
}
|
||||
uint32 GetWorldStateFromGateID(uint32 id)
|
||||
{
|
||||
uint32 uws = 0;
|
||||
switch(id)
|
||||
{
|
||||
case BG_SA_GREEN_GATE: uws = BG_SA_GREEN_GATEWS; break;
|
||||
case BG_SA_YELLOW_GATE: uws = BG_SA_YELLOW_GATEWS; break;
|
||||
case BG_SA_BLUE_GATE: uws = BG_SA_BLUE_GATEWS; break;
|
||||
case BG_SA_RED_GATE: uws = BG_SA_RED_GATEWS; break;
|
||||
case BG_SA_PURPLE_GATE: uws = BG_SA_PURPLE_GATEWS; break;
|
||||
case BG_SA_ANCIENT_GATE: uws = BG_SA_ANCIENT_GATEWS; break;
|
||||
}
|
||||
return uws;
|
||||
}
|
||||
void EndBattleGround(uint32 winner);
|
||||
|
||||
void RemovePlayer(Player *plr,uint64 guid);
|
||||
void HandleAreaTrigger(Player *Source, uint32 Trigger);
|
||||
|
||||
|
||||
/* Scorekeeping */
|
||||
void UpdatePlayerScore(Player *Source, uint32 type, uint32 value, bool doAddHonor = true);
|
||||
|
||||
private:
|
||||
bool ResetObjs();
|
||||
void StartShips();
|
||||
void TeleportPlayers();
|
||||
void OverrideGunFaction();
|
||||
void DemolisherStartState(bool start);
|
||||
void DestroyGate(Player* pl, GameObject* /*go*/, uint32 destroyedEvent);
|
||||
void SendTime();
|
||||
void CaptureGraveyard(BG_SA_Graveyards i, Player *Source);
|
||||
void ToggleTimer();
|
||||
void UpdateDemolisherSpawns();
|
||||
TeamId attackers;
|
||||
uint32 TotalTime;
|
||||
uint32 BG_SA_ENDROUNDTIME;
|
||||
bool ShipsStarted;
|
||||
BG_SA_GateState GateStatus[6];
|
||||
BG_SA_Status status;
|
||||
TeamId GraveyardStatus[BG_SA_MAX_GY];
|
||||
BG_SA_RoundScore RoundScores[2];
|
||||
bool TimerEnabled;
|
||||
uint32 UpdateWaitTimer;//5secs before starting the 1min countdown for second round
|
||||
bool SignaledRoundTwo;
|
||||
bool SignaledRoundTwoHalfMin;
|
||||
bool InitSecondRound;
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,841 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "BattleGround.h"
|
||||
#include "BattleGroundWS.h"
|
||||
#include "Creature.h"
|
||||
#include "GameObject.h"
|
||||
#include "Language.h"
|
||||
#include "Object.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "BattleGroundMgr.h"
|
||||
#include "Player.h"
|
||||
#include "World.h"
|
||||
#include "WorldPacket.h"
|
||||
|
||||
// these variables aren't used outside of this file, so declare them only here
|
||||
enum BG_WSG_Rewards
|
||||
{
|
||||
BG_WSG_WIN = 0,
|
||||
BG_WSG_FLAG_CAP,
|
||||
BG_WSG_MAP_COMPLETE,
|
||||
BG_WSG_REWARD_NUM
|
||||
};
|
||||
|
||||
uint32 BG_WSG_Honor[BG_HONOR_MODE_NUM][BG_WSG_REWARD_NUM] = {
|
||||
{20,40,40}, // normal honor
|
||||
{60,40,80} // holiday
|
||||
};
|
||||
|
||||
uint32 BG_WSG_Reputation[BG_HONOR_MODE_NUM][BG_WSG_REWARD_NUM] = {
|
||||
{0,35,0}, // normal honor
|
||||
{0,45,0} // holiday
|
||||
};
|
||||
|
||||
BattleGroundWS::BattleGroundWS()
|
||||
{
|
||||
m_BgObjects.resize(BG_WS_OBJECT_MAX);
|
||||
m_BgCreatures.resize(BG_CREATURES_MAX_WS);
|
||||
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_WS_START_TWO_MINUTES;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_WS_START_ONE_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_WS_START_HALF_MINUTE;
|
||||
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_WS_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattleGroundWS::~BattleGroundWS()
|
||||
{
|
||||
}
|
||||
|
||||
void BattleGroundWS::Update(uint32 diff)
|
||||
{
|
||||
BattleGround::Update(diff);
|
||||
|
||||
if (GetStatus() == STATUS_IN_PROGRESS)
|
||||
{
|
||||
if (GetStartTime() >= 25*MINUTE*IN_MILISECONDS) // Òàéìåð òèêàòü íà÷èíàåò ïîñëå 25 ìèíóò
|
||||
{
|
||||
if (GetTeamScore(ALLIANCE) == 0)
|
||||
{
|
||||
if (GetTeamScore(HORDE) == 0) // No one scored - result is tie
|
||||
EndBattleGround(NULL);
|
||||
else // Horde has more points and thus wins
|
||||
EndBattleGround(HORDE);
|
||||
}
|
||||
|
||||
else if (GetTeamScore(HORDE) == 0)
|
||||
EndBattleGround(ALLIANCE); // Alliance has > 0, Horde has 0, alliance wins
|
||||
|
||||
else if (GetTeamScore(HORDE) == GetTeamScore(ALLIANCE)) // Team score equal, winner is team that scored the first flag
|
||||
EndBattleGround(m_FirstFlagCaptureTeam);
|
||||
|
||||
else if (GetTeamScore(HORDE) > GetTeamScore(ALLIANCE)) // Last but not least, check who has the higher score
|
||||
EndBattleGround(HORDE);
|
||||
else
|
||||
EndBattleGround(ALLIANCE);
|
||||
}
|
||||
else if (GetStartTime() > m_minutesElapsed*MINUTE*IN_MILISECONDS)
|
||||
{
|
||||
++m_minutesElapsed;
|
||||
UpdateWorldState(BG_WS_STATE_TIMER, 25-m_minutesElapsed);
|
||||
}
|
||||
|
||||
if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_WAIT_RESPAWN)
|
||||
{
|
||||
m_FlagsTimer[BG_TEAM_ALLIANCE] -= diff;
|
||||
|
||||
if (m_FlagsTimer[BG_TEAM_ALLIANCE] < 0)
|
||||
{
|
||||
m_FlagsTimer[BG_TEAM_ALLIANCE] = 0;
|
||||
RespawnFlag(ALLIANCE, true);
|
||||
}
|
||||
}
|
||||
if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_GROUND)
|
||||
{
|
||||
m_FlagsDropTimer[BG_TEAM_ALLIANCE] -= diff;
|
||||
|
||||
if (m_FlagsDropTimer[BG_TEAM_ALLIANCE] < 0)
|
||||
{
|
||||
m_FlagsDropTimer[BG_TEAM_ALLIANCE] = 0;
|
||||
RespawnFlagAfterDrop(ALLIANCE);
|
||||
m_BothFlagsKept = false;
|
||||
}
|
||||
}
|
||||
if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_WAIT_RESPAWN)
|
||||
{
|
||||
m_FlagsTimer[BG_TEAM_HORDE] -= diff;
|
||||
|
||||
if (m_FlagsTimer[BG_TEAM_HORDE] < 0)
|
||||
{
|
||||
m_FlagsTimer[BG_TEAM_HORDE] = 0;
|
||||
RespawnFlag(HORDE, true);
|
||||
}
|
||||
}
|
||||
if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_GROUND)
|
||||
{
|
||||
m_FlagsDropTimer[BG_TEAM_HORDE] -= diff;
|
||||
|
||||
if (m_FlagsDropTimer[BG_TEAM_HORDE] < 0)
|
||||
{
|
||||
m_FlagsDropTimer[BG_TEAM_HORDE] = 0;
|
||||
RespawnFlagAfterDrop(HORDE);
|
||||
m_BothFlagsKept = false;
|
||||
}
|
||||
}
|
||||
if (m_BothFlagsKept)
|
||||
{
|
||||
m_FlagSpellForceTimer += diff;
|
||||
if (m_FlagDebuffState == 0 && m_FlagSpellForceTimer >= 600000) //10 minutes
|
||||
{
|
||||
if (Player * plr = objmgr.GetPlayer(m_FlagKeepers[0]))
|
||||
plr->CastSpell(plr,WS_SPELL_FOCUSED_ASSAULT,true);
|
||||
if (Player * plr = objmgr.GetPlayer(m_FlagKeepers[1]))
|
||||
plr->CastSpell(plr,WS_SPELL_FOCUSED_ASSAULT,true);
|
||||
m_FlagDebuffState = 1;
|
||||
}
|
||||
else if (m_FlagDebuffState == 1 && m_FlagSpellForceTimer >= 900000) //15 minutes
|
||||
{
|
||||
if (Player * plr = objmgr.GetPlayer(m_FlagKeepers[0]))
|
||||
{
|
||||
plr->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT);
|
||||
plr->CastSpell(plr,WS_SPELL_BRUTAL_ASSAULT,true);
|
||||
}
|
||||
if (Player * plr = objmgr.GetPlayer(m_FlagKeepers[1]))
|
||||
{
|
||||
plr->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT);
|
||||
plr->CastSpell(plr,WS_SPELL_BRUTAL_ASSAULT,true);
|
||||
}
|
||||
m_FlagDebuffState = 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_FlagSpellForceTimer = 0; //reset timer.
|
||||
m_FlagDebuffState = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BattleGroundWS::StartingEventCloseDoors()
|
||||
{
|
||||
for (uint32 i = BG_WS_OBJECT_DOOR_A_1; i <= BG_WS_OBJECT_DOOR_H_4; ++i)
|
||||
{
|
||||
DoorClose(i);
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
}
|
||||
for (uint32 i = BG_WS_OBJECT_A_FLAG; i <= BG_WS_OBJECT_BERSERKBUFF_2; ++i)
|
||||
SpawnBGObject(i, RESPAWN_ONE_DAY);
|
||||
|
||||
UpdateWorldState(BG_WS_STATE_TIMER_ACTIVE, 1);
|
||||
UpdateWorldState(BG_WS_STATE_TIMER, 25);
|
||||
}
|
||||
|
||||
void BattleGroundWS::StartingEventOpenDoors()
|
||||
{
|
||||
for (uint32 i = BG_WS_OBJECT_DOOR_A_1; i <= BG_WS_OBJECT_DOOR_A_4; ++i)
|
||||
DoorOpen(i);
|
||||
for (uint32 i = BG_WS_OBJECT_DOOR_H_1; i <= BG_WS_OBJECT_DOOR_H_2; ++i)
|
||||
DoorOpen(i);
|
||||
|
||||
SpawnBGObject(BG_WS_OBJECT_DOOR_A_5, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(BG_WS_OBJECT_DOOR_A_6, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(BG_WS_OBJECT_DOOR_H_3, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(BG_WS_OBJECT_DOOR_H_4, RESPAWN_ONE_DAY);
|
||||
|
||||
for (uint32 i = BG_WS_OBJECT_A_FLAG; i <= BG_WS_OBJECT_BERSERKBUFF_2; ++i)
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
}
|
||||
|
||||
void BattleGroundWS::AddPlayer(Player *plr)
|
||||
{
|
||||
BattleGround::AddPlayer(plr);
|
||||
//create score and add it to map, default values are set in constructor
|
||||
BattleGroundWGScore* sc = new BattleGroundWGScore;
|
||||
|
||||
m_PlayerScores[plr->GetGUID()] = sc;
|
||||
}
|
||||
|
||||
void BattleGroundWS::RespawnFlag(uint32 Team, bool captured)
|
||||
{
|
||||
if (Team == ALLIANCE)
|
||||
{
|
||||
sLog.outDebug("Respawn Alliance flag");
|
||||
m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_BASE;
|
||||
}
|
||||
else
|
||||
{
|
||||
sLog.outDebug("Respawn Horde flag");
|
||||
m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_ON_BASE;
|
||||
}
|
||||
|
||||
if (captured)
|
||||
{
|
||||
//when map_update will be allowed for battlegrounds this code will be useless
|
||||
SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_IMMEDIATELY);
|
||||
SendMessageToAll(LANG_BG_WS_F_PLACED, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
PlaySoundToAll(BG_WS_SOUND_FLAGS_RESPAWNED); // flag respawned sound...
|
||||
}
|
||||
m_BothFlagsKept = false;
|
||||
}
|
||||
|
||||
void BattleGroundWS::RespawnFlagAfterDrop(uint32 team)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
RespawnFlag(team,false);
|
||||
if (team == ALLIANCE)
|
||||
{
|
||||
SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_IMMEDIATELY);
|
||||
SendMessageToAll(LANG_BG_WS_ALLIANCE_FLAG_RESPAWNED, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_IMMEDIATELY);
|
||||
SendMessageToAll(LANG_BG_WS_HORDE_FLAG_RESPAWNED, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
}
|
||||
|
||||
PlaySoundToAll(BG_WS_SOUND_FLAGS_RESPAWNED);
|
||||
|
||||
GameObject *obj = GetBgMap()->GetGameObject(GetDroppedFlagGUID(team));
|
||||
if (obj)
|
||||
obj->Delete();
|
||||
else
|
||||
sLog.outError("unknown droped flag bg, guid: %u",GUID_LOPART(GetDroppedFlagGUID(team)));
|
||||
|
||||
SetDroppedFlagGUID(0,team);
|
||||
m_BothFlagsKept = false;
|
||||
}
|
||||
|
||||
void BattleGroundWS::EventPlayerCapturedFlag(Player *Source)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
uint32 winner = 0;
|
||||
|
||||
Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
|
||||
if (Source->GetTeam() == ALLIANCE)
|
||||
{
|
||||
if (!this->IsHordeFlagPickedup())
|
||||
return;
|
||||
SetHordeFlagPicker(0); // must be before aura remove to prevent 2 events (drop+capture) at the same time
|
||||
// horde flag in base (but not respawned yet)
|
||||
m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_WAIT_RESPAWN;
|
||||
// Drop Horde Flag from Player
|
||||
Source->RemoveAurasDueToSpell(BG_WS_SPELL_WARSONG_FLAG);
|
||||
if (m_FlagDebuffState == 1)
|
||||
Source->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT);
|
||||
if (m_FlagDebuffState == 2)
|
||||
Source->RemoveAurasDueToSpell(WS_SPELL_BRUTAL_ASSAULT);
|
||||
if (GetTeamScore(ALLIANCE) < BG_WS_MAX_TEAM_SCORE)
|
||||
AddPoint(ALLIANCE, 1);
|
||||
PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_ALLIANCE);
|
||||
RewardReputationToTeam(890, m_ReputationCapture, ALLIANCE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!this->IsAllianceFlagPickedup())
|
||||
return;
|
||||
SetAllianceFlagPicker(0); // must be before aura remove to prevent 2 events (drop+capture) at the same time
|
||||
// alliance flag in base (but not respawned yet)
|
||||
m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_WAIT_RESPAWN;
|
||||
// Drop Alliance Flag from Player
|
||||
Source->RemoveAurasDueToSpell(BG_WS_SPELL_SILVERWING_FLAG);
|
||||
if (m_FlagDebuffState == 1)
|
||||
Source->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT);
|
||||
if (m_FlagDebuffState == 2)
|
||||
Source->RemoveAurasDueToSpell(WS_SPELL_BRUTAL_ASSAULT);
|
||||
if (GetTeamScore(HORDE) < BG_WS_MAX_TEAM_SCORE)
|
||||
AddPoint(HORDE, 1);
|
||||
PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_HORDE);
|
||||
RewardReputationToTeam(889, m_ReputationCapture, HORDE);
|
||||
}
|
||||
//for flag capture is reward 2 honorable kills
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(2), Source->GetTeam());
|
||||
|
||||
SpawnBGObject(BG_WS_OBJECT_H_FLAG, BG_WS_FLAG_RESPAWN_TIME);
|
||||
SpawnBGObject(BG_WS_OBJECT_A_FLAG, BG_WS_FLAG_RESPAWN_TIME);
|
||||
|
||||
if (Source->GetTeam() == ALLIANCE)
|
||||
SendMessageToAll(LANG_BG_WS_CAPTURED_HF, CHAT_MSG_BG_SYSTEM_ALLIANCE, Source);
|
||||
else
|
||||
SendMessageToAll(LANG_BG_WS_CAPTURED_AF, CHAT_MSG_BG_SYSTEM_HORDE, Source);
|
||||
|
||||
UpdateFlagState(Source->GetTeam(), 1); // flag state none
|
||||
UpdateTeamScore(Source->GetTeam());
|
||||
// only flag capture should be updated
|
||||
UpdatePlayerScore(Source, SCORE_FLAG_CAPTURES, 1); // +1 flag captures
|
||||
|
||||
if (!m_FirstFlagCaptureTeam)
|
||||
SetFirstFlagCapture(Source->GetTeam());
|
||||
|
||||
if (GetTeamScore(ALLIANCE) == BG_WS_MAX_TEAM_SCORE)
|
||||
winner = ALLIANCE;
|
||||
|
||||
if (GetTeamScore(HORDE) == BG_WS_MAX_TEAM_SCORE)
|
||||
winner = HORDE;
|
||||
|
||||
if (winner)
|
||||
{
|
||||
UpdateWorldState(BG_WS_FLAG_UNK_ALLIANCE, 0);
|
||||
UpdateWorldState(BG_WS_FLAG_UNK_HORDE, 0);
|
||||
UpdateWorldState(BG_WS_FLAG_STATE_ALLIANCE, 1);
|
||||
UpdateWorldState(BG_WS_FLAG_STATE_HORDE, 1);
|
||||
UpdateWorldState(BG_WS_STATE_TIMER_ACTIVE, 0);
|
||||
|
||||
RewardHonorToTeam(BG_WSG_Honor[m_HonorMode][BG_WSG_WIN], winner);
|
||||
EndBattleGround(winner);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_FlagsTimer[GetTeamIndexByTeamId(Source->GetTeam()) ? 0 : 1] = BG_WS_FLAG_RESPAWN_TIME;
|
||||
}
|
||||
}
|
||||
|
||||
void BattleGroundWS::EventPlayerDroppedFlag(Player *Source)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
{
|
||||
// if not running, do not cast things at the dropper player (prevent spawning the "dropped" flag), neither send unnecessary messages
|
||||
// just take off the aura
|
||||
if (Source->GetTeam() == ALLIANCE)
|
||||
{
|
||||
if (!this->IsHordeFlagPickedup())
|
||||
return;
|
||||
if (GetHordeFlagPickerGUID() == Source->GetGUID())
|
||||
{
|
||||
SetHordeFlagPicker(0);
|
||||
Source->RemoveAurasDueToSpell(BG_WS_SPELL_WARSONG_FLAG);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!this->IsAllianceFlagPickedup())
|
||||
return;
|
||||
if (GetAllianceFlagPickerGUID() == Source->GetGUID())
|
||||
{
|
||||
SetAllianceFlagPicker(0);
|
||||
Source->RemoveAurasDueToSpell(BG_WS_SPELL_SILVERWING_FLAG);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool set = false;
|
||||
|
||||
if (Source->GetTeam() == ALLIANCE)
|
||||
{
|
||||
if (!IsHordeFlagPickedup())
|
||||
return;
|
||||
if (GetHordeFlagPickerGUID() == Source->GetGUID())
|
||||
{
|
||||
SetHordeFlagPicker(0);
|
||||
Source->RemoveAurasDueToSpell(BG_WS_SPELL_WARSONG_FLAG);
|
||||
if (m_FlagDebuffState == 1)
|
||||
Source->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT);
|
||||
if (m_FlagDebuffState == 2)
|
||||
Source->RemoveAurasDueToSpell(WS_SPELL_BRUTAL_ASSAULT);
|
||||
m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_ON_GROUND;
|
||||
Source->CastSpell(Source, BG_WS_SPELL_WARSONG_FLAG_DROPPED, true);
|
||||
set = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!IsAllianceFlagPickedup())
|
||||
return;
|
||||
if (GetAllianceFlagPickerGUID() == Source->GetGUID())
|
||||
{
|
||||
SetAllianceFlagPicker(0);
|
||||
Source->RemoveAurasDueToSpell(BG_WS_SPELL_SILVERWING_FLAG);
|
||||
if (m_FlagDebuffState == 1)
|
||||
Source->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT);
|
||||
if (m_FlagDebuffState == 2)
|
||||
Source->RemoveAurasDueToSpell(WS_SPELL_BRUTAL_ASSAULT);
|
||||
m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_GROUND;
|
||||
Source->CastSpell(Source, BG_WS_SPELL_SILVERWING_FLAG_DROPPED, true);
|
||||
set = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (set)
|
||||
{
|
||||
Source->CastSpell(Source, SPELL_RECENTLY_DROPPED_FLAG, true);
|
||||
UpdateFlagState(Source->GetTeam(), 1);
|
||||
|
||||
if (Source->GetTeam() == ALLIANCE)
|
||||
{
|
||||
SendMessageToAll(LANG_BG_WS_DROPPED_HF, CHAT_MSG_BG_SYSTEM_HORDE, Source);
|
||||
UpdateWorldState(BG_WS_FLAG_UNK_HORDE, uint32(-1));
|
||||
}
|
||||
else
|
||||
{
|
||||
SendMessageToAll(LANG_BG_WS_DROPPED_AF, CHAT_MSG_BG_SYSTEM_ALLIANCE, Source);
|
||||
UpdateWorldState(BG_WS_FLAG_UNK_ALLIANCE, uint32(-1));
|
||||
}
|
||||
|
||||
m_FlagsDropTimer[GetTeamIndexByTeamId(Source->GetTeam()) ? 0 : 1] = BG_WS_FLAG_DROP_TIME;
|
||||
}
|
||||
}
|
||||
|
||||
void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
int32 message_id = 0;
|
||||
ChatMsg type = CHAT_MSG_BG_SYSTEM_NEUTRAL;
|
||||
|
||||
//alliance flag picked up from base
|
||||
if (Source->GetTeam() == HORDE && this->GetFlagState(ALLIANCE) == BG_WS_FLAG_STATE_ON_BASE
|
||||
&& this->m_BgObjects[BG_WS_OBJECT_A_FLAG] == target_obj->GetGUID())
|
||||
{
|
||||
message_id = LANG_BG_WS_PICKEDUP_AF;
|
||||
type = CHAT_MSG_BG_SYSTEM_HORDE;
|
||||
PlaySoundToAll(BG_WS_SOUND_ALLIANCE_FLAG_PICKED_UP);
|
||||
SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_ONE_DAY);
|
||||
SetAllianceFlagPicker(Source->GetGUID());
|
||||
m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_PLAYER;
|
||||
//update world state to show correct flag carrier
|
||||
UpdateFlagState(HORDE, BG_WS_FLAG_STATE_ON_PLAYER);
|
||||
UpdateWorldState(BG_WS_FLAG_UNK_ALLIANCE, 1);
|
||||
Source->CastSpell(Source, BG_WS_SPELL_SILVERWING_FLAG, true);
|
||||
if (m_FlagState[1] == BG_WS_FLAG_STATE_ON_PLAYER)
|
||||
m_BothFlagsKept = true;
|
||||
}
|
||||
|
||||
//horde flag picked up from base
|
||||
if (Source->GetTeam() == ALLIANCE && this->GetFlagState(HORDE) == BG_WS_FLAG_STATE_ON_BASE
|
||||
&& this->m_BgObjects[BG_WS_OBJECT_H_FLAG] == target_obj->GetGUID())
|
||||
{
|
||||
message_id = LANG_BG_WS_PICKEDUP_HF;
|
||||
type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
|
||||
PlaySoundToAll(BG_WS_SOUND_HORDE_FLAG_PICKED_UP);
|
||||
SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_ONE_DAY);
|
||||
SetHordeFlagPicker(Source->GetGUID());
|
||||
m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_ON_PLAYER;
|
||||
//update world state to show correct flag carrier
|
||||
UpdateFlagState(ALLIANCE, BG_WS_FLAG_STATE_ON_PLAYER);
|
||||
UpdateWorldState(BG_WS_FLAG_UNK_HORDE, 1);
|
||||
Source->CastSpell(Source, BG_WS_SPELL_WARSONG_FLAG, true);
|
||||
if (m_FlagState[0] == BG_WS_FLAG_STATE_ON_PLAYER)
|
||||
m_BothFlagsKept = true;
|
||||
}
|
||||
|
||||
//Alliance flag on ground(not in base) (returned or picked up again from ground!)
|
||||
if (GetFlagState(ALLIANCE) == BG_WS_FLAG_STATE_ON_GROUND && Source->IsWithinDistInMap(target_obj, 10))
|
||||
{
|
||||
if (Source->GetTeam() == ALLIANCE)
|
||||
{
|
||||
message_id = LANG_BG_WS_RETURNED_AF;
|
||||
type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
|
||||
UpdateFlagState(HORDE, BG_WS_FLAG_STATE_WAIT_RESPAWN);
|
||||
RespawnFlag(ALLIANCE, false);
|
||||
SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_IMMEDIATELY);
|
||||
PlaySoundToAll(BG_WS_SOUND_FLAG_RETURNED);
|
||||
UpdatePlayerScore(Source, SCORE_FLAG_RETURNS, 1);
|
||||
m_BothFlagsKept = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
message_id = LANG_BG_WS_PICKEDUP_AF;
|
||||
type = CHAT_MSG_BG_SYSTEM_HORDE;
|
||||
PlaySoundToAll(BG_WS_SOUND_ALLIANCE_FLAG_PICKED_UP);
|
||||
SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_ONE_DAY);
|
||||
SetAllianceFlagPicker(Source->GetGUID());
|
||||
Source->CastSpell(Source, BG_WS_SPELL_SILVERWING_FLAG, true);
|
||||
m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_PLAYER;
|
||||
UpdateFlagState(HORDE, BG_WS_FLAG_STATE_ON_PLAYER);
|
||||
if (m_FlagDebuffState == 1)
|
||||
Source->CastSpell(Source,WS_SPELL_FOCUSED_ASSAULT,true);
|
||||
if (m_FlagDebuffState == 2)
|
||||
Source->CastSpell(Source,WS_SPELL_BRUTAL_ASSAULT,true);
|
||||
UpdateWorldState(BG_WS_FLAG_UNK_ALLIANCE, 1);
|
||||
}
|
||||
//called in HandleGameObjectUseOpcode:
|
||||
//target_obj->Delete();
|
||||
}
|
||||
|
||||
//Horde flag on ground(not in base) (returned or picked up again)
|
||||
if (GetFlagState(HORDE) == BG_WS_FLAG_STATE_ON_GROUND && Source->IsWithinDistInMap(target_obj, 10))
|
||||
{
|
||||
if (Source->GetTeam() == HORDE)
|
||||
{
|
||||
message_id = LANG_BG_WS_RETURNED_HF;
|
||||
type = CHAT_MSG_BG_SYSTEM_HORDE;
|
||||
UpdateFlagState(ALLIANCE, BG_WS_FLAG_STATE_WAIT_RESPAWN);
|
||||
RespawnFlag(HORDE, false);
|
||||
SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_IMMEDIATELY);
|
||||
PlaySoundToAll(BG_WS_SOUND_FLAG_RETURNED);
|
||||
UpdatePlayerScore(Source, SCORE_FLAG_RETURNS, 1);
|
||||
m_BothFlagsKept = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
message_id = LANG_BG_WS_PICKEDUP_HF;
|
||||
type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
|
||||
PlaySoundToAll(BG_WS_SOUND_HORDE_FLAG_PICKED_UP);
|
||||
SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_ONE_DAY);
|
||||
SetHordeFlagPicker(Source->GetGUID());
|
||||
Source->CastSpell(Source, BG_WS_SPELL_WARSONG_FLAG, true);
|
||||
m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_ON_PLAYER;
|
||||
UpdateFlagState(ALLIANCE, BG_WS_FLAG_STATE_ON_PLAYER);
|
||||
if (m_FlagDebuffState == 1)
|
||||
Source->CastSpell(Source,WS_SPELL_FOCUSED_ASSAULT,true);
|
||||
if (m_FlagDebuffState == 2)
|
||||
Source->CastSpell(Source,WS_SPELL_BRUTAL_ASSAULT,true);
|
||||
UpdateWorldState(BG_WS_FLAG_UNK_HORDE, 1);
|
||||
}
|
||||
//called in HandleGameObjectUseOpcode:
|
||||
//target_obj->Delete();
|
||||
}
|
||||
|
||||
if (!message_id)
|
||||
return;
|
||||
|
||||
SendMessageToAll(message_id, type, Source);
|
||||
Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
|
||||
}
|
||||
|
||||
void BattleGroundWS::RemovePlayer(Player *plr, uint64 guid)
|
||||
{
|
||||
// sometimes flag aura not removed :(
|
||||
if (IsAllianceFlagPickedup() && m_FlagKeepers[BG_TEAM_ALLIANCE] == guid)
|
||||
{
|
||||
if (!plr)
|
||||
{
|
||||
sLog.outError("BattleGroundWS: Removing offline player who has the FLAG!!");
|
||||
this->SetAllianceFlagPicker(0);
|
||||
this->RespawnFlag(ALLIANCE, false);
|
||||
}
|
||||
else
|
||||
this->EventPlayerDroppedFlag(plr);
|
||||
}
|
||||
if (IsHordeFlagPickedup() && m_FlagKeepers[BG_TEAM_HORDE] == guid)
|
||||
{
|
||||
if (!plr)
|
||||
{
|
||||
sLog.outError("BattleGroundWS: Removing offline player who has the FLAG!!");
|
||||
this->SetHordeFlagPicker(0);
|
||||
this->RespawnFlag(HORDE, false);
|
||||
}
|
||||
else
|
||||
this->EventPlayerDroppedFlag(plr);
|
||||
}
|
||||
}
|
||||
|
||||
void BattleGroundWS::UpdateFlagState(uint32 team, uint32 value)
|
||||
{
|
||||
if (team == ALLIANCE)
|
||||
UpdateWorldState(BG_WS_FLAG_STATE_ALLIANCE, value);
|
||||
else
|
||||
UpdateWorldState(BG_WS_FLAG_STATE_HORDE, value);
|
||||
}
|
||||
|
||||
void BattleGroundWS::UpdateTeamScore(uint32 team)
|
||||
{
|
||||
if (team == ALLIANCE)
|
||||
UpdateWorldState(BG_WS_FLAG_CAPTURES_ALLIANCE, GetTeamScore(team));
|
||||
else
|
||||
UpdateWorldState(BG_WS_FLAG_CAPTURES_HORDE, GetTeamScore(team));
|
||||
}
|
||||
|
||||
void BattleGroundWS::HandleAreaTrigger(Player *Source, uint32 Trigger)
|
||||
{
|
||||
// this is wrong way to implement these things. On official it done by gameobject spell cast.
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
//uint32 SpellId = 0;
|
||||
//uint64 buff_guid = 0;
|
||||
switch(Trigger)
|
||||
{
|
||||
case 3686: // Alliance elixir of speed spawn. Trigger not working, because located inside other areatrigger, can be replaced by IsWithinDist(object, dist) in BattleGround::Update().
|
||||
//buff_guid = m_BgObjects[BG_WS_OBJECT_SPEEDBUFF_1];
|
||||
break;
|
||||
case 3687: // Horde elixir of speed spawn. Trigger not working, because located inside other areatrigger, can be replaced by IsWithinDist(object, dist) in BattleGround::Update().
|
||||
//buff_guid = m_BgObjects[BG_WS_OBJECT_SPEEDBUFF_2];
|
||||
break;
|
||||
case 3706: // Alliance elixir of regeneration spawn
|
||||
//buff_guid = m_BgObjects[BG_WS_OBJECT_REGENBUFF_1];
|
||||
break;
|
||||
case 3708: // Horde elixir of regeneration spawn
|
||||
//buff_guid = m_BgObjects[BG_WS_OBJECT_REGENBUFF_2];
|
||||
break;
|
||||
case 3707: // Alliance elixir of berserk spawn
|
||||
//buff_guid = m_BgObjects[BG_WS_OBJECT_BERSERKBUFF_1];
|
||||
break;
|
||||
case 3709: // Horde elixir of berserk spawn
|
||||
//buff_guid = m_BgObjects[BG_WS_OBJECT_BERSERKBUFF_2];
|
||||
break;
|
||||
case 3646: // Alliance Flag spawn
|
||||
if (m_FlagState[BG_TEAM_HORDE] && !m_FlagState[BG_TEAM_ALLIANCE])
|
||||
if (GetHordeFlagPickerGUID() == Source->GetGUID())
|
||||
EventPlayerCapturedFlag(Source);
|
||||
break;
|
||||
case 3647: // Horde Flag spawn
|
||||
if (m_FlagState[BG_TEAM_ALLIANCE] && !m_FlagState[BG_TEAM_HORDE])
|
||||
if (GetAllianceFlagPickerGUID() == Source->GetGUID())
|
||||
EventPlayerCapturedFlag(Source);
|
||||
break;
|
||||
case 3649: // unk1
|
||||
case 3688: // unk2
|
||||
case 4628: // unk3
|
||||
case 4629: // unk4
|
||||
break;
|
||||
default:
|
||||
sLog.outError("WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger);
|
||||
Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger);
|
||||
break;
|
||||
}
|
||||
|
||||
//if (buff_guid)
|
||||
// HandleTriggerBuff(buff_guid,Source);
|
||||
}
|
||||
|
||||
bool BattleGroundWS::SetupBattleGround()
|
||||
{
|
||||
// flags
|
||||
if (!AddObject(BG_WS_OBJECT_A_FLAG, BG_OBJECT_A_FLAG_WS_ENTRY, 1540.423f, 1481.325f, 351.8284f, 3.089233f, 0, 0, 0.9996573f, 0.02617699f, BG_WS_FLAG_RESPAWN_TIME/1000)
|
||||
|| !AddObject(BG_WS_OBJECT_H_FLAG, BG_OBJECT_H_FLAG_WS_ENTRY, 916.0226f, 1434.405f, 345.413f, 0.01745329f, 0, 0, 0.008726535f, 0.9999619f, BG_WS_FLAG_RESPAWN_TIME/1000)
|
||||
// buffs
|
||||
|| !AddObject(BG_WS_OBJECT_SPEEDBUFF_1, BG_OBJECTID_SPEEDBUFF_ENTRY, 1449.93f, 1470.71f, 342.6346f, -1.64061f, 0, 0, 0.7313537f, -0.6819983f, BUFF_RESPAWN_TIME)
|
||||
|| !AddObject(BG_WS_OBJECT_SPEEDBUFF_2, BG_OBJECTID_SPEEDBUFF_ENTRY, 1005.171f, 1447.946f, 335.9032f, 1.64061f, 0, 0, 0.7313537f, 0.6819984f, BUFF_RESPAWN_TIME)
|
||||
|| !AddObject(BG_WS_OBJECT_REGENBUFF_1, BG_OBJECTID_REGENBUFF_ENTRY, 1317.506f, 1550.851f, 313.2344f, -0.2617996f, 0, 0, 0.1305263f, -0.9914448f, BUFF_RESPAWN_TIME)
|
||||
|| !AddObject(BG_WS_OBJECT_REGENBUFF_2, BG_OBJECTID_REGENBUFF_ENTRY, 1110.451f, 1353.656f, 316.5181f, -0.6806787f, 0, 0, 0.333807f, -0.9426414f, BUFF_RESPAWN_TIME)
|
||||
|| !AddObject(BG_WS_OBJECT_BERSERKBUFF_1, BG_OBJECTID_BERSERKERBUFF_ENTRY, 1320.09f, 1378.79f, 314.7532f, 1.186824f, 0, 0, 0.5591929f, 0.8290376f, BUFF_RESPAWN_TIME)
|
||||
|| !AddObject(BG_WS_OBJECT_BERSERKBUFF_2, BG_OBJECTID_BERSERKERBUFF_ENTRY, 1139.688f, 1560.288f, 306.8432f, -2.443461f, 0, 0, 0.9396926f, -0.3420201f, BUFF_RESPAWN_TIME)
|
||||
// alliance gates
|
||||
|| !AddObject(BG_WS_OBJECT_DOOR_A_1, BG_OBJECT_DOOR_A_1_WS_ENTRY, 1503.335f, 1493.466f, 352.1888f, 3.115414f, 0, 0, 0.9999143f, 0.01308903f, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_WS_OBJECT_DOOR_A_2, BG_OBJECT_DOOR_A_2_WS_ENTRY, 1492.478f, 1457.912f, 342.9689f, 3.115414f, 0, 0, 0.9999143f, 0.01308903f, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_WS_OBJECT_DOOR_A_3, BG_OBJECT_DOOR_A_3_WS_ENTRY, 1468.503f, 1494.357f, 351.8618f, 3.115414f, 0, 0, 0.9999143f, 0.01308903f, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_WS_OBJECT_DOOR_A_4, BG_OBJECT_DOOR_A_4_WS_ENTRY, 1471.555f, 1458.778f, 362.6332f, 3.115414f, 0, 0, 0.9999143f, 0.01308903f, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_WS_OBJECT_DOOR_A_5, BG_OBJECT_DOOR_A_5_WS_ENTRY, 1492.347f, 1458.34f, 342.3712f, -0.03490669f, 0, 0, 0.01745246f, -0.9998477f, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_WS_OBJECT_DOOR_A_6, BG_OBJECT_DOOR_A_6_WS_ENTRY, 1503.466f, 1493.367f, 351.7352f, -0.03490669f, 0, 0, 0.01745246f, -0.9998477f, RESPAWN_IMMEDIATELY)
|
||||
// horde gates
|
||||
|| !AddObject(BG_WS_OBJECT_DOOR_H_1, BG_OBJECT_DOOR_H_1_WS_ENTRY, 949.1663f, 1423.772f, 345.6241f, -0.5756807f, -0.01673368f, -0.004956111f, -0.2839723f, 0.9586737f, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_WS_OBJECT_DOOR_H_2, BG_OBJECT_DOOR_H_2_WS_ENTRY, 953.0507f, 1459.842f, 340.6526f, -1.99662f, -0.1971825f, 0.1575096f, -0.8239487f, 0.5073641f, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_WS_OBJECT_DOOR_H_3, BG_OBJECT_DOOR_H_3_WS_ENTRY, 949.9523f, 1422.751f, 344.9273f, 0.0f, 0, 0, 0, 1, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_WS_OBJECT_DOOR_H_4, BG_OBJECT_DOOR_H_4_WS_ENTRY, 950.7952f, 1459.583f, 342.1523f, 0.05235988f, 0, 0, 0.02617695f, 0.9996573f, RESPAWN_IMMEDIATELY)
|
||||
)
|
||||
{
|
||||
sLog.outErrorDb("BatteGroundWS: Failed to spawn some object BattleGround not created!");
|
||||
return false;
|
||||
}
|
||||
|
||||
WorldSafeLocsEntry const *sg = sWorldSafeLocsStore.LookupEntry(WS_GRAVEYARD_MAIN_ALLIANCE);
|
||||
if (!sg || !AddSpiritGuide(WS_SPIRIT_MAIN_ALLIANCE, sg->x, sg->y, sg->z, 3.124139f, ALLIANCE))
|
||||
{
|
||||
sLog.outErrorDb("BatteGroundWS: Failed to spawn Alliance spirit guide! BattleGround not created!");
|
||||
return false;
|
||||
}
|
||||
|
||||
sg = sWorldSafeLocsStore.LookupEntry(WS_GRAVEYARD_MAIN_HORDE);
|
||||
if (!sg || !AddSpiritGuide(WS_SPIRIT_MAIN_HORDE, sg->x, sg->y, sg->z, 3.193953f, HORDE))
|
||||
{
|
||||
sLog.outErrorDb("BatteGroundWS: Failed to spawn Horde spirit guide! BattleGround not created!");
|
||||
return false;
|
||||
}
|
||||
|
||||
sLog.outDebug("BatteGroundWS: BG objects and spirit guides spawned");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BattleGroundWS::Reset()
|
||||
{
|
||||
//call parent's class reset
|
||||
BattleGround::Reset();
|
||||
|
||||
m_FlagKeepers[BG_TEAM_ALLIANCE] = 0;
|
||||
m_FlagKeepers[BG_TEAM_HORDE] = 0;
|
||||
m_DroppedFlagGUID[BG_TEAM_ALLIANCE] = 0;
|
||||
m_DroppedFlagGUID[BG_TEAM_HORDE] = 0;
|
||||
m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_BASE;
|
||||
m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_ON_BASE;
|
||||
m_TeamScores[BG_TEAM_ALLIANCE] = 0;
|
||||
m_TeamScores[BG_TEAM_HORDE] = 0;
|
||||
bool isBGWeekend = sBattleGroundMgr.IsBGWeekend(GetTypeID());
|
||||
m_ReputationCapture = (isBGWeekend) ? 45 : 35;
|
||||
m_HonorWinKills = (isBGWeekend) ? 3 : 1;
|
||||
m_HonorEndKills = (isBGWeekend) ? 4 : 2;
|
||||
// For WorldState
|
||||
m_minutesElapsed = 0;
|
||||
m_FirstFlagCaptureTeam = 0;
|
||||
|
||||
/* Spirit nodes is static at this BG and then not required deleting at BG reset.
|
||||
if (m_BgCreatures[WS_SPIRIT_MAIN_ALLIANCE])
|
||||
DelCreature(WS_SPIRIT_MAIN_ALLIANCE);
|
||||
if (m_BgCreatures[WS_SPIRIT_MAIN_HORDE])
|
||||
DelCreature(WS_SPIRIT_MAIN_HORDE);
|
||||
*/
|
||||
}
|
||||
|
||||
void BattleGroundWS::EndBattleGround(uint32 winner)
|
||||
{
|
||||
//win reward
|
||||
if (winner == ALLIANCE)
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(m_HonorWinKills), ALLIANCE);
|
||||
if (winner == HORDE)
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(m_HonorWinKills), HORDE);
|
||||
//complete map_end rewards (even if no team wins)
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(m_HonorEndKills), ALLIANCE);
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(m_HonorEndKills), HORDE);
|
||||
|
||||
BattleGround::EndBattleGround(winner);
|
||||
}
|
||||
|
||||
void BattleGroundWS::HandleKillPlayer(Player *player, Player *killer)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
EventPlayerDroppedFlag(player);
|
||||
|
||||
BattleGround::HandleKillPlayer(player, killer);
|
||||
}
|
||||
|
||||
void BattleGroundWS::UpdatePlayerScore(Player *Source, uint32 type, uint32 value, bool doAddHonor)
|
||||
{
|
||||
|
||||
BattleGroundScoreMap::iterator itr = m_PlayerScores.find(Source->GetGUID());
|
||||
if (itr == m_PlayerScores.end()) // player not found
|
||||
return;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case SCORE_FLAG_CAPTURES: // flags captured
|
||||
((BattleGroundWGScore*)itr->second)->FlagCaptures += value;
|
||||
break;
|
||||
case SCORE_FLAG_RETURNS: // flags returned
|
||||
((BattleGroundWGScore*)itr->second)->FlagReturns += value;
|
||||
break;
|
||||
default:
|
||||
BattleGround::UpdatePlayerScore(Source, type, value, doAddHonor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
WorldSafeLocsEntry const* BattleGroundWS::GetClosestGraveYard(Player* player)
|
||||
{
|
||||
//if status in progress, it returns main graveyards with spiritguides
|
||||
//else it will return the graveyard in the flagroom - this is especially good
|
||||
//if a player dies in preparation phase - then the player can't cheat
|
||||
//and teleport to the graveyard outside the flagroom
|
||||
//and start running around, while the doors are still closed
|
||||
if (player->GetTeam() == ALLIANCE)
|
||||
{
|
||||
if (GetStatus() == STATUS_IN_PROGRESS)
|
||||
return sWorldSafeLocsStore.LookupEntry(WS_GRAVEYARD_MAIN_ALLIANCE);
|
||||
else
|
||||
return sWorldSafeLocsStore.LookupEntry(WS_GRAVEYARD_FLAGROOM_ALLIANCE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GetStatus() == STATUS_IN_PROGRESS)
|
||||
return sWorldSafeLocsStore.LookupEntry(WS_GRAVEYARD_MAIN_HORDE);
|
||||
else
|
||||
return sWorldSafeLocsStore.LookupEntry(WS_GRAVEYARD_FLAGROOM_HORDE);
|
||||
}
|
||||
}
|
||||
|
||||
void BattleGroundWS::FillInitialWorldStates(WorldPacket& data)
|
||||
{
|
||||
data << uint32(BG_WS_FLAG_CAPTURES_ALLIANCE) << uint32(GetTeamScore(ALLIANCE));
|
||||
data << uint32(BG_WS_FLAG_CAPTURES_HORDE) << uint32(GetTeamScore(HORDE));
|
||||
|
||||
if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_GROUND)
|
||||
data << uint32(BG_WS_FLAG_UNK_ALLIANCE) << uint32(-1);
|
||||
else if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_PLAYER)
|
||||
data << uint32(BG_WS_FLAG_UNK_ALLIANCE) << uint32(1);
|
||||
else
|
||||
data << uint32(BG_WS_FLAG_UNK_ALLIANCE) << uint32(0);
|
||||
|
||||
if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_GROUND)
|
||||
data << uint32(BG_WS_FLAG_UNK_HORDE) << uint32(-1);
|
||||
else if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_PLAYER)
|
||||
data << uint32(BG_WS_FLAG_UNK_HORDE) << uint32(1);
|
||||
else
|
||||
data << uint32(BG_WS_FLAG_UNK_HORDE) << uint32(0);
|
||||
|
||||
data << uint32(BG_WS_FLAG_CAPTURES_MAX) << uint32(BG_WS_MAX_TEAM_SCORE);
|
||||
|
||||
if (GetStatus() == STATUS_IN_PROGRESS)
|
||||
{
|
||||
data << uint32(BG_WS_STATE_TIMER_ACTIVE) << uint32(1);
|
||||
data << uint32(BG_WS_STATE_TIMER) << uint32(25-m_minutesElapsed);
|
||||
}
|
||||
else
|
||||
data << uint32(BG_WS_STATE_TIMER_ACTIVE) << uint32(0);
|
||||
|
||||
if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_PLAYER)
|
||||
data << uint32(BG_WS_FLAG_STATE_ALLIANCE) << uint32(2);
|
||||
else
|
||||
data << uint32(BG_WS_FLAG_STATE_ALLIANCE) << uint32(1);
|
||||
|
||||
if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_PLAYER)
|
||||
data << uint32(BG_WS_FLAG_STATE_HORDE) << uint32(2);
|
||||
else
|
||||
data << uint32(BG_WS_FLAG_STATE_HORDE) << uint32(1);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __BATTLEGROUNDWS_H
|
||||
#define __BATTLEGROUNDWS_H
|
||||
|
||||
#include "BattleGround.h"
|
||||
|
||||
enum BG_WS_TimerOrScore
|
||||
{
|
||||
BG_WS_MAX_TEAM_SCORE = 3,
|
||||
BG_WS_FLAG_RESPAWN_TIME = 23000,
|
||||
BG_WS_FLAG_DROP_TIME = 10000,
|
||||
BG_WS_SPELL_FORCE_TIME = 600000,
|
||||
BG_WS_SPELL_BRUTAL_TIME = 900000
|
||||
};
|
||||
|
||||
enum BG_WS_Sound
|
||||
{
|
||||
BG_WS_SOUND_FLAG_CAPTURED_ALLIANCE = 8173,
|
||||
BG_WS_SOUND_FLAG_CAPTURED_HORDE = 8213,
|
||||
BG_WS_SOUND_FLAG_PLACED = 8232,
|
||||
BG_WS_SOUND_FLAG_RETURNED = 8192,
|
||||
BG_WS_SOUND_HORDE_FLAG_PICKED_UP = 8212,
|
||||
BG_WS_SOUND_ALLIANCE_FLAG_PICKED_UP = 8174,
|
||||
BG_WS_SOUND_FLAGS_RESPAWNED = 8232
|
||||
};
|
||||
|
||||
enum BG_WS_SpellId
|
||||
{
|
||||
BG_WS_SPELL_WARSONG_FLAG = 23333,
|
||||
BG_WS_SPELL_WARSONG_FLAG_DROPPED = 23334,
|
||||
BG_WS_SPELL_SILVERWING_FLAG = 23335,
|
||||
BG_WS_SPELL_SILVERWING_FLAG_DROPPED = 23336,
|
||||
BG_WS_SPELL_FOCUSED_ASSAULT = 46392,
|
||||
BG_WS_SPELL_BRUTAL_ASSAULT = 46393
|
||||
};
|
||||
|
||||
enum BG_WS_WorldStates
|
||||
{
|
||||
BG_WS_FLAG_UNK_ALLIANCE = 1545,
|
||||
BG_WS_FLAG_UNK_HORDE = 1546,
|
||||
// FLAG_UNK = 1547,
|
||||
BG_WS_FLAG_CAPTURES_ALLIANCE = 1581,
|
||||
BG_WS_FLAG_CAPTURES_HORDE = 1582,
|
||||
BG_WS_FLAG_CAPTURES_MAX = 1601,
|
||||
BG_WS_FLAG_STATE_HORDE = 2338,
|
||||
BG_WS_FLAG_STATE_ALLIANCE = 2339,
|
||||
BG_WS_STATE_TIMER = 4248,
|
||||
BG_WS_STATE_TIMER_ACTIVE = 4247
|
||||
};
|
||||
|
||||
enum BG_WS_ObjectTypes
|
||||
{
|
||||
BG_WS_OBJECT_DOOR_A_1 = 0,
|
||||
BG_WS_OBJECT_DOOR_A_2 = 1,
|
||||
BG_WS_OBJECT_DOOR_A_3 = 2,
|
||||
BG_WS_OBJECT_DOOR_A_4 = 3,
|
||||
BG_WS_OBJECT_DOOR_A_5 = 4,
|
||||
BG_WS_OBJECT_DOOR_A_6 = 5,
|
||||
BG_WS_OBJECT_DOOR_H_1 = 6,
|
||||
BG_WS_OBJECT_DOOR_H_2 = 7,
|
||||
BG_WS_OBJECT_DOOR_H_3 = 8,
|
||||
BG_WS_OBJECT_DOOR_H_4 = 9,
|
||||
BG_WS_OBJECT_A_FLAG = 10,
|
||||
BG_WS_OBJECT_H_FLAG = 11,
|
||||
BG_WS_OBJECT_SPEEDBUFF_1 = 12,
|
||||
BG_WS_OBJECT_SPEEDBUFF_2 = 13,
|
||||
BG_WS_OBJECT_REGENBUFF_1 = 14,
|
||||
BG_WS_OBJECT_REGENBUFF_2 = 15,
|
||||
BG_WS_OBJECT_BERSERKBUFF_1 = 16,
|
||||
BG_WS_OBJECT_BERSERKBUFF_2 = 17,
|
||||
BG_WS_OBJECT_MAX = 18
|
||||
};
|
||||
|
||||
enum BG_WS_ObjectEntry
|
||||
{
|
||||
BG_OBJECT_DOOR_A_1_WS_ENTRY = 179918,
|
||||
BG_OBJECT_DOOR_A_2_WS_ENTRY = 179919,
|
||||
BG_OBJECT_DOOR_A_3_WS_ENTRY = 179920,
|
||||
BG_OBJECT_DOOR_A_4_WS_ENTRY = 179921,
|
||||
BG_OBJECT_DOOR_A_5_WS_ENTRY = 180322,
|
||||
BG_OBJECT_DOOR_A_6_WS_ENTRY = 180322,
|
||||
BG_OBJECT_DOOR_H_1_WS_ENTRY = 179916,
|
||||
BG_OBJECT_DOOR_H_2_WS_ENTRY = 179917,
|
||||
BG_OBJECT_DOOR_H_3_WS_ENTRY = 180322,
|
||||
BG_OBJECT_DOOR_H_4_WS_ENTRY = 180322,
|
||||
BG_OBJECT_A_FLAG_WS_ENTRY = 179830,
|
||||
BG_OBJECT_H_FLAG_WS_ENTRY = 179831,
|
||||
BG_OBJECT_A_FLAG_GROUND_WS_ENTRY = 179785,
|
||||
BG_OBJECT_H_FLAG_GROUND_WS_ENTRY = 179786
|
||||
};
|
||||
|
||||
enum BG_WS_FlagState
|
||||
{
|
||||
BG_WS_FLAG_STATE_ON_BASE = 0,
|
||||
BG_WS_FLAG_STATE_WAIT_RESPAWN = 1,
|
||||
BG_WS_FLAG_STATE_ON_PLAYER = 2,
|
||||
BG_WS_FLAG_STATE_ON_GROUND = 3
|
||||
};
|
||||
|
||||
enum BG_WS_Graveyards
|
||||
{
|
||||
WS_GRAVEYARD_FLAGROOM_ALLIANCE = 769,
|
||||
WS_GRAVEYARD_FLAGROOM_HORDE = 770,
|
||||
WS_GRAVEYARD_MAIN_ALLIANCE = 771,
|
||||
WS_GRAVEYARD_MAIN_HORDE = 772
|
||||
};
|
||||
|
||||
enum BG_WS_CreatureTypes
|
||||
{
|
||||
WS_SPIRIT_MAIN_ALLIANCE = 0,
|
||||
WS_SPIRIT_MAIN_HORDE = 1,
|
||||
|
||||
BG_CREATURES_MAX_WS = 2
|
||||
};
|
||||
|
||||
enum BG_WS_CarrierDebuffs
|
||||
{
|
||||
WS_SPELL_FOCUSED_ASSAULT = 46392,
|
||||
WS_SPELL_BRUTAL_ASSAULT = 46393
|
||||
};
|
||||
|
||||
class BattleGroundWGScore : public BattleGroundScore
|
||||
{
|
||||
public:
|
||||
BattleGroundWGScore() : FlagCaptures(0), FlagReturns(0) {};
|
||||
virtual ~BattleGroundWGScore() {};
|
||||
uint32 FlagCaptures;
|
||||
uint32 FlagReturns;
|
||||
};
|
||||
|
||||
class BattleGroundWS : public BattleGround
|
||||
{
|
||||
friend class BattleGroundMgr;
|
||||
|
||||
public:
|
||||
/* Construction */
|
||||
BattleGroundWS();
|
||||
~BattleGroundWS();
|
||||
void Update(uint32 diff);
|
||||
|
||||
/* inherited from BattlegroundClass */
|
||||
virtual void AddPlayer(Player *plr);
|
||||
virtual void StartingEventCloseDoors();
|
||||
virtual void StartingEventOpenDoors();
|
||||
|
||||
/* BG Flags */
|
||||
uint64 GetAllianceFlagPickerGUID() const { return m_FlagKeepers[BG_TEAM_ALLIANCE]; }
|
||||
uint64 GetHordeFlagPickerGUID() const { return m_FlagKeepers[BG_TEAM_HORDE]; }
|
||||
void SetAllianceFlagPicker(uint64 guid) { m_FlagKeepers[BG_TEAM_ALLIANCE] = guid; }
|
||||
void SetHordeFlagPicker(uint64 guid) { m_FlagKeepers[BG_TEAM_HORDE] = guid; }
|
||||
bool IsAllianceFlagPickedup() const { return m_FlagKeepers[BG_TEAM_ALLIANCE] != 0; }
|
||||
bool IsHordeFlagPickedup() const { return m_FlagKeepers[BG_TEAM_HORDE] != 0; }
|
||||
void RespawnFlag(uint32 Team, bool captured);
|
||||
void RespawnFlagAfterDrop(uint32 Team);
|
||||
uint8 GetFlagState(uint32 team) { return m_FlagState[GetTeamIndexByTeamId(team)]; }
|
||||
void AddTimedAura(uint32 aura);
|
||||
void RemoveTimedAura(uint32 aura);
|
||||
bool IsBrutalTimerDone;
|
||||
bool IsForceTimerDone;
|
||||
|
||||
/* Battleground Events */
|
||||
virtual void EventPlayerDroppedFlag(Player *Source);
|
||||
virtual void EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj);
|
||||
virtual void EventPlayerCapturedFlag(Player *Source);
|
||||
|
||||
void RemovePlayer(Player *plr, uint64 guid);
|
||||
void HandleAreaTrigger(Player *Source, uint32 Trigger);
|
||||
void HandleKillPlayer(Player *player, Player *killer);
|
||||
bool SetupBattleGround();
|
||||
virtual void Reset();
|
||||
void EndBattleGround(uint32 winner);
|
||||
virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player);
|
||||
|
||||
void UpdateFlagState(uint32 team, uint32 value);
|
||||
void SetFirstFlagCapture(uint32 team) { m_FirstFlagCaptureTeam = team; }
|
||||
void UpdateTeamScore(uint32 team);
|
||||
void UpdatePlayerScore(Player *Source, uint32 type, uint32 value, bool doAddHonor = true);
|
||||
void SetDroppedFlagGUID(uint64 guid, uint32 TeamID) { m_DroppedFlagGUID[GetTeamIndexByTeamId(TeamID)] = guid;}
|
||||
uint64 GetDroppedFlagGUID(uint32 TeamID) { return m_DroppedFlagGUID[GetTeamIndexByTeamId(TeamID)];}
|
||||
virtual void FillInitialWorldStates(WorldPacket& data);
|
||||
|
||||
/* Scorekeeping */
|
||||
uint32 GetTeamScore(uint32 TeamID) const { return m_TeamScores[GetTeamIndexByTeamId(TeamID)]; }
|
||||
void AddPoint(uint32 TeamID, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] += Points; }
|
||||
void SetTeamPoint(uint32 TeamID, uint32 Points = 0) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] = Points; }
|
||||
void RemovePoint(uint32 TeamID, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] -= Points; }
|
||||
private:
|
||||
uint64 m_FlagKeepers[2]; // 0 - alliance, 1 - horde
|
||||
uint64 m_DroppedFlagGUID[2];
|
||||
uint8 m_FlagState[2]; // for checking flag state
|
||||
int32 m_FlagsTimer[2];
|
||||
int32 m_FlagsDropTimer[2];
|
||||
uint32 m_FirstFlagCaptureTeam; // Winner is based on this if score is equal
|
||||
|
||||
uint32 m_ReputationCapture;
|
||||
uint32 m_HonorWinKills;
|
||||
uint32 m_HonorEndKills;
|
||||
int32 m_FlagSpellForceTimer;
|
||||
bool m_BothFlagsKept;
|
||||
uint8 m_FlagDebuffState; // 0 - no debuffs, 1 - focused assault, 2 - brutal assault
|
||||
uint8 m_minutesElapsed;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,358 @@
|
||||
# Enable precompiled headers when using the GCC compiler.
|
||||
IF(DO_PCH AND CMAKE_COMPILER_IS_GNUCXX)
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
|
||||
ENDIF(DO_PCH AND CMAKE_COMPILER_IS_GNUCXX)
|
||||
|
||||
SET(game_STAT_SRCS
|
||||
AccountMgr.cpp
|
||||
AccountMgr.h
|
||||
AddonMgr.cpp
|
||||
AddonMgr.h
|
||||
AchievementMgr.h
|
||||
AchievementMgr.cpp
|
||||
AddonHandler.cpp
|
||||
AddonHandler.h
|
||||
CombatAI.cpp
|
||||
CombatAI.h
|
||||
ArenaTeam.cpp
|
||||
ArenaTeam.h
|
||||
ArenaTeamHandler.cpp
|
||||
AuctionHouseHandler.cpp
|
||||
AuctionHouseBot.cpp
|
||||
AuctionHouseBot.h
|
||||
AuctionHouseMgr.cpp
|
||||
AuctionHouseMgr.h
|
||||
Bag.cpp
|
||||
Bag.h
|
||||
BattleGround.cpp
|
||||
BattleGroundAA.cpp
|
||||
BattleGroundAB.cpp
|
||||
BattleGroundRB.cpp
|
||||
BattleGroundAV.cpp
|
||||
BattleGroundBE.cpp
|
||||
BattleGroundDS.cpp
|
||||
BattleGroundEY.cpp
|
||||
BattleGroundIC.cpp
|
||||
BattleGroundNA.cpp
|
||||
BattleGroundRL.cpp
|
||||
BattleGroundRV.cpp
|
||||
BattleGroundSA.cpp
|
||||
BattleGroundWS.cpp
|
||||
BattleGround.h
|
||||
BattleGroundAA.h
|
||||
BattleGroundAB.h
|
||||
BattleGroundRB.h
|
||||
BattleGroundAV.h
|
||||
BattleGroundBE.h
|
||||
BattleGroundDS.h
|
||||
BattleGroundEY.h
|
||||
BattleGroundIC.h
|
||||
BattleGroundNA.h
|
||||
BattleGroundRL.h
|
||||
BattleGroundRV.h
|
||||
BattleGroundSA.h
|
||||
BattleGroundWS.h
|
||||
BattleGroundHandler.cpp
|
||||
BattleGroundMgr.cpp
|
||||
BattleGroundMgr.h
|
||||
Calendar.cpp
|
||||
Calendar.h
|
||||
CalendarHandler.cpp
|
||||
Cell.h
|
||||
CellImpl.h
|
||||
Channel.cpp
|
||||
Channel.h
|
||||
ChannelHandler.cpp
|
||||
CharacterHandler.cpp
|
||||
ChannelMgr.h
|
||||
ChannelMgr.cpp
|
||||
Chat.cpp
|
||||
Chat.h
|
||||
ChatHandler.cpp
|
||||
CombatHandler.cpp
|
||||
ConditionMgr.cpp
|
||||
ConditionMgr.h
|
||||
ConfusedMovementGenerator.cpp
|
||||
ConfusedMovementGenerator.h
|
||||
Corpse.cpp
|
||||
Corpse.h
|
||||
CreatureAI.cpp
|
||||
CreatureAI.h
|
||||
CreatureAIFactory.h
|
||||
CreatureAIImpl.h
|
||||
CreatureAIRegistry.cpp
|
||||
CreatureAIRegistry.h
|
||||
CreatureAISelector.cpp
|
||||
CreatureAISelector.h
|
||||
CreatureEventAI.cpp
|
||||
CreatureEventAIMgr.cpp
|
||||
Creature.cpp
|
||||
Creature.h
|
||||
CreatureGroups.cpp
|
||||
CreatureGroups.h
|
||||
DBCEnums.h
|
||||
DBCStores.cpp
|
||||
DBCStores.h
|
||||
DBCStructure.h
|
||||
DBCfmt.h
|
||||
Debugcmds.cpp
|
||||
DestinationHolder.cpp
|
||||
DestinationHolder.h
|
||||
DestinationHolderImp.h
|
||||
DuelHandler.cpp
|
||||
DynamicObject.cpp
|
||||
DynamicObject.h
|
||||
FleeingMovementGenerator.cpp
|
||||
FleeingMovementGenerator.h
|
||||
Formulas.h
|
||||
GameEventMgr.cpp
|
||||
GameEventMgr.h
|
||||
GameObject.cpp
|
||||
GameObject.h
|
||||
GlobalEvents.cpp
|
||||
GlobalEvents.h
|
||||
GossipDef.cpp
|
||||
GossipDef.h
|
||||
GridDefines.h
|
||||
GridNotifiers.cpp
|
||||
GridNotifiers.h
|
||||
GridNotifiersImpl.h
|
||||
GridStates.cpp
|
||||
GridStates.h
|
||||
Group.cpp
|
||||
Group.h
|
||||
GroupHandler.cpp
|
||||
GuardAI.cpp
|
||||
GuardAI.h
|
||||
Guild.cpp
|
||||
Guild.h
|
||||
GuildHandler.cpp
|
||||
HomeMovementGenerator.cpp
|
||||
HomeMovementGenerator.h
|
||||
HostileRefManager.cpp
|
||||
HostileRefManager.h
|
||||
IdleMovementGenerator.cpp
|
||||
IdleMovementGenerator.h
|
||||
InstanceData.cpp
|
||||
InstanceData.h
|
||||
InstanceSaveMgr.cpp
|
||||
InstanceSaveMgr.h
|
||||
Item.cpp
|
||||
Item.h
|
||||
ItemEnchantmentMgr.cpp
|
||||
ItemEnchantmentMgr.h
|
||||
ItemHandler.cpp
|
||||
ItemPrototype.h
|
||||
Language.h
|
||||
Level0.cpp
|
||||
Level1.cpp
|
||||
Level2.cpp
|
||||
Level3.cpp
|
||||
LFG.h
|
||||
LFGHandler.cpp
|
||||
LFGMgr.cpp
|
||||
LFGMgr.h
|
||||
LootHandler.cpp
|
||||
LootMgr.cpp
|
||||
LootMgr.h
|
||||
Mail.cpp
|
||||
Mail.h
|
||||
Map.cpp
|
||||
Map.h
|
||||
MapInstanced.cpp
|
||||
MapInstanced.h
|
||||
MapManager.cpp
|
||||
MapManager.h
|
||||
MapUpdater.cpp
|
||||
MapUpdater.h
|
||||
MapReference.h
|
||||
MapRefManager.h
|
||||
MiscHandler.cpp
|
||||
MotionMaster.cpp
|
||||
MotionMaster.h
|
||||
MovementGenerator.cpp
|
||||
MovementGenerator.h
|
||||
MovementGeneratorImpl.h
|
||||
MovementHandler.cpp
|
||||
NPCHandler.cpp
|
||||
NPCHandler.h
|
||||
PassiveAI.cpp
|
||||
PassiveAI.h
|
||||
ObjectAccessor.cpp
|
||||
ObjectAccessor.h
|
||||
Object.cpp
|
||||
ObjectDefines.h
|
||||
ObjectGridLoader.cpp
|
||||
ObjectGridLoader.h
|
||||
Object.h
|
||||
ObjectMgr.cpp
|
||||
ObjectMgr.h
|
||||
ObjectPosSelector.cpp
|
||||
ObjectPosSelector.h
|
||||
Opcodes.cpp
|
||||
Opcodes.h
|
||||
OutdoorPvP.cpp
|
||||
OutdoorPvP.h
|
||||
OutdoorPvPEP.cpp
|
||||
OutdoorPvPEP.h
|
||||
OutdoorPvPHP.cpp
|
||||
OutdoorPvPHP.h
|
||||
OutdoorPvPMgr.cpp
|
||||
OutdoorPvPMgr.h
|
||||
OutdoorPvPNA.cpp
|
||||
OutdoorPvPNA.h
|
||||
OutdoorPvPSI.cpp
|
||||
OutdoorPvPSI.h
|
||||
OutdoorPvPTF.cpp
|
||||
OutdoorPvPTF.h
|
||||
OutdoorPvPZM.cpp
|
||||
OutdoorPvPZM.h
|
||||
Path.h
|
||||
PetAI.cpp
|
||||
PetAI.h
|
||||
Pet.cpp
|
||||
Pet.h
|
||||
PetHandler.cpp
|
||||
PetitionsHandler.cpp
|
||||
Player.cpp
|
||||
Player.h
|
||||
PlayerDump.cpp
|
||||
PlayerDump.h
|
||||
PointMovementGenerator.cpp
|
||||
PointMovementGenerator.h
|
||||
PoolHandler.cpp
|
||||
PoolHandler.h
|
||||
QueryHandler.cpp
|
||||
QuestDef.cpp
|
||||
QuestDef.h
|
||||
QuestHandler.cpp
|
||||
RandomMovementGenerator.cpp
|
||||
RandomMovementGenerator.h
|
||||
ReactorAI.cpp
|
||||
ReactorAI.h
|
||||
ReputationMgr.cpp
|
||||
ReputationMgr.h
|
||||
ScriptedSmartAI.cpp
|
||||
ScriptedSmartAI.h
|
||||
ScriptLoader.cpp
|
||||
ScriptLoader.h
|
||||
ScriptMgr.cpp
|
||||
ScriptMgr.h
|
||||
ScriptSystem.cpp
|
||||
ScriptSystem.h
|
||||
SharedDefines.h
|
||||
SkillHandler.cpp
|
||||
SpellAuraDefines.h
|
||||
SpellAuras.cpp
|
||||
SpellAuras.h
|
||||
SpellAuraEffects.cpp
|
||||
SpellAuraEffects.h
|
||||
Spell.cpp
|
||||
SpellEffects.cpp
|
||||
Spell.h
|
||||
SkillDiscovery.cpp
|
||||
SkillDiscovery.h
|
||||
SkillExtraItems.cpp
|
||||
SkillExtraItems.h
|
||||
SpellHandler.cpp
|
||||
SocialMgr.cpp
|
||||
SocialMgr.h
|
||||
SpellMgr.cpp
|
||||
SpellMgr.h
|
||||
StatSystem.cpp
|
||||
TargetedMovementGenerator.cpp
|
||||
TargetedMovementGenerator.h
|
||||
TaxiHandler.cpp
|
||||
TemporarySummon.cpp
|
||||
TemporarySummon.h
|
||||
TicketHandler.cpp
|
||||
Tools.cpp
|
||||
Tools.h
|
||||
TotemAI.cpp
|
||||
TotemAI.h
|
||||
Totem.cpp
|
||||
Totem.h
|
||||
TradeHandler.cpp
|
||||
Transports.cpp
|
||||
Transports.h
|
||||
ThreatManager.cpp
|
||||
ThreatManager.h
|
||||
Traveller.h
|
||||
Unit.cpp
|
||||
Unit.h
|
||||
UnitAI.cpp
|
||||
UnitAI.h
|
||||
UnitEvents.h
|
||||
UpdateData.cpp
|
||||
UpdateData.h
|
||||
UpdateFields.h
|
||||
UpdateMask.h
|
||||
Vehicle.cpp
|
||||
Vehicle.h
|
||||
VoiceChatHandler.cpp
|
||||
WaypointManager.cpp
|
||||
WaypointManager.h
|
||||
WaypointMovementGenerator.cpp
|
||||
WaypointMovementGenerator.h
|
||||
Weather.cpp
|
||||
Weather.h
|
||||
World.cpp
|
||||
World.h
|
||||
WorldLog.cpp
|
||||
WorldLog.h
|
||||
WorldSession.cpp
|
||||
WorldSession.h
|
||||
WorldSocket.cpp
|
||||
WorldSocket.h
|
||||
WorldSocketMgr.cpp
|
||||
WorldSocketMgr.h
|
||||
FollowerReference.cpp
|
||||
FollowerReference.h
|
||||
FollowerRefManager.h
|
||||
GroupReference.cpp
|
||||
GroupReference.h
|
||||
GroupRefManager.h
|
||||
OutdoorPvPImpl.h
|
||||
ZoneScript.h
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${ACE_INCLUDE_DIR}
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_SOURCE_DIR}/dep/include
|
||||
${CMAKE_SOURCE_DIR}/src/framework
|
||||
${CMAKE_SOURCE_DIR}/src/shared
|
||||
${CMAKE_SOURCE_DIR}/src/shared/vmap
|
||||
${CMAKE_SOURCE_DIR}/src/shared/Database
|
||||
${CMAKE_SOURCE_DIR}/src/game
|
||||
${MYSQL_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
if(NOT DO_SCRIPTS)
|
||||
SET(game_STAT_SRCS ${game_STAT_SRCS}
|
||||
ScriptedEscortAI.cpp
|
||||
ScriptedEscortAI.h
|
||||
ScriptedPch.cpp
|
||||
ScriptedPch.h
|
||||
ScriptedCreature.cpp
|
||||
ScriptedCreature.h
|
||||
ScriptedFollowerAI.cpp
|
||||
ScriptedFollowerAI.h
|
||||
ScriptedGossip.h
|
||||
ScriptedGuardAI.cpp
|
||||
ScriptedGuardAI.h
|
||||
ScriptedInstance.h
|
||||
ScriptedSimpleAI.cpp
|
||||
ScriptedSimpleAI.h
|
||||
)
|
||||
message("-- Added Script Engine to GAME lib")
|
||||
endif(NOT DO_SCRIPTS)
|
||||
|
||||
add_library(game STATIC ${game_STAT_SRCS})
|
||||
ADD_DEPENDENCIES(game revision.h)
|
||||
|
||||
# Generate precompiled header
|
||||
IF(DO_PCH AND CMAKE_COMPILER_IS_GNUCXX)
|
||||
ADD_PRECOMPILED_HEADER(game ${CMAKE_SOURCE_DIR}/src/game/pchlinux.h)
|
||||
ENDIF(DO_PCH AND CMAKE_COMPILER_IS_GNUCXX)
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_CALENDAR_H
|
||||
#define TRINITY_CALENDAR_H
|
||||
|
||||
class Calendar
|
||||
{
|
||||
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,318 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Common.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
|
||||
#include "InstanceSaveMgr.h"
|
||||
#include "Log.h"
|
||||
#include "Opcodes.h"
|
||||
#include "Player.h"
|
||||
|
||||
void WorldSession::HandleCalendarGetCalendar(WorldPacket & /*recv_data*/)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_GET_CALENDAR"); // empty
|
||||
|
||||
time_t cur_time = time(NULL);
|
||||
|
||||
WorldPacket data(SMSG_CALENDAR_SEND_CALENDAR,4+4*0+4+4*0+4+4);
|
||||
|
||||
data << uint32(0); // invite count
|
||||
/*
|
||||
for (;;)
|
||||
{
|
||||
uint64 inviteId;
|
||||
uint64 unkGuid0;
|
||||
uint8 unk1, unk2, unk3;
|
||||
uint64 creatorGuid;
|
||||
}
|
||||
*/
|
||||
|
||||
data << uint32(0); // event count
|
||||
/*
|
||||
for (;;)
|
||||
{
|
||||
uint64 eventId;
|
||||
std::string title; // 128 chars
|
||||
uint32 type;
|
||||
uint32 occurrenceTime;
|
||||
uint32 flags;
|
||||
uint32 unk4; -- possibly mapid for dungeon/raid
|
||||
uint64 creatorGuid;
|
||||
}
|
||||
*/
|
||||
|
||||
data << uint32(0); // unk
|
||||
data << uint32(secsToTimeBitFields(cur_time)); // current time
|
||||
|
||||
uint32 counter = 0;
|
||||
size_t p_counter = data.wpos();
|
||||
data << uint32(counter); // instance save count
|
||||
|
||||
for (int i = 0; i < MAX_DIFFICULTY; ++i)
|
||||
{
|
||||
for (Player::BoundInstancesMap::const_iterator itr = _player->m_boundInstances[i].begin(); itr != _player->m_boundInstances[i].end(); ++itr)
|
||||
{
|
||||
if (itr->second.perm)
|
||||
{
|
||||
InstanceSave *save = itr->second.save;
|
||||
data << uint32(save->GetMapId());
|
||||
data << uint32(save->GetDifficulty());
|
||||
data << uint32(save->GetResetTime() - cur_time);
|
||||
data << uint64(save->GetInstanceId()); // instance save id as unique instance copy id
|
||||
++counter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data.put<uint32>(p_counter, counter);
|
||||
|
||||
data << uint32(1135753200); // unk (28.12.2005 12:00)
|
||||
|
||||
counter = 0;
|
||||
p_counter = data.wpos();
|
||||
data << uint32(counter); // raid reset count
|
||||
|
||||
ResetTimeByMapDifficultyMap const& resets = sInstanceSaveManager.GetResetTimeMap();
|
||||
for (ResetTimeByMapDifficultyMap::const_iterator itr = resets.begin(); itr != resets.end(); ++itr)
|
||||
{
|
||||
uint32 mapid = PAIR32_LOPART(itr->first);
|
||||
MapEntry const* mapEnt = sMapStore.LookupEntry(mapid);
|
||||
if (!mapEnt || !mapEnt->IsRaid())
|
||||
continue;
|
||||
|
||||
data << uint32(mapid);
|
||||
data << uint32(itr->second - cur_time);
|
||||
data << uint32(mapEnt->unk_time);
|
||||
++counter;
|
||||
}
|
||||
|
||||
data.put<uint32>(p_counter, counter);
|
||||
|
||||
data << uint32(0); // holiday count?
|
||||
/*
|
||||
for (;;)
|
||||
{
|
||||
uint32 unk5, unk6, unk7, unk8, unk9;
|
||||
for (uint32 j = 0; j < 26; ++j)
|
||||
{
|
||||
uint32 unk10;
|
||||
}
|
||||
for (uint32 j = 0; j < 10; ++j)
|
||||
{
|
||||
uint32 unk11;
|
||||
}
|
||||
for (uint32 j = 0; j < 10; ++j)
|
||||
{
|
||||
uint32 unk12;
|
||||
}
|
||||
std::string holidayName; // 64 chars
|
||||
}
|
||||
*/
|
||||
|
||||
sLog.outDebug("Sending calendar");
|
||||
data.hexlike();
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::HandleCalendarGetEvent(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_GET_EVENT");
|
||||
recv_data.hexlike();
|
||||
recv_data.read_skip<uint64>(); // unk
|
||||
}
|
||||
|
||||
void WorldSession::HandleCalendarGuildFilter(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_GUILD_FILTER");
|
||||
recv_data.hexlike();
|
||||
recv_data.read_skip<uint32>(); // unk1
|
||||
recv_data.read_skip<uint32>(); // unk2
|
||||
recv_data.read_skip<uint32>(); // unk3
|
||||
}
|
||||
|
||||
void WorldSession::HandleCalendarArenaTeam(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_ARENA_TEAM");
|
||||
recv_data.hexlike();
|
||||
recv_data.read_skip<uint32>(); // unk
|
||||
}
|
||||
|
||||
void WorldSession::HandleCalendarAddEvent(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_ADD_EVENT");
|
||||
recv_data.hexlike();
|
||||
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
|
||||
|
||||
//std::string unk1, unk2;
|
||||
//recv_data >> (std::string)unk1;
|
||||
//recv_data >> (std::string)unk2;
|
||||
|
||||
//uint8 unk3, unk4;
|
||||
//uint32 unk5, unk6, unk7, unk8, unk9, count = 0;
|
||||
//recv_data >> (uint8)unk3;
|
||||
//recv_data >> (uint8)unk4;
|
||||
//recv_data >> (uint32)unk5;
|
||||
//recv_data >> (uint32)unk6;
|
||||
//recv_data >> (uint32)unk7;
|
||||
//recv_data >> (uint32)unk8;
|
||||
//recv_data >> (uint32)unk9;
|
||||
//if (!((unk9 >> 6) & 1))
|
||||
//{
|
||||
// recv_data >> (uint32)count;
|
||||
// if (count)
|
||||
// {
|
||||
// uint8 unk12,unk13;
|
||||
// uint64 guid;
|
||||
// for (int i=0; i<count; i++)
|
||||
// {
|
||||
// recv_data.readPackGUID(guid);
|
||||
// recv_data >> (uint8)unk12;
|
||||
// recv_data >> (uint8)unk13;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
void WorldSession::HandleCalendarUpdateEvent(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_UPDATE_EVENT");
|
||||
recv_data.hexlike();
|
||||
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
|
||||
|
||||
//recv_data >> uint64
|
||||
//recv_data >> uint64
|
||||
//recv_data >> std::string
|
||||
//recv_data >> std::string
|
||||
//recv_data >> uint8
|
||||
//recv_data >> uint8
|
||||
//recv_data >> uint32
|
||||
//recv_data >> uint32
|
||||
//recv_data >> uint32
|
||||
//recv_data >> uint32
|
||||
//recv_data >> uint32
|
||||
}
|
||||
|
||||
void WorldSession::HandleCalendarRemoveEvent(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_REMOVE_EVENT");
|
||||
recv_data.hexlike();
|
||||
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
|
||||
|
||||
//recv_data >> uint64
|
||||
//recv_data >> uint64
|
||||
//recv_data >> uint32
|
||||
|
||||
}
|
||||
|
||||
void WorldSession::HandleCalendarCopyEvent(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_COPY_EVENT");
|
||||
recv_data.hexlike();
|
||||
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
|
||||
|
||||
//recv_data >> uint64
|
||||
//recv_data >> uint64
|
||||
//recv_data >> uint32
|
||||
|
||||
}
|
||||
|
||||
void WorldSession::HandleCalendarEventInvite(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_INVITE");
|
||||
recv_data.hexlike();
|
||||
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
|
||||
|
||||
//recv_data >> uint64
|
||||
//recv_data >> uint64
|
||||
//recv_data >> std::string
|
||||
//recv_data >> uint8
|
||||
//recv_data >> uint8
|
||||
|
||||
}
|
||||
|
||||
void WorldSession::HandleCalendarEventRsvp(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_RSVP");
|
||||
recv_data.hexlike();
|
||||
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
|
||||
|
||||
//recv_data >> uint64
|
||||
//recv_data >> uint64
|
||||
//recv_data >> uint32
|
||||
|
||||
}
|
||||
|
||||
void WorldSession::HandleCalendarEventRemoveInvite(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_REMOVE_INVITE");
|
||||
recv_data.hexlike();
|
||||
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
|
||||
|
||||
//recv_data.readPackGUID(guid)
|
||||
//recv_data >> uint64
|
||||
//recv_data >> uint64
|
||||
//recv_data >> uint64
|
||||
}
|
||||
|
||||
void WorldSession::HandleCalendarEventStatus(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_STATUS");
|
||||
recv_data.hexlike();
|
||||
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
|
||||
|
||||
//recv_data.readPackGUID(guid)
|
||||
//recv_data >> uint64
|
||||
//recv_data >> uint64
|
||||
//recv_data >> uint64
|
||||
//recv_data >> uint32
|
||||
}
|
||||
|
||||
void WorldSession::HandleCalendarEventModeratorStatus(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_MODERATOR_STATUS");
|
||||
recv_data.hexlike();
|
||||
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
|
||||
|
||||
//recv_data.readPackGUID(guid)
|
||||
//recv_data >> uint64
|
||||
//recv_data >> uint64
|
||||
//recv_data >> uint64
|
||||
//recv_data >> uint32
|
||||
}
|
||||
|
||||
void WorldSession::HandleCalendarComplain(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_COMPLAIN");
|
||||
recv_data.hexlike();
|
||||
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
|
||||
|
||||
//recv_data >> uint64
|
||||
//recv_data >> uint64
|
||||
//recv_data >> uint64
|
||||
}
|
||||
|
||||
void WorldSession::HandleCalendarGetNumPending(WorldPacket & /*recv_data*/)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_GET_NUM_PENDING"); // empty
|
||||
|
||||
WorldPacket data(SMSG_CALENDAR_SEND_NUM_PENDING, 4);
|
||||
data << uint32(0); // 0 - no pending invites, 1 - some pending invites
|
||||
SendPacket(&data);
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_CELL_H
|
||||
#define TRINITY_CELL_H
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "GameSystem/TypeContainer.h"
|
||||
#include "GameSystem/TypeContainerVisitor.h"
|
||||
|
||||
#include "GridDefines.h"
|
||||
|
||||
class Map;
|
||||
class WorldObject;
|
||||
|
||||
enum District
|
||||
{
|
||||
UPPER_DISTRICT = 1,
|
||||
LOWER_DISTRICT = 1 << 1,
|
||||
LEFT_DISTRICT = 1 << 2,
|
||||
RIGHT_DISTRICT = 1 << 3,
|
||||
CENTER_DISTRICT = 1 << 4,
|
||||
UPPER_LEFT_DISTRICT = (UPPER_DISTRICT | LEFT_DISTRICT),
|
||||
UPPER_RIGHT_DISTRICT = (UPPER_DISTRICT | RIGHT_DISTRICT),
|
||||
LOWER_LEFT_DISTRICT = (LOWER_DISTRICT | LEFT_DISTRICT),
|
||||
LOWER_RIGHT_DISTRICT = (LOWER_DISTRICT | RIGHT_DISTRICT),
|
||||
ALL_DISTRICT = (UPPER_DISTRICT | LOWER_DISTRICT | LEFT_DISTRICT | RIGHT_DISTRICT | CENTER_DISTRICT)
|
||||
};
|
||||
|
||||
struct CellArea
|
||||
{
|
||||
CellArea() : right_offset(0), left_offset(0), upper_offset(0), lower_offset(0) {}
|
||||
CellArea(int right, int left, int upper, int lower) : right_offset(right), left_offset(left), upper_offset(upper), lower_offset(lower) {}
|
||||
bool operator!() const { return !right_offset && !left_offset && !upper_offset && !lower_offset; }
|
||||
|
||||
void ResizeBorders(CellPair& begin_cell, CellPair& end_cell) const
|
||||
{
|
||||
begin_cell << left_offset;
|
||||
begin_cell -= lower_offset;
|
||||
end_cell >> right_offset;
|
||||
end_cell += upper_offset;
|
||||
}
|
||||
|
||||
int right_offset;
|
||||
int left_offset;
|
||||
int upper_offset;
|
||||
int lower_offset;
|
||||
};
|
||||
|
||||
struct Cell
|
||||
{
|
||||
Cell() { data.All = 0; }
|
||||
Cell(const Cell &cell) { data.All = cell.data.All; }
|
||||
explicit Cell(CellPair const& p);
|
||||
|
||||
void operator|=(Cell &cell)
|
||||
{
|
||||
data.Part.reserved = 0;
|
||||
cell.data.Part.reserved = 0;
|
||||
uint32 x, y, old_x, old_y;
|
||||
Compute(x, y);
|
||||
cell.Compute(old_x, old_y);
|
||||
|
||||
if (std::abs(int(x-old_x)) > 1 || std::abs(int(y-old_y)) > 1)
|
||||
{
|
||||
data.Part.reserved = ALL_DISTRICT;
|
||||
cell.data.Part.reserved = ALL_DISTRICT;
|
||||
return;
|
||||
}
|
||||
|
||||
if (x < old_x)
|
||||
{
|
||||
data.Part.reserved |= LEFT_DISTRICT;
|
||||
cell.data.Part.reserved |= RIGHT_DISTRICT;
|
||||
}
|
||||
else if (old_x < x)
|
||||
{
|
||||
data.Part.reserved |= RIGHT_DISTRICT;
|
||||
cell.data.Part.reserved |= LEFT_DISTRICT;
|
||||
}
|
||||
if (y < old_y)
|
||||
{
|
||||
data.Part.reserved |= UPPER_DISTRICT;
|
||||
cell.data.Part.reserved |= LOWER_DISTRICT;
|
||||
}
|
||||
else if (old_y < y)
|
||||
{
|
||||
data.Part.reserved |= LOWER_DISTRICT;
|
||||
cell.data.Part.reserved |= UPPER_DISTRICT;
|
||||
}
|
||||
}
|
||||
|
||||
void Compute(uint32 &x, uint32 &y) const
|
||||
{
|
||||
x = data.Part.grid_x*MAX_NUMBER_OF_CELLS + data.Part.cell_x;
|
||||
y = data.Part.grid_y*MAX_NUMBER_OF_CELLS + data.Part.cell_y;
|
||||
}
|
||||
|
||||
bool DiffCell(const Cell &cell) const
|
||||
{
|
||||
return(data.Part.cell_x != cell.data.Part.cell_x ||
|
||||
data.Part.cell_y != cell.data.Part.cell_y);
|
||||
}
|
||||
|
||||
bool DiffGrid(const Cell &cell) const
|
||||
{
|
||||
return(data.Part.grid_x != cell.data.Part.grid_x ||
|
||||
data.Part.grid_y != cell.data.Part.grid_y);
|
||||
}
|
||||
|
||||
uint32 CellX() const { return data.Part.cell_x; }
|
||||
uint32 CellY() const { return data.Part.cell_y; }
|
||||
uint32 GridX() const { return data.Part.grid_x; }
|
||||
uint32 GridY() const { return data.Part.grid_y; }
|
||||
bool NoCreate() const { return data.Part.nocreate; }
|
||||
void SetNoCreate() { data.Part.nocreate = 1; }
|
||||
|
||||
CellPair cellPair() const
|
||||
{
|
||||
return CellPair(
|
||||
data.Part.grid_x*MAX_NUMBER_OF_CELLS+data.Part.cell_x,
|
||||
data.Part.grid_y*MAX_NUMBER_OF_CELLS+data.Part.cell_y);
|
||||
}
|
||||
|
||||
Cell& operator=(const Cell &cell)
|
||||
{
|
||||
this->data.All = cell.data.All;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator == (const Cell &cell) const { return (data.All == cell.data.All); }
|
||||
bool operator != (const Cell &cell) const { return !operator == (cell); }
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned grid_x : 6;
|
||||
unsigned grid_y : 6;
|
||||
unsigned cell_x : 6;
|
||||
unsigned cell_y : 6;
|
||||
unsigned nocreate : 1;
|
||||
unsigned reserved : 7;
|
||||
} Part;
|
||||
uint32 All;
|
||||
} data;
|
||||
|
||||
template<class T, class CONTAINER> void Visit(const CellPair&, TypeContainerVisitor<T, CONTAINER> &visitor, Map &) const;
|
||||
template<class T, class CONTAINER> void Visit(const CellPair&, TypeContainerVisitor<T, CONTAINER> &visitor, Map &, const WorldObject&, float) const;
|
||||
template<class T, class CONTAINER> void Visit(const CellPair&, TypeContainerVisitor<T, CONTAINER> &visitor, Map &, float, float, float) const;
|
||||
|
||||
static CellArea CalculateCellArea(const WorldObject &obj, float radius);
|
||||
static CellArea CalculateCellArea(float x, float y, float radius);
|
||||
|
||||
private:
|
||||
template<class T, class CONTAINER> void VisitCircle(TypeContainerVisitor<T, CONTAINER> &, Map &, const CellPair&, const CellPair&) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_CELLIMPL_H
|
||||
#define TRINITY_CELLIMPL_H
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "Cell.h"
|
||||
#include "Map.h"
|
||||
#include "Object.h"
|
||||
|
||||
inline Cell::Cell(CellPair const& p)
|
||||
{
|
||||
data.Part.grid_x = p.x_coord / MAX_NUMBER_OF_CELLS;
|
||||
data.Part.grid_y = p.y_coord / MAX_NUMBER_OF_CELLS;
|
||||
data.Part.cell_x = p.x_coord % MAX_NUMBER_OF_CELLS;
|
||||
data.Part.cell_y = p.y_coord % MAX_NUMBER_OF_CELLS;
|
||||
data.Part.nocreate = 0;
|
||||
data.Part.reserved = 0;
|
||||
}
|
||||
|
||||
template<class T, class CONTAINER>
|
||||
inline void
|
||||
Cell::Visit(const CellPair& standing_cell, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m) const
|
||||
{
|
||||
if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
|
||||
return;
|
||||
|
||||
uint16 district = (District)this->data.Part.reserved;
|
||||
if (district == CENTER_DISTRICT)
|
||||
{
|
||||
m.Visit(*this, visitor);
|
||||
return;
|
||||
}
|
||||
|
||||
// set up the cell range based on the district
|
||||
// the overloaded operators handle range checking
|
||||
CellPair begin_cell = standing_cell;
|
||||
CellPair end_cell = standing_cell;
|
||||
|
||||
switch(district)
|
||||
{
|
||||
case ALL_DISTRICT:
|
||||
{
|
||||
begin_cell << 1; begin_cell -= 1; // upper left
|
||||
end_cell >> 1; end_cell += 1; // lower right
|
||||
break;
|
||||
}
|
||||
case UPPER_LEFT_DISTRICT:
|
||||
{
|
||||
begin_cell << 1; begin_cell -= 1; // upper left
|
||||
break;
|
||||
}
|
||||
case UPPER_RIGHT_DISTRICT:
|
||||
{
|
||||
begin_cell -= 1; // up
|
||||
end_cell >> 1; // right
|
||||
break;
|
||||
}
|
||||
case LOWER_LEFT_DISTRICT:
|
||||
{
|
||||
begin_cell << 1; // left
|
||||
end_cell += 1; // down
|
||||
break;
|
||||
}
|
||||
case LOWER_RIGHT_DISTRICT:
|
||||
{
|
||||
end_cell >> 1; end_cell += 1; // lower right
|
||||
break;
|
||||
}
|
||||
case LEFT_DISTRICT:
|
||||
{
|
||||
begin_cell -= 1; // up
|
||||
end_cell >> 1; end_cell += 1; // lower right
|
||||
break;
|
||||
}
|
||||
case RIGHT_DISTRICT:
|
||||
{
|
||||
begin_cell << 1; begin_cell -= 1; // upper left
|
||||
end_cell += 1; // down
|
||||
break;
|
||||
}
|
||||
case UPPER_DISTRICT:
|
||||
{
|
||||
begin_cell << 1; begin_cell -= 1; // upper left
|
||||
end_cell >> 1; // right
|
||||
break;
|
||||
}
|
||||
case LOWER_DISTRICT:
|
||||
{
|
||||
begin_cell << 1; // left
|
||||
end_cell >> 1; end_cell += 1; // lower right
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// loop the cell range
|
||||
for (uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; x++)
|
||||
{
|
||||
for (uint32 y = begin_cell.y_coord; y <= end_cell.y_coord; y++)
|
||||
{
|
||||
CellPair cell_pair(x,y);
|
||||
Cell r_zone(cell_pair);
|
||||
r_zone.data.Part.nocreate = this->data.Part.nocreate;
|
||||
m.Visit(r_zone, visitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline int CellHelper(const float radius)
|
||||
{
|
||||
if (radius < 1.0f)
|
||||
return 0;
|
||||
|
||||
return (int)ceilf(radius/SIZE_OF_GRID_CELL);
|
||||
}
|
||||
|
||||
inline CellArea Cell::CalculateCellArea(const WorldObject &obj, float radius)
|
||||
{
|
||||
return Cell::CalculateCellArea(obj.GetPositionX(), obj.GetPositionY(), radius);
|
||||
}
|
||||
|
||||
inline CellArea Cell::CalculateCellArea(float x, float y, float radius)
|
||||
{
|
||||
if (radius <= 0.0f)
|
||||
return CellArea();
|
||||
|
||||
//lets calculate object coord offsets from cell borders.
|
||||
//TODO: add more correct/generic method for this task
|
||||
const float x_offset = (x - CENTER_GRID_CELL_OFFSET)/SIZE_OF_GRID_CELL;
|
||||
const float y_offset = (y - CENTER_GRID_CELL_OFFSET)/SIZE_OF_GRID_CELL;
|
||||
|
||||
const float x_val = floor(x_offset + CENTER_GRID_CELL_ID + 0.5f);
|
||||
const float y_val = floor(y_offset + CENTER_GRID_CELL_ID + 0.5f);
|
||||
|
||||
const float x_off = (x_offset - x_val + CENTER_GRID_CELL_ID) * SIZE_OF_GRID_CELL;
|
||||
const float y_off = (y_offset - y_val + CENTER_GRID_CELL_ID) * SIZE_OF_GRID_CELL;
|
||||
|
||||
const float tmp_diff = radius - CENTER_GRID_CELL_OFFSET;
|
||||
//lets calculate upper/lower/right/left corners for cell search
|
||||
int right = CellHelper(tmp_diff + x_off);
|
||||
int left = CellHelper(tmp_diff - x_off);
|
||||
int upper = CellHelper(tmp_diff + y_off);
|
||||
int lower = CellHelper(tmp_diff - y_off);
|
||||
|
||||
return CellArea(right, left, upper, lower);
|
||||
}
|
||||
|
||||
template<class T, class CONTAINER>
|
||||
inline void
|
||||
Cell::Visit(const CellPair& standing_cell, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, float radius, float x_off, float y_off) const
|
||||
{
|
||||
if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
|
||||
return;
|
||||
|
||||
//no jokes here... Actually placing ASSERT() here was good idea, but
|
||||
//we had some problems with DynamicObjects, which pass radius = 0.0f (DB issue?)
|
||||
//maybe it is better to just return when radius <= 0.0f?
|
||||
if (radius <= 0.0f)
|
||||
{
|
||||
m.Visit(*this, visitor);
|
||||
return;
|
||||
}
|
||||
//lets limit the upper value for search radius
|
||||
if (radius > 333.0f)
|
||||
radius = 333.0f;
|
||||
|
||||
//lets calculate object coord offsets from cell borders.
|
||||
CellArea area = Cell::CalculateCellArea(x_off, y_off, radius);
|
||||
//if radius fits inside standing cell
|
||||
if (!area)
|
||||
{
|
||||
m.Visit(*this, visitor);
|
||||
return;
|
||||
}
|
||||
|
||||
CellPair begin_cell = standing_cell;
|
||||
CellPair end_cell = standing_cell;
|
||||
|
||||
area.ResizeBorders(begin_cell, end_cell);
|
||||
//visit all cells, found in CalculateCellArea()
|
||||
//if radius is known to reach cell area more than 4x4 then we should call optimized VisitCircle
|
||||
//currently this technique works with MAX_NUMBER_OF_CELLS 16 and higher, with lower values
|
||||
//there are nothing to optimize because SIZE_OF_GRID_CELL is too big...
|
||||
if (((end_cell.x_coord - begin_cell.x_coord) > 4) && ((end_cell.y_coord - begin_cell.y_coord) > 4))
|
||||
{
|
||||
VisitCircle(visitor, m, begin_cell, end_cell);
|
||||
return;
|
||||
}
|
||||
|
||||
//ALWAYS visit standing cell first!!! Since we deal with small radiuses
|
||||
//it is very essential to call visitor for standing cell firstly...
|
||||
m.Visit(*this, visitor);
|
||||
|
||||
// loop the cell range
|
||||
for (uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; ++x)
|
||||
{
|
||||
for (uint32 y = begin_cell.y_coord; y <= end_cell.y_coord; ++y)
|
||||
{
|
||||
CellPair cell_pair(x,y);
|
||||
//lets skip standing cell since we already visited it
|
||||
if (cell_pair != standing_cell)
|
||||
{
|
||||
Cell r_zone(cell_pair);
|
||||
r_zone.data.Part.nocreate = this->data.Part.nocreate;
|
||||
m.Visit(r_zone, visitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, class CONTAINER>
|
||||
inline void
|
||||
Cell::Visit(const CellPair& l, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, const WorldObject &obj, float radius) const
|
||||
{
|
||||
//we should increase search radius by object's radius, otherwise
|
||||
//we could have problems with huge creatures, which won't attack nearest players etc
|
||||
Visit(l, visitor, m, radius + obj.GetObjectSize(), obj.GetPositionX(), obj.GetPositionY());
|
||||
}
|
||||
|
||||
template<class T, class CONTAINER>
|
||||
inline void
|
||||
Cell::VisitCircle(TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, const CellPair& begin_cell, const CellPair& end_cell) const
|
||||
{
|
||||
//here is an algorithm for 'filling' circum-squared octagon
|
||||
uint32 x_shift = (uint32)ceilf((end_cell.x_coord - begin_cell.x_coord) * 0.3f - 0.5f);
|
||||
//lets calculate x_start/x_end coords for central strip...
|
||||
const uint32 x_start = begin_cell.x_coord + x_shift;
|
||||
const uint32 x_end = end_cell.x_coord - x_shift;
|
||||
|
||||
//visit central strip with constant width...
|
||||
for (uint32 x = x_start; x <= x_end; ++x)
|
||||
{
|
||||
for (uint32 y = begin_cell.y_coord; y <= end_cell.y_coord; ++y)
|
||||
{
|
||||
CellPair cell_pair(x,y);
|
||||
Cell r_zone(cell_pair);
|
||||
r_zone.data.Part.nocreate = this->data.Part.nocreate;
|
||||
m.Visit(r_zone, visitor);
|
||||
}
|
||||
}
|
||||
|
||||
//if x_shift == 0 then we have too small cell area, which were already
|
||||
//visited at previous step, so just return from procedure...
|
||||
if (x_shift == 0)
|
||||
return;
|
||||
|
||||
uint32 y_start = end_cell.y_coord;
|
||||
uint32 y_end = begin_cell.y_coord;
|
||||
//now we are visiting borders of an octagon...
|
||||
for (uint32 step = 1; step <= (x_start - begin_cell.x_coord); ++step)
|
||||
{
|
||||
//each step reduces strip height by 2 cells...
|
||||
y_end += 1;
|
||||
y_start -= 1;
|
||||
for (uint32 y = y_start; y >= y_end; --y)
|
||||
{
|
||||
//we visit cells symmetrically from both sides, heading from center to sides and from up to bottom
|
||||
//e.g. filling 2 trapezoids after filling central cell strip...
|
||||
CellPair cell_pair_left(x_start - step, y);
|
||||
Cell r_zone_left(cell_pair_left);
|
||||
r_zone_left.data.Part.nocreate = this->data.Part.nocreate;
|
||||
m.Visit(r_zone_left, visitor);
|
||||
|
||||
//right trapezoid cell visit
|
||||
CellPair cell_pair_right(x_end + step, y);
|
||||
Cell r_zone_right(cell_pair_right);
|
||||
r_zone_right.data.Part.nocreate = this->data.Part.nocreate;
|
||||
m.Visit(r_zone_right, visitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _CHANNEL_H
|
||||
#define _CHANNEL_H
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#include "Opcodes.h"
|
||||
#include "Player.h"
|
||||
#include "WorldPacket.h"
|
||||
|
||||
enum ChatNotify
|
||||
{
|
||||
CHAT_JOINED_NOTICE = 0x00, //+ "%s joined channel.";
|
||||
CHAT_LEFT_NOTICE = 0x01, //+ "%s left channel.";
|
||||
//CHAT_SUSPENDED_NOTICE = 0x01, // "%s left channel.";
|
||||
CHAT_YOU_JOINED_NOTICE = 0x02, //+ "Joined Channel: [%s]"; -- You joined
|
||||
//CHAT_YOU_CHANGED_NOTICE = 0x02, // "Changed Channel: [%s]";
|
||||
CHAT_YOU_LEFT_NOTICE = 0x03, //+ "Left Channel: [%s]"; -- You left
|
||||
CHAT_WRONG_PASSWORD_NOTICE = 0x04, //+ "Wrong password for %s.";
|
||||
CHAT_NOT_MEMBER_NOTICE = 0x05, //+ "Not on channel %s.";
|
||||
CHAT_NOT_MODERATOR_NOTICE = 0x06, //+ "Not a moderator of %s.";
|
||||
CHAT_PASSWORD_CHANGED_NOTICE = 0x07, //+ "[%s] Password changed by %s.";
|
||||
CHAT_OWNER_CHANGED_NOTICE = 0x08, //+ "[%s] Owner changed to %s.";
|
||||
CHAT_PLAYER_NOT_FOUND_NOTICE = 0x09, //+ "[%s] Player %s was not found.";
|
||||
CHAT_NOT_OWNER_NOTICE = 0x0A, //+ "[%s] You are not the channel owner.";
|
||||
CHAT_CHANNEL_OWNER_NOTICE = 0x0B, //+ "[%s] Channel owner is %s.";
|
||||
CHAT_MODE_CHANGE_NOTICE = 0x0C, //?
|
||||
CHAT_ANNOUNCEMENTS_ON_NOTICE = 0x0D, //+ "[%s] Channel announcements enabled by %s.";
|
||||
CHAT_ANNOUNCEMENTS_OFF_NOTICE = 0x0E, //+ "[%s] Channel announcements disabled by %s.";
|
||||
CHAT_MODERATION_ON_NOTICE = 0x0F, //+ "[%s] Channel moderation enabled by %s.";
|
||||
CHAT_MODERATION_OFF_NOTICE = 0x10, //+ "[%s] Channel moderation disabled by %s.";
|
||||
CHAT_MUTED_NOTICE = 0x11, //+ "[%s] You do not have permission to speak.";
|
||||
CHAT_PLAYER_KICKED_NOTICE = 0x12, //? "[%s] Player %s kicked by %s.";
|
||||
CHAT_BANNED_NOTICE = 0x13, //+ "[%s] You are banned from that channel.";
|
||||
CHAT_PLAYER_BANNED_NOTICE = 0x14, //? "[%s] Player %s banned by %s.";
|
||||
CHAT_PLAYER_UNBANNED_NOTICE = 0x15, //? "[%s] Player %s unbanned by %s.";
|
||||
CHAT_PLAYER_NOT_BANNED_NOTICE = 0x16, //+ "[%s] Player %s is not banned.";
|
||||
CHAT_PLAYER_ALREADY_MEMBER_NOTICE = 0x17, //+ "[%s] Player %s is already on the channel.";
|
||||
CHAT_INVITE_NOTICE = 0x18, //+ "%2$s has invited you to join the channel '%1$s'.";
|
||||
CHAT_INVITE_WRONG_FACTION_NOTICE = 0x19, //+ "Target is in the wrong alliance for %s.";
|
||||
CHAT_WRONG_FACTION_NOTICE = 0x1A, //+ "Wrong alliance for %s.";
|
||||
CHAT_INVALID_NAME_NOTICE = 0x1B, //+ "Invalid channel name";
|
||||
CHAT_NOT_MODERATED_NOTICE = 0x1C, //+ "%s is not moderated";
|
||||
CHAT_PLAYER_INVITED_NOTICE = 0x1D, //+ "[%s] You invited %s to join the channel";
|
||||
CHAT_PLAYER_INVITE_BANNED_NOTICE = 0x1E, //+ "[%s] %s has been banned.";
|
||||
CHAT_THROTTLED_NOTICE = 0x1F, //+ "[%s] The number of messages that can be sent to this channel is limited, please wait to send another message.";
|
||||
CHAT_NOT_IN_AREA_NOTICE = 0x20, //+ "[%s] You are not in the correct area for this channel."; -- The user is trying to send a chat to a zone specific channel, and they're not physically in that zone.
|
||||
CHAT_NOT_IN_LFG_NOTICE = 0x21, //+ "[%s] You must be queued in looking for group before joining this channel."; -- The user must be in the looking for group system to join LFG chat channels.
|
||||
CHAT_VOICE_ON_NOTICE = 0x22, //+ "[%s] Channel voice enabled by %s.";
|
||||
CHAT_VOICE_OFF_NOTICE = 0x23, //+ "[%s] Channel voice disabled by %s.";
|
||||
};
|
||||
|
||||
enum ChannelFlags
|
||||
{
|
||||
CHANNEL_FLAG_NONE = 0x00,
|
||||
CHANNEL_FLAG_CUSTOM = 0x01,
|
||||
// 0x02
|
||||
CHANNEL_FLAG_TRADE = 0x04,
|
||||
CHANNEL_FLAG_NOT_LFG = 0x08,
|
||||
CHANNEL_FLAG_GENERAL = 0x10,
|
||||
CHANNEL_FLAG_CITY = 0x20,
|
||||
CHANNEL_FLAG_LFG = 0x40,
|
||||
CHANNEL_FLAG_VOICE = 0x80
|
||||
// General 0x18 = 0x10 | 0x08
|
||||
// Trade 0x3C = 0x20 | 0x10 | 0x08 | 0x04
|
||||
// LocalDefence 0x18 = 0x10 | 0x08
|
||||
// GuildRecruitment 0x38 = 0x20 | 0x10 | 0x08
|
||||
// LookingForGroup 0x50 = 0x40 | 0x10
|
||||
};
|
||||
|
||||
enum ChannelDBCFlags
|
||||
{
|
||||
CHANNEL_DBC_FLAG_NONE = 0x00000,
|
||||
CHANNEL_DBC_FLAG_INITIAL = 0x00001, // General, Trade, LocalDefense, LFG
|
||||
CHANNEL_DBC_FLAG_ZONE_DEP = 0x00002, // General, Trade, LocalDefense, GuildRecruitment
|
||||
CHANNEL_DBC_FLAG_GLOBAL = 0x00004, // WorldDefense
|
||||
CHANNEL_DBC_FLAG_TRADE = 0x00008, // Trade
|
||||
CHANNEL_DBC_FLAG_CITY_ONLY = 0x00010, // Trade, GuildRecruitment
|
||||
CHANNEL_DBC_FLAG_CITY_ONLY2 = 0x00020, // Trade, GuildRecruitment
|
||||
CHANNEL_DBC_FLAG_DEFENSE = 0x10000, // LocalDefense, WorldDefense
|
||||
CHANNEL_DBC_FLAG_GUILD_REQ = 0x20000, // GuildRecruitment
|
||||
CHANNEL_DBC_FLAG_LFG = 0x40000 // LookingForGroup
|
||||
};
|
||||
|
||||
enum ChannelMemberFlags
|
||||
{
|
||||
MEMBER_FLAG_NONE = 0x00,
|
||||
MEMBER_FLAG_OWNER = 0x01,
|
||||
MEMBER_FLAG_MODERATOR = 0x02,
|
||||
MEMBER_FLAG_VOICED = 0x04,
|
||||
MEMBER_FLAG_MUTED = 0x08,
|
||||
MEMBER_FLAG_CUSTOM = 0x10,
|
||||
MEMBER_FLAG_MIC_MUTED = 0x20,
|
||||
// 0x40
|
||||
// 0x80
|
||||
};
|
||||
|
||||
class Channel
|
||||
{
|
||||
struct PlayerInfo
|
||||
{
|
||||
uint64 player;
|
||||
uint8 flags;
|
||||
|
||||
bool HasFlag(uint8 flag) { return flags & flag; }
|
||||
void SetFlag(uint8 flag) { if (!HasFlag(flag)) flags |= flag; }
|
||||
bool IsOwner() { return flags & MEMBER_FLAG_OWNER; }
|
||||
void SetOwner(bool state)
|
||||
{
|
||||
if (state) flags |= MEMBER_FLAG_OWNER;
|
||||
else flags &= ~MEMBER_FLAG_OWNER;
|
||||
}
|
||||
bool IsModerator() { return flags & MEMBER_FLAG_MODERATOR; }
|
||||
void SetModerator(bool state)
|
||||
{
|
||||
if (state) flags |= MEMBER_FLAG_MODERATOR;
|
||||
else flags &= ~MEMBER_FLAG_MODERATOR;
|
||||
}
|
||||
bool IsMuted() { return flags & MEMBER_FLAG_MUTED; }
|
||||
void SetMuted(bool state)
|
||||
{
|
||||
if (state) flags |= MEMBER_FLAG_MUTED;
|
||||
else flags &= ~MEMBER_FLAG_MUTED;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::map<uint64, PlayerInfo> PlayerList;
|
||||
PlayerList players;
|
||||
typedef std::set<uint64> BannedList;
|
||||
BannedList banned;
|
||||
bool m_announce;
|
||||
bool m_moderate;
|
||||
bool m_public;
|
||||
std::string m_name;
|
||||
std::string m_password;
|
||||
uint8 m_flags;
|
||||
uint32 m_channelId;
|
||||
uint64 m_ownerGUID;
|
||||
bool m_IsSaved;
|
||||
|
||||
private:
|
||||
// initial packet data (notify type and channel name)
|
||||
void MakeNotifyPacket(WorldPacket *data, uint8 notify_type);
|
||||
// type specific packet data
|
||||
void MakeJoined(WorldPacket *data, uint64 guid); //+ 0x00
|
||||
void MakeLeft(WorldPacket *data, uint64 guid); //+ 0x01
|
||||
void MakeYouJoined(WorldPacket *data); //+ 0x02
|
||||
void MakeYouLeft(WorldPacket *data); //+ 0x03
|
||||
void MakeWrongPassword(WorldPacket *data); //? 0x04
|
||||
void MakeNotMember(WorldPacket *data); //? 0x05
|
||||
void MakeNotModerator(WorldPacket *data); //? 0x06
|
||||
void MakePasswordChanged(WorldPacket *data, uint64 guid); //+ 0x07
|
||||
void MakeOwnerChanged(WorldPacket *data, uint64 guid); //? 0x08
|
||||
void MakePlayerNotFound(WorldPacket *data, const std::string& name); //+ 0x09
|
||||
void MakeNotOwner(WorldPacket *data); //? 0x0A
|
||||
void MakeChannelOwner(WorldPacket *data); //? 0x0B
|
||||
void MakeModeChange(WorldPacket *data, uint64 guid, uint8 oldflags); //+ 0x0C
|
||||
void MakeAnnouncementsOn(WorldPacket *data, uint64 guid); //+ 0x0D
|
||||
void MakeAnnouncementsOff(WorldPacket *data, uint64 guid); //+ 0x0E
|
||||
void MakeModerationOn(WorldPacket *data, uint64 guid); //+ 0x0F
|
||||
void MakeModerationOff(WorldPacket *data, uint64 guid); //+ 0x10
|
||||
void MakeMuted(WorldPacket *data); //? 0x11
|
||||
void MakePlayerKicked(WorldPacket *data, uint64 bad, uint64 good); //? 0x12
|
||||
void MakeBanned(WorldPacket *data); //? 0x13
|
||||
void MakePlayerBanned(WorldPacket *data, uint64 bad, uint64 good); //? 0x14
|
||||
void MakePlayerUnbanned(WorldPacket *data, uint64 bad, uint64 good); //? 0x15
|
||||
void MakePlayerNotBanned(WorldPacket *data, uint64 guid); //? 0x16
|
||||
void MakePlayerAlreadyMember(WorldPacket *data, uint64 guid); //+ 0x17
|
||||
void MakeInvite(WorldPacket *data, uint64 guid); //? 0x18
|
||||
void MakeInviteWrongFaction(WorldPacket *data); //? 0x19
|
||||
void MakeWrongFaction(WorldPacket *data); //? 0x1A
|
||||
void MakeInvalidName(WorldPacket *data); //? 0x1B
|
||||
void MakeNotModerated(WorldPacket *data); //? 0x1C
|
||||
void MakePlayerInvited(WorldPacket *data, const std::string& name); //+ 0x1D
|
||||
void MakePlayerInviteBanned(WorldPacket *data, uint64 guid); //? 0x1E
|
||||
void MakeThrottled(WorldPacket *data); //? 0x1F
|
||||
void MakeNotInArea(WorldPacket *data); //? 0x20
|
||||
void MakeNotInLfg(WorldPacket *data); //? 0x21
|
||||
void MakeVoiceOn(WorldPacket *data, uint64 guid); //+ 0x22
|
||||
void MakeVoiceOff(WorldPacket *data, uint64 guid); //+ 0x23
|
||||
|
||||
void SendToAll(WorldPacket *data, uint64 p = 0);
|
||||
void SendToAllButOne(WorldPacket *data, uint64 who);
|
||||
void SendToOne(WorldPacket *data, uint64 who);
|
||||
|
||||
bool IsOn(uint64 who) const { return players.find(who) != players.end(); }
|
||||
bool IsBanned(uint64 guid) const { return banned.find(guid) != banned.end(); }
|
||||
|
||||
bool _UpdateStringInDB(const std::string& colName, const std::string& colValue) const;
|
||||
bool _UpdateIntInDB(const std::string& colName, int colValue) const;
|
||||
void _UpdateBanListInDB() const;
|
||||
|
||||
uint8 GetPlayerFlags(uint64 p) const
|
||||
{
|
||||
PlayerList::const_iterator p_itr = players.find(p);
|
||||
if (p_itr == players.end())
|
||||
return 0;
|
||||
|
||||
return p_itr->second.flags;
|
||||
}
|
||||
|
||||
void SetModerator(uint64 p, bool set)
|
||||
{
|
||||
if (players[p].IsModerator() != set)
|
||||
{
|
||||
uint8 oldFlag = GetPlayerFlags(p);
|
||||
players[p].SetModerator(set);
|
||||
|
||||
WorldPacket data;
|
||||
MakeModeChange(&data, p, oldFlag);
|
||||
SendToAll(&data);
|
||||
}
|
||||
}
|
||||
|
||||
void SetMute(uint64 p, bool set)
|
||||
{
|
||||
if (players[p].IsMuted() != set)
|
||||
{
|
||||
uint8 oldFlag = GetPlayerFlags(p);
|
||||
players[p].SetMuted(set);
|
||||
|
||||
WorldPacket data;
|
||||
MakeModeChange(&data, p, oldFlag);
|
||||
SendToAll(&data);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
uint32 m_Team;
|
||||
Channel(const std::string& name, uint32 channel_id, uint32 Team = 0);
|
||||
std::string GetName() const { return m_name; }
|
||||
uint32 GetChannelId() const { return m_channelId; }
|
||||
bool IsConstant() const { return m_channelId != 0; }
|
||||
bool IsAnnounce() const { return m_announce; }
|
||||
bool IsLFG() const { return GetFlags() & CHANNEL_FLAG_LFG; }
|
||||
std::string GetPassword() const { return m_password; }
|
||||
void SetPassword(const std::string& npassword) { m_password = npassword; }
|
||||
void SetAnnounce(bool nannounce) { m_announce = nannounce; }
|
||||
uint32 GetNumPlayers() const { return players.size(); }
|
||||
uint8 GetFlags() const { return m_flags; }
|
||||
bool HasFlag(uint8 flag) { return m_flags & flag; }
|
||||
|
||||
void Join(uint64 p, const char *pass);
|
||||
void Leave(uint64 p, bool send = true);
|
||||
void KickOrBan(uint64 good, const char *badname, bool ban);
|
||||
void Kick(uint64 good, const char *badname) { KickOrBan(good, badname, false); }
|
||||
void Ban(uint64 good, const char *badname) { KickOrBan(good, badname, true); }
|
||||
void UnBan(uint64 good, const char *badname);
|
||||
void Password(uint64 p, const char *pass);
|
||||
void SetMode(uint64 p, const char *p2n, bool mod, bool set);
|
||||
void SetOwner(uint64 p, bool exclaim = true);
|
||||
void SetOwner(uint64 p, const char *newname);
|
||||
void SendWhoOwner(uint64 p);
|
||||
void SetModerator(uint64 p, const char *newname) { SetMode(p, newname, true, true); }
|
||||
void UnsetModerator(uint64 p, const char *newname) { SetMode(p, newname, true, false); }
|
||||
void SetMute(uint64 p, const char *newname) { SetMode(p, newname, false, true); }
|
||||
void UnsetMute(uint64 p, const char *newname) { SetMode(p, newname, false, false); }
|
||||
void List(Player* p);
|
||||
void Announce(uint64 p);
|
||||
void Moderate(uint64 p);
|
||||
void Say(uint64 p, const char *what, uint32 lang);
|
||||
void Invite(uint64 p, const char *newp);
|
||||
void Voice(uint64 guid1, uint64 guid2);
|
||||
void DeVoice(uint64 guid1, uint64 guid2);
|
||||
void JoinNotify(uint64 guid); // invisible notify
|
||||
void LeaveNotify(uint64 guid); // invisible notify
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Policies/SingletonImp.h"
|
||||
|
||||
#include "ObjectMgr.h" // for normalizePlayerName
|
||||
#include "ChannelMgr.h"
|
||||
|
||||
void WorldSession::HandleJoinChannel(WorldPacket& recvPacket)
|
||||
{
|
||||
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
|
||||
|
||||
uint32 channel_id;
|
||||
uint8 unknown1, unknown2;
|
||||
std::string channelname, pass;
|
||||
|
||||
recvPacket >> channel_id >> unknown1 >> unknown2;
|
||||
recvPacket >> channelname;
|
||||
|
||||
if (channelname.empty())
|
||||
return;
|
||||
|
||||
recvPacket >> pass;
|
||||
if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
|
||||
{
|
||||
cMgr->team = _player->GetTeam();
|
||||
if (Channel *chn = cMgr->GetJoinChannel(channelname, channel_id))
|
||||
chn->Join(_player->GetGUID(), pass.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandleLeaveChannel(WorldPacket& recvPacket)
|
||||
{
|
||||
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
|
||||
//recvPacket.hexlike();
|
||||
|
||||
uint32 unk;
|
||||
std::string channelname;
|
||||
recvPacket >> unk; // channel id?
|
||||
recvPacket >> channelname;
|
||||
|
||||
if (channelname.empty())
|
||||
return;
|
||||
|
||||
if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
|
||||
{
|
||||
if (Channel *chn = cMgr->GetChannel(channelname, _player))
|
||||
chn->Leave(_player->GetGUID(), true);
|
||||
cMgr->LeftChannel(channelname);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandleChannelList(WorldPacket& recvPacket)
|
||||
{
|
||||
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
|
||||
//recvPacket.hexlike();
|
||||
std::string channelname;
|
||||
recvPacket >> channelname;
|
||||
|
||||
if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
|
||||
if (Channel *chn = cMgr->GetChannel(channelname, _player))
|
||||
chn->List(_player);
|
||||
}
|
||||
|
||||
void WorldSession::HandleChannelPassword(WorldPacket& recvPacket)
|
||||
{
|
||||
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
|
||||
//recvPacket.hexlike();
|
||||
std::string channelname, pass;
|
||||
recvPacket >> channelname;
|
||||
|
||||
recvPacket >> pass;
|
||||
|
||||
if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
|
||||
if (Channel *chn = cMgr->GetChannel(channelname, _player))
|
||||
chn->Password(_player->GetGUID(), pass.c_str());
|
||||
}
|
||||
|
||||
void WorldSession::HandleChannelSetOwner(WorldPacket& recvPacket)
|
||||
{
|
||||
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
|
||||
//recvPacket.hexlike();
|
||||
std::string channelname, newp;
|
||||
recvPacket >> channelname;
|
||||
|
||||
recvPacket >> newp;
|
||||
|
||||
if (!normalizePlayerName(newp))
|
||||
return;
|
||||
|
||||
if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
|
||||
if (Channel *chn = cMgr->GetChannel(channelname, _player))
|
||||
chn->SetOwner(_player->GetGUID(), newp.c_str());
|
||||
}
|
||||
|
||||
void WorldSession::HandleChannelOwner(WorldPacket& recvPacket)
|
||||
{
|
||||
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
|
||||
//recvPacket.hexlike();
|
||||
std::string channelname;
|
||||
recvPacket >> channelname;
|
||||
if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
|
||||
if (Channel *chn = cMgr->GetChannel(channelname, _player))
|
||||
chn->SendWhoOwner(_player->GetGUID());
|
||||
}
|
||||
|
||||
void WorldSession::HandleChannelModerator(WorldPacket& recvPacket)
|
||||
{
|
||||
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
|
||||
//recvPacket.hexlike();
|
||||
std::string channelname, otp;
|
||||
recvPacket >> channelname;
|
||||
|
||||
recvPacket >> otp;
|
||||
|
||||
if (!normalizePlayerName(otp))
|
||||
return;
|
||||
|
||||
if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
|
||||
if (Channel *chn = cMgr->GetChannel(channelname, _player))
|
||||
chn->SetModerator(_player->GetGUID(), otp.c_str());
|
||||
}
|
||||
|
||||
void WorldSession::HandleChannelUnmoderator(WorldPacket& recvPacket)
|
||||
{
|
||||
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
|
||||
//recvPacket.hexlike();
|
||||
std::string channelname, otp;
|
||||
recvPacket >> channelname;
|
||||
|
||||
recvPacket >> otp;
|
||||
|
||||
if (!normalizePlayerName(otp))
|
||||
return;
|
||||
|
||||
if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
|
||||
if (Channel *chn = cMgr->GetChannel(channelname, _player))
|
||||
chn->UnsetModerator(_player->GetGUID(), otp.c_str());
|
||||
}
|
||||
|
||||
void WorldSession::HandleChannelMute(WorldPacket& recvPacket)
|
||||
{
|
||||
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
|
||||
//recvPacket.hexlike();
|
||||
std::string channelname, otp;
|
||||
recvPacket >> channelname;
|
||||
|
||||
recvPacket >> otp;
|
||||
|
||||
if (!normalizePlayerName(otp))
|
||||
return;
|
||||
|
||||
if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
|
||||
if (Channel *chn = cMgr->GetChannel(channelname, _player))
|
||||
chn->SetMute(_player->GetGUID(), otp.c_str());
|
||||
}
|
||||
|
||||
void WorldSession::HandleChannelUnmute(WorldPacket& recvPacket)
|
||||
{
|
||||
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
|
||||
//recvPacket.hexlike();
|
||||
|
||||
std::string channelname, otp;
|
||||
recvPacket >> channelname;
|
||||
|
||||
recvPacket >> otp;
|
||||
|
||||
if (!normalizePlayerName(otp))
|
||||
return;
|
||||
|
||||
if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
|
||||
if (Channel *chn = cMgr->GetChannel(channelname, _player))
|
||||
chn->UnsetMute(_player->GetGUID(), otp.c_str());
|
||||
}
|
||||
|
||||
void WorldSession::HandleChannelInvite(WorldPacket& recvPacket)
|
||||
{
|
||||
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
|
||||
//recvPacket.hexlike();
|
||||
std::string channelname, otp;
|
||||
recvPacket >> channelname;
|
||||
|
||||
recvPacket >> otp;
|
||||
|
||||
if (!normalizePlayerName(otp))
|
||||
return;
|
||||
|
||||
if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
|
||||
if (Channel *chn = cMgr->GetChannel(channelname, _player))
|
||||
chn->Invite(_player->GetGUID(), otp.c_str());
|
||||
}
|
||||
|
||||
void WorldSession::HandleChannelKick(WorldPacket& recvPacket)
|
||||
{
|
||||
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
|
||||
//recvPacket.hexlike();
|
||||
std::string channelname, otp;
|
||||
recvPacket >> channelname;
|
||||
|
||||
recvPacket >> otp;
|
||||
if (!normalizePlayerName(otp))
|
||||
return;
|
||||
|
||||
if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
|
||||
if (Channel *chn = cMgr->GetChannel(channelname, _player))
|
||||
chn->Kick(_player->GetGUID(), otp.c_str());
|
||||
}
|
||||
|
||||
void WorldSession::HandleChannelBan(WorldPacket& recvPacket)
|
||||
{
|
||||
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
|
||||
//recvPacket.hexlike();
|
||||
std::string channelname, otp;
|
||||
recvPacket >> channelname;
|
||||
|
||||
recvPacket >> otp;
|
||||
|
||||
if (!normalizePlayerName(otp))
|
||||
return;
|
||||
|
||||
if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
|
||||
if (Channel *chn = cMgr->GetChannel(channelname, _player))
|
||||
chn->Ban(_player->GetGUID(), otp.c_str());
|
||||
}
|
||||
|
||||
void WorldSession::HandleChannelUnban(WorldPacket& recvPacket)
|
||||
{
|
||||
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
|
||||
//recvPacket.hexlike();
|
||||
|
||||
std::string channelname, otp;
|
||||
recvPacket >> channelname;
|
||||
|
||||
recvPacket >> otp;
|
||||
|
||||
if (!normalizePlayerName(otp))
|
||||
return;
|
||||
|
||||
if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
|
||||
if (Channel *chn = cMgr->GetChannel(channelname, _player))
|
||||
chn->UnBan(_player->GetGUID(), otp.c_str());
|
||||
}
|
||||
|
||||
void WorldSession::HandleChannelAnnouncements(WorldPacket& recvPacket)
|
||||
{
|
||||
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
|
||||
//recvPacket.hexlike();
|
||||
std::string channelname;
|
||||
recvPacket >> channelname;
|
||||
if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
|
||||
if (Channel *chn = cMgr->GetChannel(channelname, _player))
|
||||
chn->Announce(_player->GetGUID());
|
||||
}
|
||||
|
||||
void WorldSession::HandleChannelModerate(WorldPacket& recvPacket)
|
||||
{
|
||||
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
|
||||
//recvPacket.hexlike();
|
||||
std::string channelname;
|
||||
recvPacket >> channelname;
|
||||
if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
|
||||
if (Channel *chn = cMgr->GetChannel(channelname, _player))
|
||||
chn->Moderate(_player->GetGUID());
|
||||
}
|
||||
|
||||
void WorldSession::HandleChannelDisplayListQuery(WorldPacket &recvPacket)
|
||||
{
|
||||
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
|
||||
//recvPacket.hexlike();
|
||||
std::string channelname;
|
||||
recvPacket >> channelname;
|
||||
if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
|
||||
if (Channel *chn = cMgr->GetChannel(channelname, _player))
|
||||
chn->List(_player);
|
||||
}
|
||||
|
||||
void WorldSession::HandleGetChannelMemberCount(WorldPacket &recvPacket)
|
||||
{
|
||||
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
|
||||
//recvPacket.hexlike();
|
||||
std::string channelname;
|
||||
recvPacket >> channelname;
|
||||
if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
|
||||
{
|
||||
if (Channel *chn = cMgr->GetChannel(channelname, _player))
|
||||
{
|
||||
WorldPacket data(SMSG_CHANNEL_MEMBER_COUNT, chn->GetName().size()+1+1+4);
|
||||
data << chn->GetName();
|
||||
data << uint8(chn->GetFlags());
|
||||
data << uint32(chn->GetNumPlayers());
|
||||
SendPacket(&data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandleSetChannelWatch(WorldPacket &recvPacket)
|
||||
{
|
||||
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
|
||||
//recvPacket.hexlike();
|
||||
std::string channelname;
|
||||
recvPacket >> channelname;
|
||||
/*if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
|
||||
if (Channel *chn = cMgr->GetChannel(channelname, _player))
|
||||
chn->JoinNotify(_player->GetGUID());*/
|
||||
}
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "ChannelMgr.h"
|
||||
#include "Policies/SingletonImp.h"
|
||||
#include "World.h"
|
||||
|
||||
INSTANTIATE_SINGLETON_1(AllianceChannelMgr);
|
||||
INSTANTIATE_SINGLETON_1(HordeChannelMgr);
|
||||
|
||||
ChannelMgr* channelMgr(uint32 team)
|
||||
{
|
||||
if (sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL))
|
||||
return &Trinity::Singleton<AllianceChannelMgr>::Instance(); // cross-faction
|
||||
|
||||
if (team == ALLIANCE)
|
||||
return &Trinity::Singleton<AllianceChannelMgr>::Instance();
|
||||
if (team == HORDE)
|
||||
return &Trinity::Singleton<HordeChannelMgr>::Instance();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ChannelMgr::~ChannelMgr()
|
||||
{
|
||||
for (ChannelMap::iterator itr = channels.begin(); itr != channels.end(); ++itr)
|
||||
delete itr->second;
|
||||
|
||||
channels.clear();
|
||||
}
|
||||
|
||||
Channel *ChannelMgr::GetJoinChannel(std::string name, uint32 channel_id)
|
||||
{
|
||||
std::wstring wname;
|
||||
Utf8toWStr(name,wname);
|
||||
wstrToLower(wname);
|
||||
|
||||
if (channels.find(wname) == channels.end())
|
||||
{
|
||||
Channel *nchan = new Channel(name,channel_id, team);
|
||||
channels[wname] = nchan;
|
||||
return nchan;
|
||||
}
|
||||
|
||||
return channels[wname];
|
||||
}
|
||||
|
||||
Channel *ChannelMgr::GetChannel(std::string name, Player *p, bool pkt)
|
||||
{
|
||||
std::wstring wname;
|
||||
Utf8toWStr(name,wname);
|
||||
wstrToLower(wname);
|
||||
|
||||
ChannelMap::const_iterator i = channels.find(wname);
|
||||
|
||||
if (i == channels.end())
|
||||
{
|
||||
if (pkt)
|
||||
{
|
||||
WorldPacket data;
|
||||
MakeNotOnPacket(&data,name);
|
||||
p->GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
return i->second;
|
||||
}
|
||||
|
||||
void ChannelMgr::LeftChannel(std::string name)
|
||||
{
|
||||
std::wstring wname;
|
||||
Utf8toWStr(name,wname);
|
||||
wstrToLower(wname);
|
||||
|
||||
ChannelMap::const_iterator i = channels.find(wname);
|
||||
|
||||
if (i == channels.end())
|
||||
return;
|
||||
|
||||
Channel* channel = i->second;
|
||||
|
||||
if (channel->GetNumPlayers() == 0 && !channel->IsConstant())
|
||||
{
|
||||
channels.erase(wname);
|
||||
delete channel;
|
||||
}
|
||||
}
|
||||
|
||||
void ChannelMgr::MakeNotOnPacket(WorldPacket *data, std::string name)
|
||||
{
|
||||
data->Initialize(SMSG_CHANNEL_NOTIFY, (1+10)); // we guess size
|
||||
(*data) << (uint8)0x05 << name;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __TRINITY_CHANNELMGR_H
|
||||
#define __TRINITY_CHANNELMGR_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "Channel.h"
|
||||
#include "Policies/Singleton.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "Policies/Singleton.h"
|
||||
|
||||
#include "Channel.h"
|
||||
#include "World.h"
|
||||
|
||||
class ChannelMgr
|
||||
{
|
||||
public:
|
||||
uint32 team;
|
||||
typedef std::map<std::wstring,Channel*> ChannelMap;
|
||||
ChannelMgr() {team = 0;}
|
||||
~ChannelMgr();
|
||||
|
||||
Channel *GetJoinChannel(std::string name, uint32 channel_id);
|
||||
Channel *GetChannel(std::string name, Player *p, bool pkt = true);
|
||||
void LeftChannel(std::string name);
|
||||
private:
|
||||
ChannelMap channels;
|
||||
void MakeNotOnPacket(WorldPacket *data, std::string name);
|
||||
};
|
||||
|
||||
class AllianceChannelMgr : public ChannelMgr {};
|
||||
class HordeChannelMgr : public ChannelMgr {};
|
||||
|
||||
ChannelMgr* channelMgr(uint32 team);
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,654 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef TRINITYCORE_CHAT_H
|
||||
#define TRINITYCORE_CHAT_H
|
||||
|
||||
#include "SharedDefines.h"
|
||||
|
||||
class ChatHandler;
|
||||
class WorldSession;
|
||||
class Creature;
|
||||
class Player;
|
||||
class Unit;
|
||||
struct GameTele;
|
||||
|
||||
class ChatCommand
|
||||
{
|
||||
public:
|
||||
const char * Name;
|
||||
uint32 SecurityLevel; // function pointer required correct align (use uint32)
|
||||
bool AllowConsole;
|
||||
bool (ChatHandler::*Handler)(const char* args);
|
||||
std::string Help;
|
||||
ChatCommand * ChildCommands;
|
||||
};
|
||||
|
||||
class ChatHandler
|
||||
{
|
||||
public:
|
||||
explicit ChatHandler(WorldSession* session) : m_session(session) {}
|
||||
explicit ChatHandler(Player* player) : m_session(player->GetSession()) {}
|
||||
~ChatHandler() {}
|
||||
|
||||
static void FillMessageData(WorldPacket *data, WorldSession* session, uint8 type, uint32 language, const char *channelName, uint64 target_guid, const char *message, Unit *speaker);
|
||||
|
||||
void FillMessageData(WorldPacket *data, uint8 type, uint32 language, uint64 target_guid, const char* message)
|
||||
{
|
||||
FillMessageData(data, m_session, type, language, NULL, target_guid, message, NULL);
|
||||
}
|
||||
|
||||
void FillSystemMessageData(WorldPacket *data, const char* message)
|
||||
{
|
||||
FillMessageData(data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, 0, message);
|
||||
}
|
||||
|
||||
static char* LineFromMessage(char*& pos) { char* start = strtok(pos,"\n"); pos = NULL; return start; }
|
||||
|
||||
// function with different implementation for chat/console
|
||||
virtual const char *GetTrinityString(int32 entry) const;
|
||||
virtual void SendSysMessage(const char *str);
|
||||
|
||||
void SendSysMessage(int32 entry);
|
||||
void PSendSysMessage(const char *format, ...) ATTR_PRINTF(2,3);
|
||||
void PSendSysMessage(int32 entry, ...);
|
||||
std::string PGetParseString(int32 entry, ...);
|
||||
|
||||
int ParseCommands(const char* text);
|
||||
|
||||
static ChatCommand* getCommandTable();
|
||||
|
||||
bool isValidChatMessage(const char* msg);
|
||||
void SendGlobalSysMessage(const char *str);
|
||||
protected:
|
||||
explicit ChatHandler() : m_session(NULL) {} // for CLI subclass
|
||||
|
||||
bool hasStringAbbr(const char* name, const char* part);
|
||||
|
||||
// function with different implementation for chat/console
|
||||
virtual bool isAvailable(ChatCommand const& cmd) const;
|
||||
virtual std::string GetNameLink() const { return GetNameLink(m_session->GetPlayer()); }
|
||||
virtual bool needReportToTarget(Player* chr) const;
|
||||
virtual LocaleConstant GetSessionDbcLocale() const;
|
||||
virtual int GetSessionDbLocaleIndex() const;
|
||||
|
||||
bool HasLowerSecurity(Player* target, uint64 guid, bool strong = false);
|
||||
bool HasLowerSecurityAccount(WorldSession* target, uint32 account, bool strong = false);
|
||||
|
||||
void SendGlobalGMSysMessage(const char *str);
|
||||
|
||||
static bool SetDataForCommandInTable(ChatCommand *table, const char* text, uint32 security, std::string const& help, std::string const& fullcommand);
|
||||
bool ExecuteCommandInTable(ChatCommand *table, const char* text, const std::string& fullcommand);
|
||||
bool ShowHelpForCommand(ChatCommand *table, const char* cmd);
|
||||
bool ShowHelpForSubCommands(ChatCommand *table, char const* cmd, char const* subcmd);
|
||||
|
||||
bool HandleAccountCommand(const char* args);
|
||||
bool HandleAccountAddonCommand(const char* args);
|
||||
bool HandleAccountCreateCommand(const char* args);
|
||||
bool HandleAccountDeleteCommand(const char* args);
|
||||
bool HandleAccountLockCommand(const char* args);
|
||||
bool HandleAccountOnlineListCommand(const char* args);
|
||||
bool HandleAccountPasswordCommand(const char* args);
|
||||
bool HandleAccountSetAddonCommand(const char* args);
|
||||
bool HandleAccountSetGmLevelCommand(const char* args);
|
||||
bool HandleAccountSetPasswordCommand(const char* args);
|
||||
|
||||
bool HandleAHBotOptionsCommand(const char * args);
|
||||
bool HandleNameAnnounceCommand(const char* args);
|
||||
bool HandleGMNameAnnounceCommand(const char* args);
|
||||
bool HandleGMAnnounceCommand(const char* args);
|
||||
bool HandleGMNotifyCommand(const char* args);
|
||||
|
||||
bool HandleBanAccountCommand(const char* args);
|
||||
bool HandleBanCharacterCommand(const char* args);
|
||||
bool HandleBanIPCommand(const char* args);
|
||||
bool HandleBanInfoAccountCommand(const char* args);
|
||||
bool HandleBanInfoCharacterCommand(const char* args);
|
||||
bool HandleBanInfoIPCommand(const char* args);
|
||||
bool HandleBanListAccountCommand(const char* args);
|
||||
bool HandleBanListCharacterCommand(const char* args);
|
||||
bool HandleBanListIPCommand(const char* args);
|
||||
|
||||
bool HandleCastCommand(const char *args);
|
||||
bool HandleCastBackCommand(const char *args);
|
||||
bool HandleCastDistCommand(const char *args);
|
||||
bool HandleCastSelfCommand(const char *args);
|
||||
bool HandleCastTargetCommand(const char *args);
|
||||
|
||||
bool HandleCharacterCustomizeCommand(const char * args);
|
||||
bool HandleCharacterDeleteCommand(const char* args);
|
||||
bool HandleCharacterLevelCommand(const char* args);
|
||||
bool HandleCharacterRenameCommand(const char * args);
|
||||
bool HandleCharacterReputationCommand(const char* args);
|
||||
bool HandleCharacterTitlesCommand(const char* args);
|
||||
|
||||
bool HandleChannelSetPublic(const char *args);
|
||||
|
||||
bool HandleDebugAnimCommand(const char* args);
|
||||
bool HandleDebugArenaCommand(const char * args);
|
||||
bool HandleDebugBattlegroundCommand(const char * args);
|
||||
bool HandleDebugGetItemStateCommand(const char * args);
|
||||
bool HandleDebugGetLootRecipientCommand(const char * args);
|
||||
bool HandleDebugGetValueCommand(const char* args);
|
||||
bool HandleDebugGetItemValueCommand(const char* args);
|
||||
bool HandleDebugMod32ValueCommand(const char* args);
|
||||
bool HandleDebugSetAuraStateCommand(const char * args);
|
||||
bool HandleDebugSetItemValueCommand(const char * args);
|
||||
bool HandleDebugItemExpireCommand(const char * args);
|
||||
bool HandleDebugSetVehicleId(const char * args);
|
||||
bool HandleDebugEnterVehicle(const char * args);
|
||||
bool HandleDebugSetValueCommand(const char* args);
|
||||
bool HandleDebugSpawnVehicle(const char * args);
|
||||
bool HandleDebugSpellCheckCommand(const char* args);
|
||||
bool HandleDebugUpdateCommand(const char* args);
|
||||
bool HandleDebugUpdateWorldStateCommand(const char* args);
|
||||
|
||||
bool HandleDebugSet32Bit(const char* args);
|
||||
bool HandleDebugThreatList(const char * args);
|
||||
bool HandleDebugHostileRefList(const char * args);
|
||||
bool HandlePossessCommand(const char* args);
|
||||
bool HandleUnPossessCommand(const char* args);
|
||||
bool HandleBindSightCommand(const char* args);
|
||||
bool HandleUnbindSightCommand(const char* args);
|
||||
|
||||
bool HandleDebugPlayCinematicCommand(const char* args);
|
||||
bool HandleDebugPlayMovieCommand(const char* args);
|
||||
bool HandleDebugPlaySoundCommand(const char* args);
|
||||
|
||||
bool HandleDebugSendBuyErrorCommand(const char* args);
|
||||
bool HandleDebugSendChannelNotifyCommand(const char* args);
|
||||
bool HandleDebugSendChatMsgCommand(const char* args);
|
||||
bool HandleDebugSendEquipErrorCommand(const char* args);
|
||||
bool HandleDebugSendLargePacketCommand(const char * args);
|
||||
bool HandleDebugSendOpcodeCommand(const char* args);
|
||||
bool HandleDebugSendPoiCommand(const char* args);
|
||||
bool HandleDebugSendQuestPartyMsgCommand(const char* args);
|
||||
bool HandleDebugSendQuestInvalidMsgCommand(const char* args);
|
||||
bool HandleDebugSendSellErrorCommand(const char* args);
|
||||
bool HandleDebugSendSetPhaseShiftCommand(const char * args);
|
||||
bool HandleDebugSendSpellFailCommand(const char* args);
|
||||
|
||||
bool HandleEventActiveListCommand(const char* args);
|
||||
bool HandleEventStartCommand(const char* args);
|
||||
bool HandleEventStopCommand(const char* args);
|
||||
bool HandleEventInfoCommand(const char* args);
|
||||
|
||||
bool HandleGameObjectAddCommand(const char* args);
|
||||
bool HandleGameObjectDeleteCommand(const char* args);
|
||||
bool HandleGOInfoCommand(const char* args);
|
||||
bool HandleGameObjectMoveCommand(const char* args);
|
||||
bool HandleGameObjectNearCommand(const char* args);
|
||||
bool HandleGameObjectPhaseCommand(const char* args);
|
||||
bool HandleGameObjectStateCommand(const char* args);
|
||||
bool HandleGameObjectTargetCommand(const char* args);
|
||||
bool HandleGameObjectTurnCommand(const char* args);
|
||||
|
||||
bool HandleGMCommand(const char* args);
|
||||
bool HandleGMChatCommand(const char* args);
|
||||
bool HandleGMFlyCommand(const char* args);
|
||||
bool HandleGMListFullCommand(const char* args);
|
||||
bool HandleGMListIngameCommand(const char* args);
|
||||
bool HandleGMVisibleCommand(const char* args);
|
||||
|
||||
bool HandleGoCommand(const char* args);
|
||||
bool HandleGoCreatureCommand(const char* args);
|
||||
bool HandleGoGraveyardCommand(const char* args);
|
||||
bool HandleGoGridCommand(const char* args);
|
||||
bool HandleGoObjectCommand(const char* args);
|
||||
bool HandleGoTaxinodeCommand(const char* args);
|
||||
bool HandleGoTriggerCommand(const char* args);
|
||||
bool HandleGoXYCommand(const char* args);
|
||||
bool HandleGoXYZCommand(const char* args);
|
||||
bool HandleGoZoneXYCommand(const char* args);
|
||||
|
||||
bool HandleGoTicketCommand(const char* args);
|
||||
|
||||
bool HandleGuildCreateCommand(const char* args);
|
||||
bool HandleGuildInviteCommand(const char* args);
|
||||
bool HandleGuildUninviteCommand(const char* args);
|
||||
bool HandleGuildRankCommand(const char* args);
|
||||
bool HandleGuildDeleteCommand(const char* args);
|
||||
|
||||
bool HandleHonorAddCommand(const char* args);
|
||||
bool HandleHonorAddKillCommand(const char* args);
|
||||
bool HandleHonorUpdateCommand(const char* args);
|
||||
|
||||
bool HandleInstanceListBindsCommand(const char* args);
|
||||
bool HandleInstanceUnbindCommand(const char* args);
|
||||
bool HandleInstanceStatsCommand(const char* args);
|
||||
bool HandleInstanceSaveDataCommand(const char * args);
|
||||
bool HandleInstanceOpenCommand(const char * args);
|
||||
bool HandleInstanceCloseCommand(const char * args);
|
||||
bool HandleInstanceOpenCloseCommand(const char * args, bool open);
|
||||
|
||||
bool HandleLearnCommand(const char* args);
|
||||
bool HandleLearnAllCommand(const char* args);
|
||||
bool HandleLearnAllGMCommand(const char* args);
|
||||
bool HandleLearnAllCraftsCommand(const char* args);
|
||||
bool HandleLearnAllRecipesCommand(const char* args);
|
||||
bool HandleLearnAllDefaultCommand(const char* args);
|
||||
bool HandleLearnAllLangCommand(const char* args);
|
||||
bool HandleLearnAllMyClassCommand(const char* args);
|
||||
bool HandleLearnAllMyPetTalentsCommand(const char* args);
|
||||
bool HandleLearnAllMySpellsCommand(const char* args);
|
||||
bool HandleLearnAllMyTalentsCommand(const char* args);
|
||||
|
||||
bool HandleListAurasCommand(const char * args);
|
||||
bool HandleListCreatureCommand(const char* args);
|
||||
bool HandleListItemCommand(const char* args);
|
||||
bool HandleListObjectCommand(const char* args);
|
||||
|
||||
bool HandleLookupAreaCommand(const char* args);
|
||||
bool HandleLookupCreatureCommand(const char* args);
|
||||
bool HandleLookupEventCommand(const char* args);
|
||||
bool HandleLookupFactionCommand(const char * args);
|
||||
bool HandleLookupItemCommand(const char * args);
|
||||
bool HandleLookupItemSetCommand(const char * args);
|
||||
bool HandleLookupObjectCommand(const char* args);
|
||||
bool HandleLookupPlayerIpCommand(const char* args);
|
||||
bool HandleLookupPlayerAccountCommand(const char* args);
|
||||
bool HandleLookupPlayerEmailCommand(const char* args);
|
||||
bool HandleLookupQuestCommand(const char* args);
|
||||
bool HandleLookupSkillCommand(const char* args);
|
||||
bool HandleLookupSpellCommand(const char* args);
|
||||
bool HandleLookupTaxiNodeCommand(const char * args);
|
||||
bool HandleLookupTeleCommand(const char * args);
|
||||
bool HandleLookupMapCommand(const char* args);
|
||||
bool HandleLookupTitleCommand(const char * args);
|
||||
|
||||
bool HandleModifyHPCommand(const char* args);
|
||||
bool HandleModifyManaCommand(const char* args);
|
||||
bool HandleModifyRageCommand(const char* args);
|
||||
bool HandleModifyRunicPowerCommand(const char* args);
|
||||
bool HandleModifyEnergyCommand(const char* args);
|
||||
bool HandleModifyMoneyCommand(const char* args);
|
||||
bool HandleModifyASpeedCommand(const char* args);
|
||||
bool HandleModifySpeedCommand(const char* args);
|
||||
bool HandleModifyBWalkCommand(const char* args);
|
||||
bool HandleModifyFlyCommand(const char* args);
|
||||
bool HandleModifySwimCommand(const char* args);
|
||||
bool HandleModifyScaleCommand(const char* args);
|
||||
bool HandleModifyMountCommand(const char* args);
|
||||
bool HandleModifyBitCommand(const char* args);
|
||||
bool HandleModifyFactionCommand(const char* args);
|
||||
bool HandleModifySpellCommand(const char* args);
|
||||
bool HandleModifyTalentCommand (const char* args);
|
||||
bool HandleModifyHonorCommand (const char* args);
|
||||
bool HandleModifyRepCommand(const char* args);
|
||||
bool HandleModifyArenaCommand(const char* args);
|
||||
bool HandleModifyPhaseCommand(const char* args);
|
||||
bool HandleModifyGenderCommand(const char* args);
|
||||
|
||||
//-----------------------Npc Commands-----------------------
|
||||
bool HandleNpcAddCommand(const char* args);
|
||||
bool HandleNpcAddMoveCommand(const char* args);
|
||||
bool HandleNpcAddVendorItemCommand(const char* args);
|
||||
bool HandleNpcAllowMovementCommand(const char* args);
|
||||
bool HandleNpcChangeEntryCommand(const char *args);
|
||||
bool HandleNpcChangeLevelCommand(const char* args);
|
||||
bool HandleNpcDeleteCommand(const char* args);
|
||||
bool HandleNpcDelVendorItemCommand(const char* args);
|
||||
bool HandleNpcFactionIdCommand(const char* args);
|
||||
bool HandleNpcFlagCommand(const char* args);
|
||||
bool HandleNpcFollowCommand(const char* args);
|
||||
bool HandleNpcInfoCommand(const char* args);
|
||||
bool HandleNpcMoveCommand(const char* args);
|
||||
bool HandleNpcPlayEmoteCommand(const char* args);
|
||||
bool HandleNpcSayCommand(const char* args);
|
||||
bool HandleNpcSetDeathStateCommand(const char* args);
|
||||
bool HandleNpcSetModelCommand(const char* args);
|
||||
bool HandleNpcSetMoveTypeCommand(const char* args);
|
||||
bool HandleNpcSetPhaseCommand(const char* args);
|
||||
bool HandleNpcSpawnDistCommand(const char* args);
|
||||
bool HandleNpcSpawnTimeCommand(const char* args);
|
||||
bool HandleNpcTameCommand(const char* args);
|
||||
bool HandleNpcTextEmoteCommand(const char* args);
|
||||
bool HandleNpcUnFollowCommand(const char* args);
|
||||
bool HandleNpcWhisperCommand(const char* args);
|
||||
bool HandleNpcYellCommand(const char* args);
|
||||
bool HandleNpcAddFormationCommand(const char* args);
|
||||
bool HandleNpcSetLinkCommand(const char* args);
|
||||
|
||||
//TODO: NpcCommands that needs to be fixed :
|
||||
bool HandleNpcAddWeaponCommand(const char* args);
|
||||
bool HandleNpcNameCommand(const char* args);
|
||||
bool HandleNpcSubNameCommand(const char* args);
|
||||
//----------------------------------------------------------
|
||||
|
||||
bool HandlePDumpLoadCommand(const char *args);
|
||||
bool HandlePDumpWriteCommand(const char *args);
|
||||
|
||||
bool HandleQuestAdd(const char * args);
|
||||
bool HandleQuestRemove(const char * args);
|
||||
bool HandleQuestComplete(const char * args);
|
||||
|
||||
bool HandleReloadAllCommand(const char* args);
|
||||
bool HandleReloadAllAchievementCommand(const char* args);
|
||||
bool HandleReloadAllAreaCommand(const char* args);
|
||||
bool HandleReloadAllItemCommand(const char* args);
|
||||
bool HandleReloadAllLootCommand(const char* args);
|
||||
bool HandleReloadAllNpcCommand(const char* args);
|
||||
bool HandleReloadAllQuestCommand(const char* args);
|
||||
bool HandleReloadAllScriptsCommand(const char* args);
|
||||
bool HandleReloadAllEventAICommand(const char* args);
|
||||
bool HandleReloadAllSpellCommand(const char* args);
|
||||
bool HandleReloadAllLocalesCommand(const char* args);
|
||||
|
||||
bool HandleReloadConfigCommand(const char* args);
|
||||
|
||||
bool HandleReloadAccessRequirementCommand(const char* args);
|
||||
bool HandleReloadAchievementCriteriaDataCommand(const char* args);
|
||||
bool HandleReloadAchievementRewardCommand(const char* args);
|
||||
bool HandleReloadAreaTriggerTavernCommand(const char* args);
|
||||
bool HandleReloadAreaTriggerTeleportCommand(const char* args);
|
||||
bool HandleReloadAutobroadcastCommand(const char* args);
|
||||
bool HandleReloadEventScriptsCommand(const char* args);
|
||||
bool HandleReloadEventAITextsCommand(const char* args);
|
||||
bool HandleReloadEventAISummonsCommand(const char* args);
|
||||
bool HandleReloadEventAIScriptsCommand(const char* args);
|
||||
bool HandleReloadCommandCommand(const char* args);
|
||||
bool HandleReloadCreatureTemplateCommand(const char* args);
|
||||
bool HandleReloadCreatureQuestRelationsCommand(const char* args);
|
||||
bool HandleReloadCreatureQuestInvRelationsCommand(const char* args);
|
||||
bool HandleReloadCreatureLinkedRespawnCommand(const char* args);
|
||||
bool HandleReloadDbScriptStringCommand(const char* args);
|
||||
bool HandleReloadGameGraveyardZoneCommand(const char* args);
|
||||
bool HandleReloadGameObjectScriptsCommand(const char* args);
|
||||
bool HandleReloadGameTeleCommand(const char* args);
|
||||
bool HandleReloadGossipMenuCommand(const char* args);
|
||||
bool HandleReloadGossipMenuOptionCommand(const char* args);
|
||||
bool HandleReloadGOQuestRelationsCommand(const char* args);
|
||||
bool HandleReloadGOQuestInvRelationsCommand(const char* args);
|
||||
bool HandleReloadItemEnchantementsCommand(const char* args);
|
||||
bool HandleReloadLocalesAchievementRewardCommand(const char* args);
|
||||
bool HandleReloadLocalesCreatureCommand(const char* args);
|
||||
bool HandleReloadLocalesGameobjectCommand(const char* args);
|
||||
bool HandleReloadLocalesItemCommand(const char* args);
|
||||
bool HandleReloadLocalesNpcTextCommand(const char* args);
|
||||
bool HandleReloadLocalesPageTextCommand(const char* args);
|
||||
bool HandleReloadLocalesPointsOfInterestCommand(const char* args);
|
||||
bool HandleReloadLocalesQuestCommand(const char* args);
|
||||
// bool HandleReloadAuctionsCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesCreatureCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesDisenchantCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesFishingCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesGameobjectCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesItemCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesMailCommand(const char* args);
|
||||
bool HandleReloadMailLevelRewardCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesMillingCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesPickpocketingCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesProspectingCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesReferenceCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesSkinningCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesSpellCommand(const char* args);
|
||||
bool HandleReloadTrinityStringCommand(const char* args);
|
||||
bool HandleReloadNpcGossipCommand(const char* args);
|
||||
bool HandleReloadNpcTrainerCommand(const char* args);
|
||||
bool HandleReloadNpcVendorCommand(const char* args);
|
||||
bool HandleReloadPageTextsCommand(const char* args);
|
||||
bool HandleReloadPointsOfInterestCommand(const char* args);
|
||||
bool HandleReloadSpellClickSpellsCommand(const char* args);
|
||||
bool HandleReloadQuestAreaTriggersCommand(const char* args);
|
||||
bool HandleReloadQuestEndScriptsCommand(const char* args);
|
||||
bool HandleReloadQuestStartScriptsCommand(const char* args);
|
||||
bool HandleReloadQuestTemplateCommand(const char* args);
|
||||
bool HandleReloadReservedNameCommand(const char*);
|
||||
bool HandleReloadSkillDiscoveryTemplateCommand(const char* args);
|
||||
bool HandleReloadSkillExtraItemTemplateCommand(const char* args);
|
||||
bool HandleReloadSkillFishingBaseLevelCommand(const char* args);
|
||||
bool HandleReloadSpellRequiredCommand(const char* args);
|
||||
bool HandleReloadSpellAreaCommand(const char* args);
|
||||
bool HandleReloadSpellGroupsCommand(const char* args);
|
||||
bool HandleReloadSpellLearnSpellCommand(const char* args);
|
||||
bool HandleReloadSpellLinkedSpellCommand(const char* args);
|
||||
bool HandleReloadSpellProcEventCommand(const char* args);
|
||||
bool HandleReloadSpellBonusesCommand(const char* args);
|
||||
bool HandleReloadSpellScriptsCommand(const char* args);
|
||||
bool HandleReloadSpellTargetPositionCommand(const char* args);
|
||||
bool HandleReloadSpellThreatsCommand(const char* args);
|
||||
bool HandleReloadSpellPetAurasCommand(const char* args);
|
||||
bool HandleReloadSpellDisabledCommand(const char* args);
|
||||
bool HandleReloadSpellGroupStackRulesCommand(const char* args);
|
||||
bool HandleReloadAuctionsCommand(const char* args);
|
||||
bool HandleReloadWpScriptsCommand(const char* args);
|
||||
bool HandleReloadConditions(const char* args);
|
||||
|
||||
bool HandleResetAchievementsCommand(const char * args);
|
||||
bool HandleResetAllCommand(const char * args);
|
||||
bool HandleResetHonorCommand(const char * args);
|
||||
bool HandleResetLevelCommand(const char * args);
|
||||
bool HandleResetSpellsCommand(const char * args);
|
||||
bool HandleResetStatsCommand(const char * args);
|
||||
bool HandleResetTalentsCommand(const char * args);
|
||||
|
||||
bool HandleSendItemsCommand(const char* args);
|
||||
bool HandleSendMailCommand(const char* args);
|
||||
bool HandleSendMessageCommand(const char * args);
|
||||
bool HandleSendMoneyCommand(const char* args);
|
||||
|
||||
bool HandleServerCorpsesCommand(const char* args);
|
||||
bool HandleServerExitCommand(const char* args);
|
||||
bool HandleServerIdleRestartCommand(const char* args);
|
||||
bool HandleServerIdleShutDownCommand(const char* args);
|
||||
bool HandleServerInfoCommand(const char* args);
|
||||
bool HandleServerMotdCommand(const char* args);
|
||||
bool HandleServerPLimitCommand(const char* args);
|
||||
bool HandleServerRestartCommand(const char* args);
|
||||
bool HandleServerSetLogLevelCommand(const char* args);
|
||||
bool HandleServerSetMotdCommand(const char* args);
|
||||
bool HandleServerShutDownCommand(const char* args);
|
||||
bool HandleServerShutDownCancelCommand(const char* args);
|
||||
bool HandleServerSetClosedCommand(const char* args);
|
||||
|
||||
bool HandleServerSetLogFileLevelCommand(const char* args);
|
||||
bool HandleServerSetDiffTimeCommand(const char* args);
|
||||
|
||||
bool HandleTeleCommand(const char * args);
|
||||
bool HandleTeleAddCommand(const char * args);
|
||||
bool HandleTeleDelCommand(const char * args);
|
||||
bool HandleTeleGroupCommand(const char* args);
|
||||
bool HandleTeleNameCommand(const char* args);
|
||||
|
||||
bool HandleTitlesAddCommand(const char* args);
|
||||
bool HandleTitlesCurrentCommand(const char* args);
|
||||
bool HandleTitlesRemoveCommand(const char* args);
|
||||
bool HandleTitlesSetMaskCommand(const char* args);
|
||||
|
||||
bool HandleUnBanAccountCommand(const char* args);
|
||||
bool HandleUnBanCharacterCommand(const char* args);
|
||||
bool HandleUnBanIPCommand(const char* args);
|
||||
|
||||
bool HandleWpAddCommand(const char* args);
|
||||
bool HandleWpLoadPathCommand(const char* args);
|
||||
bool HandleWpUnLoadPathCommand(const char* args);
|
||||
bool HandleWpModifyCommand(const char* args);
|
||||
bool HandleWpEventCommand(const char* args);
|
||||
bool HandleWpShowCommand(const char* args);
|
||||
bool HandleReloadAllPaths(const char *args);
|
||||
|
||||
bool HandleHelpCommand(const char* args);
|
||||
bool HandleCommandsCommand(const char* args);
|
||||
bool HandleStartCommand(const char* args);
|
||||
bool HandleDismountCommand(const char* args);
|
||||
bool HandleSaveCommand(const char* args);
|
||||
|
||||
bool HandleNamegoCommand(const char* args);
|
||||
bool HandleGonameCommand(const char* args);
|
||||
bool HandleGroupgoCommand(const char* args);
|
||||
bool HandleRecallCommand(const char* args);
|
||||
bool HandleAnnounceCommand(const char* args);
|
||||
bool HandleNotifyCommand(const char* args);
|
||||
bool HandleGPSCommand(const char* args);
|
||||
bool HandleTaxiCheatCommand(const char* args);
|
||||
bool HandleWhispersCommand(const char* args);
|
||||
bool HandleModifyDrunkCommand(const char* args);
|
||||
|
||||
bool HandleGUIDCommand(const char* args);
|
||||
bool HandleItemMoveCommand(const char* args);
|
||||
bool HandleDeMorphCommand(const char* args);
|
||||
bool HandlePInfoCommand(const char* args);
|
||||
bool HandleMuteCommand(const char* args);
|
||||
bool HandleUnmuteCommand(const char* args);
|
||||
bool HandleMovegensCommand(const char* args);
|
||||
bool HandleFreezeCommand(const char *args);
|
||||
bool HandleUnFreezeCommand(const char *args);
|
||||
bool HandleListFreezeCommand(const char* args);
|
||||
|
||||
bool HandleCooldownCommand(const char* args);
|
||||
bool HandleUnLearnCommand(const char* args);
|
||||
bool HandleGetDistanceCommand(const char* args);
|
||||
bool HandleModifyStandStateCommand(const char* args);
|
||||
bool HandleDieCommand(const char* args);
|
||||
bool HandleDamageCommand(const char *args);
|
||||
bool HandleReviveCommand(const char* args);
|
||||
bool HandleModifyMorphCommand(const char* args);
|
||||
bool HandleAuraCommand(const char* args);
|
||||
bool HandleUnAuraCommand(const char* args);
|
||||
bool HandleLinkGraveCommand(const char* args);
|
||||
bool HandleNearGraveCommand(const char* args);
|
||||
bool HandleActivateObjectCommand(const char* args);
|
||||
bool HandleSpawnTransportCommand(const char* args);
|
||||
bool HandleExploreCheatCommand(const char* args);
|
||||
bool HandleHoverCommand(const char* args);
|
||||
bool HandleWaterwalkCommand(const char* args);
|
||||
bool HandleLevelUpCommand(const char* args);
|
||||
bool HandleShowAreaCommand(const char* args);
|
||||
bool HandleHideAreaCommand(const char* args);
|
||||
bool HandleAddItemCommand(const char* args);
|
||||
bool HandleAddItemSetCommand(const char* args);
|
||||
bool HandlePetTpCommand(const char* args);
|
||||
bool HandlePetUnlearnCommand(const char* args);
|
||||
bool HandlePetLearnCommand(const char* args);
|
||||
bool HandleCreatePetCommand(const char* args);
|
||||
|
||||
bool HandleGroupLeaderCommand(const char* args);
|
||||
bool HandleGroupDisbandCommand(const char* args);
|
||||
bool HandleGroupRemoveCommand(const char* args);
|
||||
|
||||
bool HandleBankCommand(const char* args);
|
||||
bool HandleChangeWeather(const char* args);
|
||||
bool HandleKickPlayerCommand(const char * args);
|
||||
|
||||
// GM ticket command handlers
|
||||
bool HandleGMTicketListCommand(const char* args);
|
||||
bool HandleGMTicketListOnlineCommand(const char* args);
|
||||
bool HandleGMTicketListClosedCommand(const char* args);
|
||||
bool HandleGMTicketGetByIdCommand(const char* args);
|
||||
bool HandleGMTicketGetByNameCommand(const char* args);
|
||||
bool HandleGMTicketCloseByIdCommand(const char* args);
|
||||
bool HandleGMTicketAssignToCommand(const char* args);
|
||||
bool HandleGMTicketUnAssignCommand(const char* args);
|
||||
bool HandleGMTicketCommentCommand(const char* args);
|
||||
bool HandleGMTicketDeleteByIdCommand(const char* args);
|
||||
bool HandleGMTicketReloadCommand(const char*);
|
||||
|
||||
bool HandleMaxSkillCommand(const char* args);
|
||||
bool HandleSetSkillCommand(const char* args);
|
||||
bool HandleRespawnCommand(const char* args);
|
||||
bool HandleComeToMeCommand(const char *args);
|
||||
bool HandleCombatStopCommand(const char *args);
|
||||
|
||||
/*bool HandleCharDeleteCommand(const char *args);
|
||||
bool HandleSendMessageCommand(const char * args);*/
|
||||
|
||||
bool HandleFlushArenaPointsCommand(const char *args);
|
||||
bool HandlePlayAllCommand(const char* args);
|
||||
bool HandleRepairitemsCommand(const char* args);
|
||||
|
||||
bool HandleTempGameObjectCommand(const char* args);
|
||||
bool HandleTempAddSpwCommand(const char* args);
|
||||
|
||||
//! Development Commands
|
||||
|
||||
/*bool HandleQuestAdd(const char * args);
|
||||
bool HandleQuestRemove(const char * args);
|
||||
bool HandleQuestComplete(const char * args);*/
|
||||
|
||||
//bool HandleSet32Bit(const char* args);
|
||||
bool HandleSaveAllCommand(const char* args);
|
||||
|
||||
Player* getSelectedPlayer();
|
||||
Creature* getSelectedCreature();
|
||||
Unit* getSelectedUnit();
|
||||
WorldObject* getSelectedObject();
|
||||
|
||||
char* extractKeyFromLink(char* text, char const* linkType, char** something1 = NULL);
|
||||
char* extractKeyFromLink(char* text, char const* const* linkTypes, int* found_idx, char** something1 = NULL);
|
||||
|
||||
// if args have single value then it return in arg2 and arg1 == NULL
|
||||
void extractOptFirstArg(char* args, char** arg1, char** arg2);
|
||||
char* extractQuotedArg(char* args);
|
||||
|
||||
uint32 extractSpellIdFromLink(char* text);
|
||||
uint64 extractGuidFromLink(char* text);
|
||||
GameTele const* extractGameTeleFromLink(char* text);
|
||||
bool GetPlayerGroupAndGUIDByName(const char* cname, Player* &plr, Group* &group, uint64 &guid, bool offline = false);
|
||||
std::string extractPlayerNameFromLink(char* text);
|
||||
// select by arg (name/link) or in-game selection online/offline player
|
||||
bool extractPlayerTarget(char* args, Player** player, uint64* player_guid = NULL, std::string* player_name = NULL);
|
||||
|
||||
std::string playerLink(std::string const& name) const { return m_session ? "|cffffffff|Hplayer:"+name+"|h["+name+"]|h|r" : name; }
|
||||
std::string GetNameLink(Player* chr) const { return playerLink(chr->GetName()); }
|
||||
|
||||
GameObject* GetNearbyGameObject();
|
||||
GameObject* GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid,uint32 entry);
|
||||
|
||||
// Utility methods for commands
|
||||
bool LookupPlayerSearchCommand(QueryResult_AutoPtr result, int32 limit);
|
||||
bool HandleBanListHelper(QueryResult_AutoPtr result);
|
||||
bool HandleBanHelper(BanMode mode,char const* args);
|
||||
bool HandleBanInfoHelper(uint32 accountid, char const* accountname);
|
||||
bool HandleUnBanHelper(BanMode mode,char const* args);
|
||||
void HandleCharacterLevel(Player* player, uint64 player_guid, uint32 oldlevel, uint32 newlevel);
|
||||
void HandleLearnSkillRecipesHelper(Player* player,uint32 skill_id);
|
||||
|
||||
void SetSentErrorMessage(bool val){ sentErrorMessage = val;};
|
||||
private:
|
||||
WorldSession * m_session; // != NULL for chat command call and NULL for CLI command
|
||||
|
||||
// common global flag
|
||||
static bool load_command_table;
|
||||
bool sentErrorMessage;
|
||||
};
|
||||
|
||||
class CliHandler : public ChatHandler
|
||||
{
|
||||
public:
|
||||
typedef void Print(char const*);
|
||||
explicit CliHandler(Print* zprint) : m_print(zprint) {}
|
||||
|
||||
// overwrite functions
|
||||
const char *GetTrinityString(int32 entry) const;
|
||||
bool isAvailable(ChatCommand const& cmd) const;
|
||||
void SendSysMessage(const char *str);
|
||||
std::string GetNameLink() const;
|
||||
bool needReportToTarget(Player* chr) const;
|
||||
LocaleConstant GetSessionDbcLocale() const;
|
||||
int GetSessionDbLocaleIndex() const;
|
||||
|
||||
private:
|
||||
Print* m_print;
|
||||
};
|
||||
|
||||
char const *fmtstring(char const *format, ...);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,756 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Common.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "World.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
|
||||
#include "CellImpl.h"
|
||||
#include "Chat.h"
|
||||
#include "ChannelMgr.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
#include "Group.h"
|
||||
#include "Guild.h"
|
||||
#include "Language.h"
|
||||
#include "Log.h"
|
||||
#include "Opcodes.h"
|
||||
#include "Player.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "Util.h"
|
||||
|
||||
bool WorldSession::processChatmessageFurtherAfterSecurityChecks(std::string& msg, uint32 lang)
|
||||
{
|
||||
if (lang != LANG_ADDON)
|
||||
{
|
||||
// strip invisible characters for non-addon messages
|
||||
if (sWorld.getConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING))
|
||||
stripLineInvisibleChars(msg);
|
||||
|
||||
if (sWorld.getConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY) && GetSecurity() < SEC_MODERATOR
|
||||
&& !ChatHandler(this).isValidChatMessage(msg.c_str()))
|
||||
{
|
||||
sLog.outError("Player %s (GUID: %u) sent a chatmessage with an invalid link: %s", GetPlayer()->GetName(),
|
||||
GetPlayer()->GetGUIDLow(), msg.c_str());
|
||||
if (sWorld.getConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_KICK))
|
||||
KickPlayer();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WorldSession::HandleMessagechatOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
uint32 type;
|
||||
uint32 lang;
|
||||
|
||||
recv_data >> type;
|
||||
recv_data >> lang;
|
||||
|
||||
if (type >= MAX_CHAT_MSG_TYPE)
|
||||
{
|
||||
sLog.outError("CHAT: Wrong message type received: %u", type);
|
||||
return;
|
||||
}
|
||||
|
||||
//sLog.outDebug("CHAT: packet received. type %u, lang %u", type, lang);
|
||||
|
||||
// prevent talking at unknown language (cheating)
|
||||
LanguageDesc const* langDesc = GetLanguageDescByID(lang);
|
||||
if (!langDesc)
|
||||
{
|
||||
SendNotification(LANG_UNKNOWN_LANGUAGE);
|
||||
return;
|
||||
}
|
||||
if (langDesc->skill_id != 0 && !_player->HasSkill(langDesc->skill_id))
|
||||
{
|
||||
// also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language)
|
||||
Unit::AuraEffectList const& langAuras = _player->GetAuraEffectsByType(SPELL_AURA_COMPREHEND_LANGUAGE);
|
||||
bool foundAura = false;
|
||||
for (Unit::AuraEffectList::const_iterator i = langAuras.begin(); i != langAuras.end(); ++i)
|
||||
{
|
||||
if ((*i)->GetMiscValue() == int32(lang))
|
||||
{
|
||||
foundAura = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundAura)
|
||||
{
|
||||
SendNotification(LANG_NOT_LEARNED_LANGUAGE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (lang == LANG_ADDON)
|
||||
{
|
||||
if (sWorld.getConfig(CONFIG_CHATLOG_ADDON))
|
||||
{
|
||||
std::string msg = "";
|
||||
recv_data >> msg;
|
||||
|
||||
if (msg.empty())
|
||||
{
|
||||
sLog.outDebug("Player %s send empty addon msg", GetPlayer()->GetName());
|
||||
return;
|
||||
}
|
||||
|
||||
sLog.outChat("[ADDON] Player %s sends: %s",
|
||||
GetPlayer()->GetName(), msg.c_str());
|
||||
}
|
||||
|
||||
// Disabled addon channel?
|
||||
if (!sWorld.getConfig(CONFIG_ADDON_CHANNEL))
|
||||
return;
|
||||
}
|
||||
// LANG_ADDON should not be changed nor be affected by flood control
|
||||
else
|
||||
{
|
||||
// send in universal language if player in .gmon mode (ignore spell effects)
|
||||
if (_player->isGameMaster())
|
||||
lang = LANG_UNIVERSAL;
|
||||
else
|
||||
{
|
||||
// send in universal language in two side iteration allowed mode
|
||||
if (sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT))
|
||||
lang = LANG_UNIVERSAL;
|
||||
else
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case CHAT_MSG_PARTY:
|
||||
case CHAT_MSG_RAID:
|
||||
case CHAT_MSG_RAID_LEADER:
|
||||
case CHAT_MSG_RAID_WARNING:
|
||||
// allow two side chat at group channel if two side group allowed
|
||||
if (sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP))
|
||||
lang = LANG_UNIVERSAL;
|
||||
break;
|
||||
case CHAT_MSG_GUILD:
|
||||
case CHAT_MSG_OFFICER:
|
||||
// allow two side chat at guild channel if two side guild allowed
|
||||
if (sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD))
|
||||
lang = LANG_UNIVERSAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// but overwrite it by SPELL_AURA_MOD_LANGUAGE auras (only single case used)
|
||||
Unit::AuraEffectList const& ModLangAuras = _player->GetAuraEffectsByType(SPELL_AURA_MOD_LANGUAGE);
|
||||
if (!ModLangAuras.empty())
|
||||
lang = ModLangAuras.front()->GetMiscValue();
|
||||
}
|
||||
|
||||
if (!_player->CanSpeak())
|
||||
{
|
||||
std::string timeStr = secsToTimeString(m_muteTime - time(NULL));
|
||||
SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING),timeStr.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (type != CHAT_MSG_AFK && type != CHAT_MSG_DND)
|
||||
GetPlayer()->UpdateSpeakTime();
|
||||
}
|
||||
|
||||
if (GetPlayer()->HasAura(1852) && type != CHAT_MSG_WHISPER)
|
||||
{
|
||||
std::string msg="";
|
||||
recv_data >> msg;
|
||||
|
||||
SendNotification(GetTrinityString(LANG_GM_SILENCE), GetPlayer()->GetName());
|
||||
return;
|
||||
}
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case CHAT_MSG_SAY:
|
||||
case CHAT_MSG_EMOTE:
|
||||
case CHAT_MSG_YELL:
|
||||
{
|
||||
std::string msg;
|
||||
recv_data >> msg;
|
||||
|
||||
if (msg.empty())
|
||||
break;
|
||||
|
||||
if (ChatHandler(this).ParseCommands(msg.c_str()) > 0)
|
||||
break;
|
||||
|
||||
if (_player->getLevel() < sWorld.getConfig(CONFIG_CHAT_SAY_LEVEL_REQ))
|
||||
{
|
||||
SendNotification(GetTrinityString(LANG_SAY_REQ), sWorld.getConfig(CONFIG_CHAT_SAY_LEVEL_REQ));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
|
||||
return;
|
||||
|
||||
if (msg.empty())
|
||||
break;
|
||||
|
||||
if (type == CHAT_MSG_SAY)
|
||||
GetPlayer()->Say(msg, lang);
|
||||
else if (type == CHAT_MSG_EMOTE)
|
||||
GetPlayer()->TextEmote(msg);
|
||||
else if (type == CHAT_MSG_YELL)
|
||||
GetPlayer()->Yell(msg, lang);
|
||||
} break;
|
||||
|
||||
case CHAT_MSG_WHISPER:
|
||||
{
|
||||
std::string to, msg;
|
||||
recv_data >> to;
|
||||
recv_data >> msg;
|
||||
|
||||
if (_player->getLevel() < sWorld.getConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ))
|
||||
{
|
||||
SendNotification(GetTrinityString(LANG_WHISPER_REQ), sWorld.getConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
|
||||
return;
|
||||
|
||||
if (msg.empty())
|
||||
break;
|
||||
|
||||
if (!normalizePlayerName(to))
|
||||
{
|
||||
SendPlayerNotFoundNotice(to);
|
||||
break;
|
||||
}
|
||||
|
||||
Player *player = objmgr.GetPlayer(to.c_str());
|
||||
uint32 tSecurity = GetSecurity();
|
||||
uint32 pSecurity = player ? player->GetSession()->GetSecurity() : SEC_PLAYER;
|
||||
if (!player || (tSecurity == SEC_PLAYER && pSecurity > SEC_PLAYER && !player->isAcceptWhispers()))
|
||||
{
|
||||
SendPlayerNotFoundNotice(to);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT) && tSecurity == SEC_PLAYER && pSecurity == SEC_PLAYER)
|
||||
{
|
||||
uint32 sidea = GetPlayer()->GetTeam();
|
||||
uint32 sideb = player->GetTeam();
|
||||
if (sidea != sideb)
|
||||
{
|
||||
SendWrongFactionNotice();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (GetPlayer()->HasAura(1852) && !player->isGameMaster())
|
||||
{
|
||||
SendNotification(GetTrinityString(LANG_GM_SILENCE), GetPlayer()->GetName());
|
||||
return;
|
||||
}
|
||||
|
||||
GetPlayer()->Whisper(msg, lang, player->GetGUID());
|
||||
} break;
|
||||
|
||||
case CHAT_MSG_PARTY:
|
||||
case CHAT_MSG_PARTY_LEADER:
|
||||
{
|
||||
std::string msg;
|
||||
recv_data >> msg;
|
||||
|
||||
if (msg.empty())
|
||||
break;
|
||||
|
||||
if (ChatHandler(this).ParseCommands(msg.c_str()) > 0)
|
||||
break;
|
||||
|
||||
if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
|
||||
return;
|
||||
|
||||
if (msg.empty())
|
||||
break;
|
||||
|
||||
// if player is in battleground, he cannot say to battleground members by /p
|
||||
Group *group = GetPlayer()->GetOriginalGroup();
|
||||
if (!group)
|
||||
{
|
||||
group = _player->GetGroup();
|
||||
if (!group || group->isBGGroup())
|
||||
return;
|
||||
}
|
||||
|
||||
if ((type == CHAT_MSG_PARTY_LEADER) && !group->IsLeader(_player->GetGUID()))
|
||||
return;
|
||||
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, this, type, lang, NULL, 0, msg.c_str(), NULL);
|
||||
group->BroadcastPacket(&data, false, group->GetMemberGroup(GetPlayer()->GetGUID()));
|
||||
|
||||
if (sWorld.getConfig(CONFIG_CHATLOG_PARTY))
|
||||
sLog.outChat("[PARTY] Player %s tells group with leader %s: %s",
|
||||
GetPlayer()->GetName(), group->GetLeaderName(), msg.c_str());
|
||||
} break;
|
||||
|
||||
case CHAT_MSG_GUILD:
|
||||
{
|
||||
std::string msg;
|
||||
recv_data >> msg;
|
||||
|
||||
if (msg.empty())
|
||||
break;
|
||||
|
||||
if (ChatHandler(this).ParseCommands(msg.c_str()) > 0)
|
||||
break;
|
||||
|
||||
if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
|
||||
return;
|
||||
|
||||
if (msg.empty())
|
||||
break;
|
||||
|
||||
if (GetPlayer()->GetGuildId())
|
||||
{
|
||||
Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
|
||||
|
||||
if (guild)
|
||||
guild->BroadcastToGuild(this, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
|
||||
|
||||
if (lang != LANG_ADDON && sWorld.getConfig(CONFIG_CHATLOG_GUILD))
|
||||
{
|
||||
sLog.outChat("[GUILD] Player %s tells guild %s: %s",
|
||||
GetPlayer()->GetName(), guild->GetName().c_str(), msg.c_str());
|
||||
}
|
||||
else if (lang == LANG_ADDON && sWorld.getConfig(CONFIG_CHATLOG_ADDON))
|
||||
{
|
||||
sLog.outChat("[ADDON] Player %s sends to guild %s: %s",
|
||||
GetPlayer()->GetName(), guild->GetName().c_str(), msg.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case CHAT_MSG_OFFICER:
|
||||
{
|
||||
std::string msg;
|
||||
recv_data >> msg;
|
||||
|
||||
if (msg.empty())
|
||||
break;
|
||||
|
||||
if (ChatHandler(this).ParseCommands(msg.c_str()) > 0)
|
||||
break;
|
||||
|
||||
if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
|
||||
return;
|
||||
|
||||
if (msg.empty())
|
||||
break;
|
||||
|
||||
if (GetPlayer()->GetGuildId())
|
||||
{
|
||||
Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
|
||||
|
||||
if (guild)
|
||||
guild->BroadcastToOfficers(this, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
|
||||
|
||||
if (sWorld.getConfig(CONFIG_CHATLOG_GUILD))
|
||||
sLog.outChat("[OFFICER] Player %s tells guild %s officers: %s",
|
||||
GetPlayer()->GetName(), guild->GetName().c_str(), msg.c_str());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CHAT_MSG_RAID:
|
||||
{
|
||||
std::string msg;
|
||||
recv_data >> msg;
|
||||
|
||||
if (msg.empty())
|
||||
break;
|
||||
|
||||
if (ChatHandler(this).ParseCommands(msg.c_str()) > 0)
|
||||
break;
|
||||
|
||||
if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
|
||||
return;
|
||||
|
||||
if (msg.empty())
|
||||
break;
|
||||
|
||||
// if player is in battleground, he cannot say to battleground members by /ra
|
||||
Group *group = GetPlayer()->GetOriginalGroup();
|
||||
if (!group)
|
||||
{
|
||||
group = GetPlayer()->GetGroup();
|
||||
if (!group || group->isBGGroup() || !group->isRaidGroup())
|
||||
return;
|
||||
}
|
||||
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID, lang, "", 0, msg.c_str(), NULL);
|
||||
group->BroadcastPacket(&data, false);
|
||||
|
||||
if (sWorld.getConfig(CONFIG_CHATLOG_RAID))
|
||||
sLog.outChat("[RAID] Player %s tells raid with leader %s: %s",
|
||||
GetPlayer()->GetName(), group->GetLeaderName(), msg.c_str());
|
||||
} break;
|
||||
case CHAT_MSG_RAID_LEADER:
|
||||
{
|
||||
std::string msg;
|
||||
recv_data >> msg;
|
||||
|
||||
if (msg.empty())
|
||||
break;
|
||||
|
||||
if (ChatHandler(this).ParseCommands(msg.c_str()) > 0)
|
||||
break;
|
||||
|
||||
if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
|
||||
return;
|
||||
|
||||
if (msg.empty())
|
||||
break;
|
||||
|
||||
// if player is in battleground, he cannot say to battleground members by /ra
|
||||
Group *group = GetPlayer()->GetOriginalGroup();
|
||||
if (!group)
|
||||
{
|
||||
group = GetPlayer()->GetGroup();
|
||||
if (!group || group->isBGGroup() || !group->isRaidGroup() || !group->IsLeader(_player->GetGUID()))
|
||||
return;
|
||||
}
|
||||
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID_LEADER, lang, "", 0, msg.c_str(), NULL);
|
||||
group->BroadcastPacket(&data, false);
|
||||
|
||||
if (sWorld.getConfig(CONFIG_CHATLOG_RAID))
|
||||
sLog.outChat("[RAID] Leader player %s tells raid: %s",
|
||||
GetPlayer()->GetName(), msg.c_str());
|
||||
} break;
|
||||
case CHAT_MSG_RAID_WARNING:
|
||||
{
|
||||
std::string msg;
|
||||
recv_data >> msg;
|
||||
|
||||
if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
|
||||
return;
|
||||
|
||||
if (msg.empty())
|
||||
break;
|
||||
|
||||
Group *group = GetPlayer()->GetGroup();
|
||||
if (!group || !group->isRaidGroup() || !(group->IsLeader(GetPlayer()->GetGUID()) || group->IsAssistant(GetPlayer()->GetGUID())) || group->isBGGroup())
|
||||
return;
|
||||
|
||||
WorldPacket data;
|
||||
//in battleground, raid warning is sent only to players in battleground - code is ok
|
||||
ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID_WARNING, lang, "", 0, msg.c_str(), NULL);
|
||||
group->BroadcastPacket(&data, false);
|
||||
|
||||
if (sWorld.getConfig(CONFIG_CHATLOG_RAID))
|
||||
sLog.outChat("[RAID] Leader player %s warns raid with: %s",
|
||||
GetPlayer()->GetName(), msg.c_str());
|
||||
} break;
|
||||
|
||||
case CHAT_MSG_BATTLEGROUND:
|
||||
{
|
||||
std::string msg;
|
||||
recv_data >> msg;
|
||||
|
||||
if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
|
||||
return;
|
||||
|
||||
if (msg.empty())
|
||||
break;
|
||||
|
||||
//battleground raid is always in Player->GetGroup(), never in GetOriginalGroup()
|
||||
Group *group = GetPlayer()->GetGroup();
|
||||
if (!group || !group->isBGGroup())
|
||||
return;
|
||||
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, this, CHAT_MSG_BATTLEGROUND, lang, "", 0, msg.c_str(), NULL);
|
||||
group->BroadcastPacket(&data, false);
|
||||
|
||||
if (sWorld.getConfig(CONFIG_CHATLOG_BGROUND))
|
||||
sLog.outChat("[BATTLEGROUND] Player %s tells battleground with leader %s: %s",
|
||||
GetPlayer()->GetName(), group->GetLeaderName(), msg.c_str());
|
||||
} break;
|
||||
|
||||
case CHAT_MSG_BATTLEGROUND_LEADER:
|
||||
{
|
||||
std::string msg;
|
||||
recv_data >> msg;
|
||||
|
||||
if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
|
||||
return;
|
||||
|
||||
if (msg.empty())
|
||||
break;
|
||||
|
||||
// battleground raid is always in Player->GetGroup(), never in GetOriginalGroup()
|
||||
Group *group = GetPlayer()->GetGroup();
|
||||
if (!group || !group->isBGGroup() || !group->IsLeader(GetPlayer()->GetGUID()))
|
||||
return;
|
||||
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, this, CHAT_MSG_BATTLEGROUND_LEADER, lang, "", 0, msg.c_str(), NULL);
|
||||
group->BroadcastPacket(&data, false);
|
||||
|
||||
if (sWorld.getConfig(CONFIG_CHATLOG_BGROUND))
|
||||
sLog.outChat("[RAID] Leader player %s tells battleground: %s",
|
||||
GetPlayer()->GetName(), msg.c_str());
|
||||
} break;
|
||||
|
||||
case CHAT_MSG_CHANNEL:
|
||||
{
|
||||
std::string channel, msg;
|
||||
recv_data >> channel;
|
||||
recv_data >> msg;
|
||||
|
||||
if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
|
||||
return;
|
||||
|
||||
if (_player->getLevel() < sWorld.getConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ))
|
||||
{
|
||||
SendNotification(GetTrinityString(LANG_CHANNEL_REQ), sWorld.getConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ));
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg.empty())
|
||||
break;
|
||||
|
||||
if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
|
||||
{
|
||||
|
||||
if (Channel *chn = cMgr->GetChannel(channel, _player))
|
||||
{
|
||||
chn->Say(_player->GetGUID(), msg.c_str(), lang);
|
||||
|
||||
if ((chn->HasFlag(CHANNEL_FLAG_TRADE) ||
|
||||
chn->HasFlag(CHANNEL_FLAG_GENERAL) ||
|
||||
chn->HasFlag(CHANNEL_FLAG_CITY) ||
|
||||
chn->HasFlag(CHANNEL_FLAG_LFG)) &&
|
||||
sWorld.getConfig(CONFIG_CHATLOG_SYSCHAN))
|
||||
sLog.outChat("[SYSCHAN] Player %s tells channel %s: %s",
|
||||
GetPlayer()->GetName(), chn->GetName().c_str(), msg.c_str());
|
||||
else if (sWorld.getConfig(CONFIG_CHATLOG_CHANNEL))
|
||||
sLog.outChat("[CHANNEL] Player %s tells channel %s: %s",
|
||||
GetPlayer()->GetName(), chn->GetName().c_str(), msg.c_str());
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case CHAT_MSG_AFK:
|
||||
{
|
||||
std::string msg;
|
||||
recv_data >> msg;
|
||||
|
||||
if ((msg.empty() || !_player->isAFK()) && !_player->isInCombat())
|
||||
{
|
||||
if (!_player->isAFK())
|
||||
{
|
||||
if (msg.empty())
|
||||
msg = GetTrinityString(LANG_PLAYER_AFK_DEFAULT);
|
||||
_player->afkMsg = msg;
|
||||
}
|
||||
_player->ToggleAFK();
|
||||
if (_player->isAFK() && _player->isDND())
|
||||
_player->ToggleDND();
|
||||
}
|
||||
} break;
|
||||
|
||||
case CHAT_MSG_DND:
|
||||
{
|
||||
std::string msg;
|
||||
recv_data >> msg;
|
||||
|
||||
if (msg.empty() || !_player->isDND())
|
||||
{
|
||||
if (!_player->isDND())
|
||||
{
|
||||
if (msg.empty())
|
||||
msg = GetTrinityString(LANG_PLAYER_DND_DEFAULT);
|
||||
_player->dndMsg = msg;
|
||||
}
|
||||
_player->ToggleDND();
|
||||
if (_player->isDND() && _player->isAFK())
|
||||
_player->ToggleAFK();
|
||||
}
|
||||
} break;
|
||||
|
||||
default:
|
||||
sLog.outError("CHAT: unknown message type %u, lang: %u", type, lang);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandleEmoteOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
if (!GetPlayer()->isAlive())
|
||||
return;
|
||||
|
||||
uint32 emote;
|
||||
recv_data >> emote;
|
||||
GetPlayer()->HandleEmoteCommand(emote);
|
||||
}
|
||||
|
||||
namespace Trinity
|
||||
{
|
||||
class EmoteChatBuilder
|
||||
{
|
||||
public:
|
||||
EmoteChatBuilder(Player const& pl, uint32 text_emote, uint32 emote_num, Unit const* target)
|
||||
: i_player(pl), i_text_emote(text_emote), i_emote_num(emote_num), i_target(target) {}
|
||||
|
||||
void operator()(WorldPacket& data, int32 loc_idx)
|
||||
{
|
||||
char const* nam = i_target ? i_target->GetNameForLocaleIdx(loc_idx) : NULL;
|
||||
uint32 namlen = (nam ? strlen(nam) : 0) + 1;
|
||||
|
||||
data.Initialize(SMSG_TEXT_EMOTE, (20+namlen));
|
||||
data << i_player.GetGUID();
|
||||
data << (uint32)i_text_emote;
|
||||
data << i_emote_num;
|
||||
data << (uint32)namlen;
|
||||
if (namlen > 1)
|
||||
data.append(nam, namlen);
|
||||
else
|
||||
data << (uint8)0x00;
|
||||
}
|
||||
|
||||
private:
|
||||
Player const& i_player;
|
||||
uint32 i_text_emote;
|
||||
uint32 i_emote_num;
|
||||
Unit const* i_target;
|
||||
};
|
||||
} // namespace Trinity
|
||||
|
||||
void WorldSession::HandleTextEmoteOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
if (!GetPlayer()->isAlive())
|
||||
return;
|
||||
|
||||
if (!GetPlayer()->CanSpeak())
|
||||
{
|
||||
std::string timeStr = secsToTimeString(m_muteTime - time(NULL));
|
||||
SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING),timeStr.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 text_emote, emoteNum;
|
||||
uint64 guid;
|
||||
|
||||
recv_data >> text_emote;
|
||||
recv_data >> emoteNum;
|
||||
recv_data >> guid;
|
||||
|
||||
EmotesTextEntry const *em = sEmotesTextStore.LookupEntry(text_emote);
|
||||
if (!em)
|
||||
return;
|
||||
|
||||
uint32 emote_anim = em->textid;
|
||||
|
||||
switch(emote_anim)
|
||||
{
|
||||
case EMOTE_STATE_SLEEP:
|
||||
case EMOTE_STATE_SIT:
|
||||
case EMOTE_STATE_KNEEL:
|
||||
case EMOTE_ONESHOT_NONE:
|
||||
break;
|
||||
default:
|
||||
GetPlayer()->HandleEmoteCommand(emote_anim);
|
||||
break;
|
||||
}
|
||||
|
||||
Unit* unit = ObjectAccessor::GetUnit(*_player, guid);
|
||||
|
||||
CellPair p = Trinity::ComputeCellPair(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY());
|
||||
|
||||
Cell cell(p);
|
||||
cell.data.Part.reserved = ALL_DISTRICT;
|
||||
cell.SetNoCreate();
|
||||
|
||||
Trinity::EmoteChatBuilder emote_builder(*GetPlayer(), text_emote, emoteNum, unit);
|
||||
Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder > emote_do(emote_builder);
|
||||
Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder > > emote_worker(GetPlayer(), sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), emote_do);
|
||||
TypeContainerVisitor<Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder> >, WorldTypeMapContainer> message(emote_worker);
|
||||
cell.Visit(p, message, *GetPlayer()->GetMap(), *GetPlayer(), sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
|
||||
|
||||
GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit);
|
||||
|
||||
//Send scripted event call
|
||||
if (unit && unit->GetTypeId() == TYPEID_UNIT && ((Creature*)unit)->AI())
|
||||
((Creature*)unit)->AI()->ReceiveEmote(GetPlayer(), text_emote);
|
||||
}
|
||||
|
||||
void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recv_data)
|
||||
{
|
||||
uint64 iguid;
|
||||
uint8 unk;
|
||||
//sLog.outDebug("WORLD: Received CMSG_CHAT_IGNORED");
|
||||
|
||||
recv_data >> iguid;
|
||||
recv_data >> unk; // probably related to spam reporting
|
||||
|
||||
Player *player = objmgr.GetPlayer(iguid);
|
||||
if (!player || !player->GetSession())
|
||||
return;
|
||||
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, this, CHAT_MSG_IGNORED, LANG_UNIVERSAL, NULL, GetPlayer()->GetGUID(), GetPlayer()->GetName(), NULL);
|
||||
player->GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::HandleChannelDeclineInvite(WorldPacket &recvPacket)
|
||||
{
|
||||
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
|
||||
}
|
||||
|
||||
void WorldSession::SendPlayerNotFoundNotice(std::string name)
|
||||
{
|
||||
WorldPacket data(SMSG_CHAT_PLAYER_NOT_FOUND, name.size()+1);
|
||||
data << name;
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::SendPlayerAmbiguousNotice(std::string name)
|
||||
{
|
||||
WorldPacket data(SMSG_CHAT_PLAYER_AMBIGUOUS, name.size()+1);
|
||||
data << name;
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::SendWrongFactionNotice()
|
||||
{
|
||||
WorldPacket data(SMSG_CHAT_WRONG_FACTION, 0);
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::SendChatRestrictedNotice(ChatRestrictionType restriction)
|
||||
{
|
||||
WorldPacket data(SMSG_CHAT_RESTRICTED, 1);
|
||||
data << uint8(restriction);
|
||||
SendPacket(&data);
|
||||
}
|
||||
@@ -0,0 +1,370 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "CombatAI.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "Vehicle.h"
|
||||
|
||||
int AggressorAI::Permissible(const Creature *creature)
|
||||
{
|
||||
// have some hostile factions, it will be selected by IsHostileTo check at MoveInLineOfSight
|
||||
if (!creature->isCivilian() && !creature->IsNeutralToAll())
|
||||
return PERMIT_BASE_PROACTIVE;
|
||||
|
||||
return PERMIT_BASE_NO;
|
||||
}
|
||||
|
||||
void AggressorAI::UpdateAI(const uint32 /*diff*/)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
// some day we will delete these useless things
|
||||
int CombatAI::Permissible(const Creature * /*creature*/)
|
||||
{
|
||||
return PERMIT_BASE_NO;
|
||||
}
|
||||
|
||||
int ArchorAI::Permissible(const Creature * /*creature*/)
|
||||
{
|
||||
return PERMIT_BASE_NO;
|
||||
}
|
||||
|
||||
int TurretAI::Permissible(const Creature * /*creature*/)
|
||||
{
|
||||
return PERMIT_BASE_NO;
|
||||
}
|
||||
|
||||
int AOEAI::Permissible(const Creature * /*creature*/)
|
||||
{
|
||||
return PERMIT_BASE_NO;
|
||||
}
|
||||
|
||||
int VehicleAI::Permissible(const Creature * /*creature*/)
|
||||
{
|
||||
return PERMIT_BASE_NO;
|
||||
}
|
||||
|
||||
void CombatAI::InitializeAI()
|
||||
{
|
||||
for (uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i)
|
||||
if (me->m_spells[i] && GetSpellStore()->LookupEntry(me->m_spells[i]))
|
||||
spells.push_back(me->m_spells[i]);
|
||||
|
||||
CreatureAI::InitializeAI();
|
||||
}
|
||||
|
||||
void CombatAI::Reset()
|
||||
{
|
||||
events.Reset();
|
||||
}
|
||||
|
||||
void CombatAI::JustDied(Unit *killer)
|
||||
{
|
||||
for (SpellVct::iterator i = spells.begin(); i != spells.end(); ++i)
|
||||
if (AISpellInfo[*i].condition == AICOND_DIE)
|
||||
me->CastSpell(killer, *i, true);
|
||||
}
|
||||
|
||||
void CombatAI::EnterCombat(Unit *who)
|
||||
{
|
||||
for (SpellVct::iterator i = spells.begin(); i != spells.end(); ++i)
|
||||
{
|
||||
if (AISpellInfo[*i].condition == AICOND_AGGRO)
|
||||
me->CastSpell(who, *i, false);
|
||||
else if (AISpellInfo[*i].condition == AICOND_COMBAT)
|
||||
events.ScheduleEvent(*i, AISpellInfo[*i].cooldown + rand()%AISpellInfo[*i].cooldown);
|
||||
}
|
||||
}
|
||||
|
||||
void CombatAI::UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->hasUnitState(UNIT_STAT_CASTING))
|
||||
return;
|
||||
|
||||
if (uint32 spellId = events.ExecuteEvent())
|
||||
{
|
||||
DoCast(spellId);
|
||||
events.ScheduleEvent(spellId, AISpellInfo[spellId].cooldown + rand()%AISpellInfo[spellId].cooldown);
|
||||
}
|
||||
else
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
/////////////////
|
||||
//CasterAI
|
||||
/////////////////
|
||||
|
||||
void CasterAI::InitializeAI()
|
||||
{
|
||||
CombatAI::InitializeAI();
|
||||
|
||||
float m_attackDist = 30.0f;
|
||||
for (SpellVct::iterator itr = spells.begin(); itr != spells.end(); ++itr)
|
||||
if (AISpellInfo[*itr].condition == AICOND_COMBAT && m_attackDist > GetAISpellInfo(*itr)->maxRange)
|
||||
m_attackDist = GetAISpellInfo(*itr)->maxRange;
|
||||
if (m_attackDist == 30.0f)
|
||||
m_attackDist = MELEE_RANGE;
|
||||
}
|
||||
|
||||
void CasterAI::EnterCombat(Unit *who)
|
||||
{
|
||||
if (spells.empty())
|
||||
return;
|
||||
|
||||
uint32 spell = rand()%spells.size();
|
||||
uint32 count = 0;
|
||||
for (SpellVct::iterator itr = spells.begin(); itr != spells.end(); ++itr, ++count)
|
||||
{
|
||||
if (AISpellInfo[*itr].condition == AICOND_AGGRO)
|
||||
me->CastSpell(who, *itr, false);
|
||||
else if (AISpellInfo[*itr].condition == AICOND_COMBAT)
|
||||
{
|
||||
uint32 cooldown = GetAISpellInfo(*itr)->realCooldown;
|
||||
if (count == spell)
|
||||
{
|
||||
DoCast(spells[spell]);
|
||||
cooldown += me->GetCurrentSpellCastTime(*itr);
|
||||
}
|
||||
events.ScheduleEvent(*itr, cooldown);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CasterAI::UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->hasUnitState(UNIT_STAT_CASTING))
|
||||
return;
|
||||
|
||||
if (uint32 spellId = events.ExecuteEvent())
|
||||
{
|
||||
DoCast(spellId);
|
||||
uint32 casttime = me->GetCurrentSpellCastTime(spellId);
|
||||
events.ScheduleEvent(spellId, (casttime ? casttime : 500) + GetAISpellInfo(spellId)->realCooldown);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////
|
||||
//ArchorAI
|
||||
//////////////
|
||||
|
||||
ArchorAI::ArchorAI(Creature *c) : CreatureAI(c)
|
||||
{
|
||||
if (!me->m_spells[0])
|
||||
sLog.outError("ArchorAI set for creature (entry = %u) with spell1=0. AI will do nothing", me->GetEntry());
|
||||
|
||||
m_minRange = GetSpellMinRange(me->m_spells[0], false);
|
||||
if (!m_minRange)
|
||||
m_minRange = MELEE_RANGE;
|
||||
me->m_CombatDistance = GetSpellMaxRange(me->m_spells[0], false);
|
||||
me->m_SightDistance = me->m_CombatDistance;
|
||||
}
|
||||
|
||||
void ArchorAI::AttackStart(Unit *who)
|
||||
{
|
||||
if (!who)
|
||||
return;
|
||||
|
||||
if (me->IsWithinCombatRange(who, m_minRange))
|
||||
{
|
||||
if (me->Attack(who, true) && !who->IsFlying())
|
||||
me->GetMotionMaster()->MoveChase(who);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (me->Attack(who, false) && !who->IsFlying())
|
||||
me->GetMotionMaster()->MoveChase(who, me->m_CombatDistance);
|
||||
}
|
||||
|
||||
if (who->IsFlying())
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
}
|
||||
|
||||
void ArchorAI::UpdateAI(const uint32 /*diff*/)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (!me->IsWithinCombatRange(me->getVictim(), m_minRange))
|
||||
DoSpellAttackIfReady(me->m_spells[0]);
|
||||
else
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
//////////////
|
||||
//TurretAI
|
||||
//////////////
|
||||
|
||||
TurretAI::TurretAI(Creature *c) : CreatureAI(c)
|
||||
{
|
||||
if (!me->m_spells[0])
|
||||
sLog.outError("TurretAI set for creature (entry = %u) with spell1=0. AI will do nothing", me->GetEntry());
|
||||
|
||||
m_minRange = GetSpellMinRange(me->m_spells[0], false);
|
||||
me->m_CombatDistance = GetSpellMaxRange(me->m_spells[0], false);
|
||||
me->m_SightDistance = me->m_CombatDistance;
|
||||
}
|
||||
|
||||
bool TurretAI::CanAIAttack(const Unit * /*who*/) const
|
||||
{
|
||||
// TODO: use one function to replace it
|
||||
if (!me->IsWithinCombatRange(me->getVictim(), me->m_CombatDistance)
|
||||
|| m_minRange && me->IsWithinCombatRange(me->getVictim(), m_minRange))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void TurretAI::AttackStart(Unit *who)
|
||||
{
|
||||
if (who)
|
||||
me->Attack(who, false);
|
||||
}
|
||||
|
||||
void TurretAI::UpdateAI(const uint32 /*diff*/)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoSpellAttackIfReady(me->m_spells[0]);
|
||||
}
|
||||
|
||||
//////////////
|
||||
//AOEAI
|
||||
//////////////
|
||||
|
||||
AOEAI::AOEAI(Creature *c) : CreatureAI(c)
|
||||
{
|
||||
if (!me->m_spells[0])
|
||||
sLog.outError("AOEAI set for creature (entry = %u) with spell1=0. AI will do nothing", me->GetEntry());
|
||||
|
||||
me->SetVisibility(VISIBILITY_ON);//visible to see all spell anims
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);//can't be targeted
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_1);//can't be damaged
|
||||
me->SetDisplayId(11686);//invisible model,around a size of a player
|
||||
}
|
||||
|
||||
bool AOEAI::CanAIAttack(const Unit * /*who*/) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void AOEAI::AttackStart(Unit * /*who*/)
|
||||
{
|
||||
}
|
||||
|
||||
void AOEAI::UpdateAI(const uint32 /*diff*/)
|
||||
{
|
||||
if (!me->HasAura(me->m_spells[0]))
|
||||
me->CastSpell(me, me->m_spells[0],false);
|
||||
}
|
||||
|
||||
//////////////
|
||||
//VehicleAI
|
||||
//////////////
|
||||
|
||||
VehicleAI::VehicleAI(Creature *c) : CreatureAI(c), m_vehicle(c->GetVehicleKit()), m_IsVehicleInUse(false), m_ConditionsTimer(VEHICLE_CONDITION_CHECK_TIME)
|
||||
{
|
||||
LoadConditions();
|
||||
m_DoDismiss = false;
|
||||
m_DismissTimer = VEHICLE_DISMISS_TIME;
|
||||
}
|
||||
|
||||
|
||||
//NOTE: VehicleAI::UpdateAI runs even while the vehicle is mounted
|
||||
void VehicleAI::UpdateAI(const uint32 diff)
|
||||
{
|
||||
CheckConditions(diff);
|
||||
|
||||
if (m_DoDismiss)
|
||||
{
|
||||
if (m_DismissTimer < diff)
|
||||
{
|
||||
m_DoDismiss = false;
|
||||
me->SetVisibility(VISIBILITY_OFF);
|
||||
me->ForcedDespawn();
|
||||
}else m_DismissTimer -= diff;
|
||||
}
|
||||
}
|
||||
|
||||
void VehicleAI::Reset()
|
||||
{
|
||||
me->SetVisibility(VISIBILITY_ON);
|
||||
|
||||
m_vehicle->Reset();
|
||||
}
|
||||
|
||||
void VehicleAI::OnCharmed(bool apply)
|
||||
{
|
||||
if (m_IsVehicleInUse && !apply && !conditions.empty())//was used and has conditions
|
||||
{
|
||||
m_DoDismiss = true;//needs reset
|
||||
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE);
|
||||
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||
}
|
||||
else if (apply)
|
||||
m_DoDismiss = false;//in use again
|
||||
m_DismissTimer = VEHICLE_DISMISS_TIME;//reset timer
|
||||
m_IsVehicleInUse = apply;
|
||||
}
|
||||
|
||||
void VehicleAI::LoadConditions()
|
||||
{
|
||||
conditions = sConditionMgr.GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_CREATURE_TEMPLATE_VEHICLE, me->GetEntry());
|
||||
if (!conditions.empty())
|
||||
{
|
||||
sLog.outDebug("VehicleAI::LoadConditions: loaded %u conditions", uint32(conditions.size()));
|
||||
}
|
||||
}
|
||||
|
||||
void VehicleAI::CheckConditions(const uint32 diff)
|
||||
{
|
||||
if(m_ConditionsTimer < diff)
|
||||
{
|
||||
if (!conditions.empty())
|
||||
{
|
||||
for (SeatMap::iterator itr = m_vehicle->m_Seats.begin(); itr != m_vehicle->m_Seats.end(); ++itr)
|
||||
if (Unit *passenger = itr->second.passenger)
|
||||
{
|
||||
if (Player* plr = passenger->ToPlayer())
|
||||
{
|
||||
if (!sConditionMgr.IsPlayerMeetToConditions(plr, conditions))
|
||||
{
|
||||
plr->ExitVehicle();
|
||||
return;//check other pessanger in next tick
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m_ConditionsTimer = VEHICLE_CONDITION_CHECK_TIME;
|
||||
} else m_ConditionsTimer -= diff;
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_COMBATAI_H
|
||||
#define TRINITY_COMBATAI_H
|
||||
|
||||
#include "CreatureAI.h"
|
||||
#include "CreatureAIImpl.h"
|
||||
#include "ConditionMgr.h"
|
||||
|
||||
class Creature;
|
||||
|
||||
class AggressorAI : public CreatureAI
|
||||
{
|
||||
public:
|
||||
explicit AggressorAI(Creature *c) : CreatureAI(c) {}
|
||||
|
||||
void UpdateAI(const uint32);
|
||||
static int Permissible(const Creature *);
|
||||
};
|
||||
|
||||
typedef std::vector<uint32> SpellVct;
|
||||
|
||||
class CombatAI : public CreatureAI
|
||||
{
|
||||
public:
|
||||
explicit CombatAI(Creature *c) : CreatureAI(c) {}
|
||||
|
||||
void InitializeAI();
|
||||
void Reset();
|
||||
void EnterCombat(Unit* who);
|
||||
void JustDied(Unit *killer);
|
||||
void UpdateAI(const uint32 diff);
|
||||
static int Permissible(const Creature *);
|
||||
protected:
|
||||
EventMap events;
|
||||
SpellVct spells;
|
||||
};
|
||||
|
||||
class CasterAI : public CombatAI
|
||||
{
|
||||
public:
|
||||
explicit CasterAI(Creature *c) : CombatAI(c) { m_attackDist = MELEE_RANGE; }
|
||||
void InitializeAI();
|
||||
void AttackStart(Unit * victim) { AttackStartCaster(victim, m_attackDist); }
|
||||
void UpdateAI(const uint32 diff);
|
||||
void EnterCombat(Unit * /*who*/);
|
||||
private:
|
||||
float m_attackDist;
|
||||
};
|
||||
|
||||
struct ArchorAI : public CreatureAI
|
||||
{
|
||||
public:
|
||||
explicit ArchorAI(Creature *c);
|
||||
void AttackStart(Unit *who);
|
||||
void UpdateAI(const uint32 diff);
|
||||
|
||||
static int Permissible(const Creature *);
|
||||
protected:
|
||||
float m_minRange;
|
||||
};
|
||||
|
||||
struct TurretAI : public CreatureAI
|
||||
{
|
||||
public:
|
||||
explicit TurretAI(Creature *c);
|
||||
bool CanAIAttack(const Unit *who) const;
|
||||
void AttackStart(Unit *who);
|
||||
void UpdateAI(const uint32 diff);
|
||||
|
||||
static int Permissible(const Creature *);
|
||||
protected:
|
||||
float m_minRange;
|
||||
};
|
||||
|
||||
struct AOEAI : public CreatureAI
|
||||
{
|
||||
public:
|
||||
explicit AOEAI(Creature *c);
|
||||
bool CanAIAttack(const Unit *who) const;
|
||||
void AttackStart(Unit *who);
|
||||
void UpdateAI(const uint32 diff);
|
||||
|
||||
static int Permissible(const Creature *);
|
||||
};
|
||||
#define VEHICLE_CONDITION_CHECK_TIME 1000
|
||||
#define VEHICLE_DISMISS_TIME 5000
|
||||
struct VehicleAI : public CreatureAI
|
||||
{
|
||||
public:
|
||||
explicit VehicleAI(Creature *c);
|
||||
|
||||
void UpdateAI(const uint32 diff);
|
||||
static int Permissible(const Creature *);
|
||||
void Reset();
|
||||
void MoveInLineOfSight(Unit *) {}
|
||||
void AttackStart(Unit *) {}
|
||||
void OnCharmed(bool apply);
|
||||
|
||||
private:
|
||||
Vehicle* m_vehicle;
|
||||
bool m_IsVehicleInUse;
|
||||
void LoadConditions();
|
||||
void CheckConditions(const uint32 diff);
|
||||
ConditionList conditions;
|
||||
uint32 m_ConditionsTimer;
|
||||
bool m_DoDismiss;
|
||||
uint32 m_DismissTimer;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Common.h"
|
||||
#include "Log.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "CreatureAI.h"
|
||||
#include "ObjectDefines.h"
|
||||
|
||||
void WorldSession::HandleAttackSwingOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
uint64 guid;
|
||||
recv_data >> guid;
|
||||
|
||||
DEBUG_LOG("WORLD: Recvd CMSG_ATTACKSWING Message guidlow:%u guidhigh:%u", GUID_LOPART(guid), GUID_HIPART(guid));
|
||||
|
||||
Unit *pEnemy = ObjectAccessor::GetUnit(*_player, guid);
|
||||
|
||||
if (!pEnemy)
|
||||
{
|
||||
if (!IS_UNIT_GUID(guid))
|
||||
sLog.outError("WORLD: Object %u (TypeID: %u) isn't player, pet or creature",GUID_LOPART(guid),GuidHigh2TypeId(GUID_HIPART(guid)));
|
||||
else
|
||||
sLog.outError("WORLD: Enemy %s %u not found",GetLogNameForGuid(guid),GUID_LOPART(guid));
|
||||
|
||||
// stop attack state at client
|
||||
SendAttackStop(NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_player->canAttack(pEnemy))
|
||||
{
|
||||
sLog.outError("WORLD: Enemy %s %u is friendly",(IS_PLAYER_GUID(guid) ? "player" : "creature"),GUID_LOPART(guid));
|
||||
|
||||
// stop attack state at client
|
||||
SendAttackStop(pEnemy);
|
||||
return;
|
||||
}
|
||||
|
||||
_player->Attack(pEnemy,true);
|
||||
}
|
||||
|
||||
void WorldSession::HandleAttackStopOpcode(WorldPacket & /*recv_data*/)
|
||||
{
|
||||
GetPlayer()->AttackStop();
|
||||
}
|
||||
|
||||
void WorldSession::HandleSetSheathedOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
uint32 sheathed;
|
||||
recv_data >> sheathed;
|
||||
|
||||
//sLog.outDebug("WORLD: Recvd CMSG_SETSHEATHED Message guidlow:%u value1:%u", GetPlayer()->GetGUIDLow(), sheathed);
|
||||
|
||||
if (sheathed >= MAX_SHEATH_STATE)
|
||||
{
|
||||
sLog.outError("Unknown sheath state %u ??",sheathed);
|
||||
return;
|
||||
}
|
||||
|
||||
GetPlayer()->SetSheath(SheathState(sheathed));
|
||||
}
|
||||
|
||||
void WorldSession::SendAttackStop(Unit const* enemy)
|
||||
{
|
||||
WorldPacket data(SMSG_ATTACKSTOP, (4+20)); // we guess size
|
||||
data.append(GetPlayer()->GetPackGUID());
|
||||
data.append(enemy ? enemy->GetPackGUID() : 0); // must be packed guid
|
||||
data << uint32(0); // unk, can be 1 also
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_CONDITIONMGR_H
|
||||
#define TRINITY_CONDITIONMGR_H
|
||||
|
||||
#include "LootMgr.h"
|
||||
|
||||
class Player;
|
||||
class Unit;
|
||||
class LootTemplate;
|
||||
|
||||
enum ConditionType
|
||||
{ // value1 value2 value3
|
||||
CONDITION_NONE = 0, // 0 0 0 always true
|
||||
CONDITION_AURA = 1, // spell_id effindex +referenceID true if has aura of spell_id with effect effindex
|
||||
CONDITION_ITEM = 2, // item_id count +referenceID true if has #count of item_ids
|
||||
CONDITION_ITEM_EQUIPPED = 3, // item_id 0 +referenceID true if has item_id equipped
|
||||
CONDITION_ZONEID = 4, // zone_id 0 +referenceID true if in zone_id
|
||||
CONDITION_REPUTATION_RANK = 5, // faction_id min_rank +referenceID true if has min_rank for faction_id
|
||||
CONDITION_TEAM = 6, // player_team 0, +referenceID 469 - Alliance, 67 - Horde)
|
||||
CONDITION_SKILL = 7, // skill_id skill_value +referenceID true if has skill_value for skill_id
|
||||
CONDITION_QUESTREWARDED = 8, // quest_id 0 +referenceID true if quest_id was rewarded before
|
||||
CONDITION_QUESTTAKEN = 9, // quest_id 0, +referenceID true while quest active
|
||||
CONDITION_AD_COMMISSION_AURA = 10, // 0 0, +referenceID true while one from AD commission aura active
|
||||
CONDITION_NO_AURA = 11, // spell_id effindex +referenceID true if does not have aura of spell_id with effect effindex
|
||||
CONDITION_ACTIVE_EVENT = 12, // event_id 0 +referenceID true if event is active
|
||||
CONDITION_INSTANCE_DATA = 13, // entry data +referenceID true if data is set in current instance
|
||||
CONDITION_QUEST_NONE = 14, // quest_id 0 +referenceID true if doesn't have quest saved
|
||||
CONDITION_CLASS = 15, // class 0 +referenceID true if player's class is equal to class
|
||||
CONDITION_RACE = 16, // race 0 +referenceID true if player's race is equal to race
|
||||
CONDITION_ACHIEVEMENT = 17, // achievement_id 0 +referenceID true if achievement is complete
|
||||
CONDITION_SPELL_SCRIPT_TARGET = 18, // SpellScriptTargetType, TargetEntry, 0
|
||||
CONDITION_CREATURE_TARGET = 19, // creature entry 0 +referenceID true if current target is creature with value1 entry
|
||||
CONDITION_TARGET_HEALTH_BELOW_PCT = 20, // 0-100 0 +referenceID true if target's health is below value1 percent, false if over or no target
|
||||
CONDITION_TARGET_RANGE = 21, // minDistance maxDist +referenceID true if target is closer then minDist and further then maxDist or if max is 0 then max dist is infinit
|
||||
CONDITION_MAPID = 22, // map_id 0 +referenceID true if in map_id
|
||||
CONDITION_AREAID = 23, // area_id 0 +referenceID true if in area_id
|
||||
CONDITION_ITEM_TARGET = 24 // ItemRequiredTargetType, TargetEntry, 0
|
||||
};
|
||||
|
||||
#define MAX_CONDITION 25 // maximum value in ConditionType enum
|
||||
|
||||
enum ConditionSourceType
|
||||
{
|
||||
CONDITION_SOURCE_TYPE_NONE = 0,//DONE
|
||||
CONDITION_SOURCE_TYPE_CREATURE_LOOT_TEMPLATE = 1,//DONE
|
||||
CONDITION_SOURCE_TYPE_DISENCHANT_LOOT_TEMPLATE = 2,//DONE
|
||||
CONDITION_SOURCE_TYPE_FISHING_LOOT_TEMPLATE = 3,//DONE
|
||||
CONDITION_SOURCE_TYPE_GAMEOBJECT_LOOT_TEMPLATE = 4,//DONE
|
||||
CONDITION_SOURCE_TYPE_ITEM_LOOT_TEMPLATE = 5,//DONE
|
||||
CONDITION_SOURCE_TYPE_MAIL_LOOT_TEMPLATE = 6,//DONE
|
||||
CONDITION_SOURCE_TYPE_MILLING_LOOT_TEMPLATE = 7,//DONE
|
||||
CONDITION_SOURCE_TYPE_PICKPOCKETING_LOOT_TEMPLATE = 8,//DONE
|
||||
CONDITION_SOURCE_TYPE_PROSPECTING_LOOT_TEMPLATE = 9,//DONE
|
||||
CONDITION_SOURCE_TYPE_REFERENCE_LOOT_TEMPLATE = 10,//DONE
|
||||
CONDITION_SOURCE_TYPE_SKINNING_LOOT_TEMPLATE = 11,//DONE
|
||||
CONDITION_SOURCE_TYPE_SPELL_LOOT_TEMPLATE = 12,//DONE
|
||||
CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET = 13,//DONE
|
||||
CONDITION_SOURCE_TYPE_GOSSIP_MENU = 14,//DONE
|
||||
CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION = 15,//DONE
|
||||
CONDITION_SOURCE_TYPE_CREATURE_TEMPLATE_VEHICLE = 16,//DONE
|
||||
CONDITION_SOURCE_TYPE_SPELL = 17,//DONE
|
||||
CONDITION_SOURCE_TYPE_ITEM_REQUIRED_TARGET = 18//DONE
|
||||
};
|
||||
|
||||
#define MAX_CONDITIONSOURCETYPE 19
|
||||
|
||||
struct Condition
|
||||
{
|
||||
ConditionSourceType mSourceType; //SourceTypeOrReferenceId
|
||||
uint32 mSourceGroup;
|
||||
uint32 mSourceEntry;
|
||||
uint32 mElseGroup;
|
||||
ConditionType mConditionType; //ConditionTypeOrReference
|
||||
uint32 mConditionValue1;
|
||||
uint32 mConditionValue2;
|
||||
uint32 mConditionValue3;
|
||||
uint32 ErrorTextd;
|
||||
uint32 mReferenceId;
|
||||
|
||||
Condition()
|
||||
{
|
||||
mSourceType = CONDITION_SOURCE_TYPE_NONE;
|
||||
mSourceGroup = 0;
|
||||
mSourceEntry = 0;
|
||||
mElseGroup = 0;
|
||||
mConditionType = CONDITION_NONE;
|
||||
mConditionValue1 = 0;
|
||||
mConditionValue2 = 0;
|
||||
mConditionValue3 = 0;
|
||||
mReferenceId = 0;
|
||||
ErrorTextd = 0;
|
||||
}
|
||||
bool Meets(Player * player, Unit* targetOverride = NULL);
|
||||
bool isLoaded() { return mConditionType > CONDITION_NONE || mReferenceId; }
|
||||
};
|
||||
|
||||
typedef std::list<Condition*> ConditionList;
|
||||
typedef std::map<uint32, ConditionList > ConditionTypeMap;
|
||||
typedef std::map<ConditionSourceType, ConditionTypeMap > ConditionMap;//used for all conditions, except references
|
||||
|
||||
typedef std::map<uint32, ConditionList > ConditionReferenceMap;//only used for references
|
||||
|
||||
class ConditionMgr
|
||||
{
|
||||
public:
|
||||
ConditionMgr();
|
||||
~ConditionMgr();
|
||||
|
||||
void LoadConditions(bool isReload = false);
|
||||
bool isConditionTypeValid(Condition* cond);
|
||||
ConditionList GetConditionReferences(uint32 refId);
|
||||
|
||||
bool IsPlayerMeetToConditions(Player* player, ConditionList conditions, Unit* targetOverride = NULL);
|
||||
ConditionList GetConditionsForNotGroupedEntry(ConditionSourceType sType, uint32 uEntry);
|
||||
|
||||
protected:
|
||||
ConditionMap m_ConditionMap;
|
||||
ConditionReferenceMap m_ConditionReferenceMap;
|
||||
|
||||
private:
|
||||
bool isSourceTypeValid(Condition* cond);
|
||||
bool addToLootTemplate(Condition* cond, LootTemplate* loot);
|
||||
bool addToGossipMenus(Condition* cond);
|
||||
bool addToGossipMenuItems(Condition* cond);
|
||||
bool IsPlayerMeetToConditionList(Player* player,const ConditionList& conditions, Unit* targetOverride = NULL);
|
||||
|
||||
bool isGroupable(ConditionSourceType sourceType)
|
||||
{
|
||||
return (sourceType == CONDITION_SOURCE_TYPE_CREATURE_LOOT_TEMPLATE ||
|
||||
sourceType == CONDITION_SOURCE_TYPE_DISENCHANT_LOOT_TEMPLATE ||
|
||||
sourceType == CONDITION_SOURCE_TYPE_FISHING_LOOT_TEMPLATE ||
|
||||
sourceType == CONDITION_SOURCE_TYPE_GAMEOBJECT_LOOT_TEMPLATE ||
|
||||
sourceType == CONDITION_SOURCE_TYPE_ITEM_LOOT_TEMPLATE ||
|
||||
sourceType == CONDITION_SOURCE_TYPE_MAIL_LOOT_TEMPLATE ||
|
||||
sourceType == CONDITION_SOURCE_TYPE_MILLING_LOOT_TEMPLATE ||
|
||||
sourceType == CONDITION_SOURCE_TYPE_PICKPOCKETING_LOOT_TEMPLATE ||
|
||||
sourceType == CONDITION_SOURCE_TYPE_PROSPECTING_LOOT_TEMPLATE ||
|
||||
sourceType == CONDITION_SOURCE_TYPE_REFERENCE_LOOT_TEMPLATE ||
|
||||
sourceType == CONDITION_SOURCE_TYPE_SKINNING_LOOT_TEMPLATE ||
|
||||
sourceType == CONDITION_SOURCE_TYPE_SPELL_LOOT_TEMPLATE ||
|
||||
sourceType == CONDITION_SOURCE_TYPE_GOSSIP_MENU ||
|
||||
sourceType == CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION);
|
||||
}
|
||||
};
|
||||
|
||||
#define sConditionMgr Trinity::Singleton<ConditionMgr>::Instance()
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Creature.h"
|
||||
#include "MapManager.h"
|
||||
#include "Opcodes.h"
|
||||
#include "ConfusedMovementGenerator.h"
|
||||
#include "DestinationHolderImp.h"
|
||||
#include "VMapFactory.h"
|
||||
|
||||
#ifdef MAP_BASED_RAND_GEN
|
||||
#define rand_norm() unit.rand_norm()
|
||||
#define urand(a,b) unit.urand(a,b)
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
void
|
||||
ConfusedMovementGenerator<T>::Initialize(T &unit)
|
||||
{
|
||||
const float wander_distance = 11;
|
||||
float x,y,z;
|
||||
x = unit.GetPositionX();
|
||||
y = unit.GetPositionY();
|
||||
z = unit.GetPositionZ();
|
||||
|
||||
Map const* map = unit.GetBaseMap();
|
||||
|
||||
i_nextMove = 1;
|
||||
|
||||
bool is_water_ok, is_land_ok;
|
||||
_InitSpecific(unit, is_water_ok, is_land_ok);
|
||||
|
||||
VMAP::IVMapManager *vMaps = VMAP::VMapFactory::createOrGetVMapManager();
|
||||
|
||||
for (uint8 idx = 0; idx <= MAX_CONF_WAYPOINTS; ++idx)
|
||||
{
|
||||
const bool isInLoS = vMaps->isInLineOfSight(unit.GetMapId(), x, y, z + 2.0f, i_waypoints[idx][0], i_waypoints[idx][1], z + 2.0f);
|
||||
if (isInLoS)
|
||||
{
|
||||
const float wanderX = wander_distance*rand_norm() - wander_distance/2;
|
||||
const float wanderY = wander_distance*rand_norm() - wander_distance/2;
|
||||
i_waypoints[idx][0] = x + wanderX;
|
||||
i_waypoints[idx][1] = y + wanderY;
|
||||
}
|
||||
else
|
||||
{
|
||||
i_waypoints[idx][0] = x;
|
||||
i_waypoints[idx][1] = y;
|
||||
}
|
||||
|
||||
// prevent invalid coordinates generation
|
||||
Trinity::NormalizeMapCoord(i_waypoints[idx][0]);
|
||||
Trinity::NormalizeMapCoord(i_waypoints[idx][1]);
|
||||
|
||||
bool is_water = map->IsInWater(i_waypoints[idx][0],i_waypoints[idx][1],z);
|
||||
// if generated wrong path just ignore
|
||||
if ((is_water && !is_water_ok) || (!is_water && !is_land_ok))
|
||||
{
|
||||
i_waypoints[idx][0] = idx > 0 ? i_waypoints[idx-1][0] : x;
|
||||
i_waypoints[idx][1] = idx > 0 ? i_waypoints[idx-1][1] : y;
|
||||
}
|
||||
|
||||
unit.UpdateGroundPositionZ(i_waypoints[idx][0],i_waypoints[idx][1],z);
|
||||
i_waypoints[idx][2] = z;
|
||||
}
|
||||
|
||||
unit.SetUInt64Value(UNIT_FIELD_TARGET, 0);
|
||||
unit.SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED);
|
||||
unit.CastStop();
|
||||
unit.StopMoving();
|
||||
unit.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
|
||||
unit.addUnitState(UNIT_STAT_CONFUSED);
|
||||
}
|
||||
|
||||
template<>
|
||||
void
|
||||
ConfusedMovementGenerator<Creature>::_InitSpecific(Creature &creature, bool &is_water_ok, bool &is_land_ok)
|
||||
{
|
||||
is_water_ok = creature.canSwim();
|
||||
is_land_ok = creature.canWalk();
|
||||
}
|
||||
|
||||
template<>
|
||||
void
|
||||
ConfusedMovementGenerator<Player>::_InitSpecific(Player &, bool &is_water_ok, bool &is_land_ok)
|
||||
{
|
||||
is_water_ok = true;
|
||||
is_land_ok = true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
ConfusedMovementGenerator<T>::Reset(T &unit)
|
||||
{
|
||||
i_nextMove = 1;
|
||||
i_nextMoveTime.Reset(0);
|
||||
i_destinationHolder.ResetUpdate();
|
||||
unit.StopMoving();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
ConfusedMovementGenerator<T>::Update(T &unit, const uint32 &diff)
|
||||
{
|
||||
if (!&unit)
|
||||
return true;
|
||||
|
||||
if (unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
|
||||
return true;
|
||||
|
||||
if (i_nextMoveTime.Passed())
|
||||
{
|
||||
// currently moving, update location
|
||||
Traveller<T> traveller(unit);
|
||||
if (i_destinationHolder.UpdateTraveller(traveller, diff))
|
||||
{
|
||||
if (i_destinationHolder.HasArrived())
|
||||
{
|
||||
// arrived, stop and wait a bit
|
||||
unit.clearUnitState(UNIT_STAT_MOVE);
|
||||
|
||||
i_nextMove = urand(1,MAX_CONF_WAYPOINTS);
|
||||
i_nextMoveTime.Reset(urand(0, 1500-1)); // TODO: check the minimum reset time, should be probably higher
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// waiting for next move
|
||||
i_nextMoveTime.Update(diff);
|
||||
if (i_nextMoveTime.Passed())
|
||||
{
|
||||
// start moving
|
||||
assert(i_nextMove <= MAX_CONF_WAYPOINTS);
|
||||
const float x = i_waypoints[i_nextMove][0];
|
||||
const float y = i_waypoints[i_nextMove][1];
|
||||
const float z = i_waypoints[i_nextMove][2];
|
||||
Traveller<T> traveller(unit);
|
||||
i_destinationHolder.SetDestination(traveller, x, y, z);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
ConfusedMovementGenerator<T>::Finalize(T &unit)
|
||||
{
|
||||
unit.RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED);
|
||||
unit.clearUnitState(UNIT_STAT_CONFUSED);
|
||||
if (unit.GetTypeId() == TYPEID_UNIT && unit.getVictim())
|
||||
unit.SetUInt64Value(UNIT_FIELD_TARGET, unit.getVictim()->GetGUID());
|
||||
}
|
||||
|
||||
template void ConfusedMovementGenerator<Player>::Initialize(Player &player);
|
||||
template void ConfusedMovementGenerator<Creature>::Initialize(Creature &creature);
|
||||
template void ConfusedMovementGenerator<Player>::Finalize(Player &player);
|
||||
template void ConfusedMovementGenerator<Creature>::Finalize(Creature &creature);
|
||||
template void ConfusedMovementGenerator<Player>::Reset(Player &player);
|
||||
template void ConfusedMovementGenerator<Creature>::Reset(Creature &creature);
|
||||
template bool ConfusedMovementGenerator<Player>::Update(Player &player, const uint32 &diff);
|
||||
template bool ConfusedMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff);
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_CONFUSEDGENERATOR_H
|
||||
#define TRINITY_CONFUSEDGENERATOR_H
|
||||
|
||||
#include "MovementGenerator.h"
|
||||
#include "DestinationHolder.h"
|
||||
#include "Traveller.h"
|
||||
|
||||
#define MAX_CONF_WAYPOINTS 24
|
||||
|
||||
template<class T>
|
||||
class ConfusedMovementGenerator
|
||||
: public MovementGeneratorMedium< T, ConfusedMovementGenerator<T> >
|
||||
{
|
||||
public:
|
||||
explicit ConfusedMovementGenerator() : i_nextMoveTime(0) {}
|
||||
|
||||
void Initialize(T &);
|
||||
void Finalize(T &);
|
||||
void Reset(T &);
|
||||
bool Update(T &, const uint32 &);
|
||||
|
||||
bool GetDestination(float &x, float &y, float &z) const
|
||||
{
|
||||
if (i_destinationHolder.HasArrived()) return false;
|
||||
i_destinationHolder.GetDestination(x,y,z);
|
||||
return true;
|
||||
}
|
||||
|
||||
MovementGeneratorType GetMovementGeneratorType() { return CONFUSED_MOTION_TYPE; }
|
||||
private:
|
||||
void _InitSpecific(T &, bool &, bool &);
|
||||
TimeTracker i_nextMoveTime;
|
||||
float i_waypoints[MAX_CONF_WAYPOINTS+1][3];
|
||||
DestinationHolder< Traveller<T> > i_destinationHolder;
|
||||
uint32 i_nextMove;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Common.h"
|
||||
#include "Corpse.h"
|
||||
#include "Player.h"
|
||||
#include "UpdateMask.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "Opcodes.h"
|
||||
#include "GossipDef.h"
|
||||
#include "World.h"
|
||||
|
||||
Corpse::Corpse(CorpseType type) : WorldObject()
|
||||
, m_type(type)
|
||||
{
|
||||
m_objectType |= TYPEMASK_CORPSE;
|
||||
m_objectTypeId = TYPEID_CORPSE;
|
||||
|
||||
m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_POSITION);
|
||||
|
||||
m_valuesCount = CORPSE_END;
|
||||
|
||||
m_time = time(NULL);
|
||||
|
||||
lootForBody = false;
|
||||
|
||||
if (type != CORPSE_BONES)
|
||||
m_isWorldObject = true;
|
||||
}
|
||||
|
||||
Corpse::~Corpse()
|
||||
{
|
||||
}
|
||||
|
||||
void Corpse::AddToWorld()
|
||||
{
|
||||
///- Register the corpse for guid lookup
|
||||
if (!IsInWorld())
|
||||
ObjectAccessor::Instance().AddObject(this);
|
||||
|
||||
Object::AddToWorld();
|
||||
}
|
||||
|
||||
void Corpse::RemoveFromWorld()
|
||||
{
|
||||
///- Remove the corpse from the accessor
|
||||
if (IsInWorld())
|
||||
ObjectAccessor::Instance().RemoveObject(this);
|
||||
|
||||
Object::RemoveFromWorld();
|
||||
}
|
||||
|
||||
bool Corpse::Create(uint32 guidlow, Map *map)
|
||||
{
|
||||
SetMap(map);
|
||||
Object::_Create(guidlow, 0, HIGHGUID_CORPSE);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Corpse::Create(uint32 guidlow, Player *owner)
|
||||
{
|
||||
ASSERT(owner);
|
||||
|
||||
Relocate(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ(), owner->GetOrientation());
|
||||
|
||||
if (!IsPositionValid())
|
||||
{
|
||||
sLog.outError("Corpse (guidlow %d, owner %s) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
|
||||
guidlow, owner->GetName(), owner->GetPositionX(), owner->GetPositionY());
|
||||
return false;
|
||||
}
|
||||
|
||||
//we need to assign owner's map for corpse
|
||||
//in other way we will get a crash in Corpse::SaveToDB()
|
||||
SetMap(owner->GetMap());
|
||||
|
||||
WorldObject::_Create(guidlow, HIGHGUID_CORPSE, owner->GetPhaseMask());
|
||||
|
||||
SetFloatValue(OBJECT_FIELD_SCALE_X, 1);
|
||||
SetUInt64Value(CORPSE_FIELD_OWNER, owner->GetGUID());
|
||||
|
||||
m_grid = Trinity::ComputeGridPair(GetPositionX(), GetPositionY());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Corpse::SaveToDB()
|
||||
{
|
||||
// prevent DB data inconsistence problems and duplicates
|
||||
CharacterDatabase.BeginTransaction();
|
||||
DeleteFromDB();
|
||||
|
||||
std::ostringstream ss;
|
||||
ss << "INSERT INTO corpse (guid,player,position_x,position_y,position_z,orientation,zone,map,data,time,corpse_type,instance,phaseMask) VALUES ("
|
||||
<< GetGUIDLow() << ", "
|
||||
<< GUID_LOPART(GetOwnerGUID()) << ", "
|
||||
<< GetPositionX() << ", "
|
||||
<< GetPositionY() << ", "
|
||||
<< GetPositionZ() << ", "
|
||||
<< GetOrientation() << ", "
|
||||
<< GetZoneId() << ", "
|
||||
<< GetMapId() << ", '";
|
||||
for (uint16 i = 0; i < m_valuesCount; ++i)
|
||||
ss << GetUInt32Value(i) << " ";
|
||||
ss << "',"
|
||||
<< uint64(m_time) <<", "
|
||||
<< uint32(GetType()) << ", "
|
||||
<< int(GetInstanceId()) << ", "
|
||||
<< uint16(GetPhaseMask()) << ")"; // prevent out of range error
|
||||
CharacterDatabase.Execute(ss.str().c_str());
|
||||
CharacterDatabase.CommitTransaction();
|
||||
}
|
||||
|
||||
void Corpse::DeleteBonesFromWorld()
|
||||
{
|
||||
assert(GetType() == CORPSE_BONES);
|
||||
Corpse* corpse = ObjectAccessor::GetCorpse(*this, GetGUID());
|
||||
|
||||
if (!corpse)
|
||||
{
|
||||
sLog.outError("Bones %u not found in world.", GetGUIDLow());
|
||||
return;
|
||||
}
|
||||
|
||||
AddObjectToRemoveList();
|
||||
}
|
||||
|
||||
void Corpse::DeleteFromDB()
|
||||
{
|
||||
if (GetType() == CORPSE_BONES)
|
||||
// only specific bones
|
||||
CharacterDatabase.PExecute("DELETE FROM corpse WHERE guid = '%d'", GetGUIDLow());
|
||||
else
|
||||
// all corpses (not bones)
|
||||
CharacterDatabase.PExecute("DELETE FROM corpse WHERE player = '%d' AND corpse_type <> '0'", GUID_LOPART(GetOwnerGUID()));
|
||||
}
|
||||
|
||||
/*
|
||||
bool Corpse::LoadFromDB(uint32 guid, QueryResult *result, uint32 InstanceId)
|
||||
{
|
||||
bool external = (result != NULL);
|
||||
if (!external)
|
||||
// 0 1 2 3 4 5 6 7 8 9
|
||||
result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map,data,time,corpse_type,instance,phaseMask FROM corpse WHERE guid = '%u'",guid);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
sLog.outError("Corpse (GUID: %u) not found in table `corpse`, can't load. ",guid);
|
||||
return false;
|
||||
}
|
||||
|
||||
Field *fields = result->Fetch();
|
||||
|
||||
if (!LoadFromDB(guid, fields))
|
||||
{
|
||||
if (!external)
|
||||
delete result;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!external)
|
||||
delete result;
|
||||
|
||||
return true;
|
||||
}*/
|
||||
|
||||
bool Corpse::LoadFromDB(uint32 guid, Field *fields)
|
||||
{
|
||||
float positionX = fields[0].GetFloat();
|
||||
float positionY = fields[1].GetFloat();
|
||||
float positionZ = fields[2].GetFloat();
|
||||
float ort = fields[3].GetFloat();
|
||||
uint32 mapid = fields[4].GetUInt32();
|
||||
|
||||
Object::_Create(guid, 0, HIGHGUID_CORPSE);
|
||||
|
||||
if (!LoadValues(fields[5].GetString()))
|
||||
{
|
||||
sLog.outError("Corpse #%d have broken data in `data` field. Can't be loaded.",guid);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_time = time_t(fields[6].GetUInt64());
|
||||
m_type = CorpseType(fields[7].GetUInt32());
|
||||
|
||||
if (m_type >= MAX_CORPSE_TYPE)
|
||||
{
|
||||
sLog.outError("Corpse (guidlow %d, owner %d) have wrong corpse type, not load.",GetGUIDLow(),GUID_LOPART(GetOwnerGUID()));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_type != CORPSE_BONES)
|
||||
m_isWorldObject = true;
|
||||
|
||||
uint32 instanceid = fields[8].GetUInt32();
|
||||
|
||||
uint32 phaseMask = fields[9].GetUInt32();
|
||||
|
||||
// overwrite possible wrong/corrupted guid
|
||||
SetUInt64Value(OBJECT_FIELD_GUID, MAKE_NEW_GUID(guid, 0, HIGHGUID_CORPSE));
|
||||
|
||||
// place
|
||||
SetLocationInstanceId(instanceid);
|
||||
SetLocationMapId(mapid);
|
||||
SetPhaseMask(phaseMask, false);
|
||||
Relocate(positionX, positionY, positionZ, ort);
|
||||
|
||||
if (!IsPositionValid())
|
||||
{
|
||||
sLog.outError("Corpse (guidlow %d, owner %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
|
||||
GetGUIDLow(), GUID_LOPART(GetOwnerGUID()), GetPositionX(), GetPositionY());
|
||||
return false;
|
||||
}
|
||||
|
||||
m_grid = Trinity::ComputeGridPair(GetPositionX(), GetPositionY());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Corpse::isVisibleForInState(Player const* u, bool inVisibleList) const
|
||||
{
|
||||
return IsInWorld() && u->IsInWorld() && IsWithinDistInMap(u->m_seer, World::GetMaxVisibleDistanceForObject() + (inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef TRINITYCORE_CORPSE_H
|
||||
#define TRINITYCORE_CORPSE_H
|
||||
|
||||
#include "Object.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "GridDefines.h"
|
||||
#include "LootMgr.h"
|
||||
|
||||
enum CorpseType
|
||||
{
|
||||
CORPSE_BONES = 0,
|
||||
CORPSE_RESURRECTABLE_PVE = 1,
|
||||
CORPSE_RESURRECTABLE_PVP = 2
|
||||
};
|
||||
#define MAX_CORPSE_TYPE 3
|
||||
|
||||
// Value equal client resurrection dialog show radius.
|
||||
#define CORPSE_RECLAIM_RADIUS 39
|
||||
|
||||
enum CorpseFlags
|
||||
{
|
||||
CORPSE_FLAG_NONE = 0x00,
|
||||
CORPSE_FLAG_BONES = 0x01,
|
||||
CORPSE_FLAG_UNK1 = 0x02,
|
||||
CORPSE_FLAG_UNK2 = 0x04,
|
||||
CORPSE_FLAG_HIDE_HELM = 0x08,
|
||||
CORPSE_FLAG_HIDE_CLOAK = 0x10,
|
||||
CORPSE_FLAG_LOOTABLE = 0x20
|
||||
};
|
||||
|
||||
class Corpse : public WorldObject, public GridObject<Corpse>
|
||||
{
|
||||
public:
|
||||
explicit Corpse(CorpseType type = CORPSE_BONES);
|
||||
~Corpse();
|
||||
|
||||
void AddToWorld();
|
||||
void RemoveFromWorld();
|
||||
|
||||
bool Create(uint32 guidlow, Map *map);
|
||||
bool Create(uint32 guidlow, Player *owner);
|
||||
|
||||
void SaveToDB();
|
||||
//bool LoadFromDB(uint32 guid, QueryResult *result, uint32 InstanceId);
|
||||
bool LoadFromDB(uint32 guid, Field *fields);
|
||||
|
||||
void DeleteBonesFromWorld();
|
||||
void DeleteFromDB();
|
||||
|
||||
uint64 const& GetOwnerGUID() const { return GetUInt64Value(CORPSE_FIELD_OWNER); }
|
||||
|
||||
time_t const& GetGhostTime() const { return m_time; }
|
||||
void ResetGhostTime() { m_time = time(NULL); }
|
||||
CorpseType GetType() const { return m_type; }
|
||||
|
||||
GridPair const& GetGrid() const { return m_grid; }
|
||||
void SetGrid(GridPair const& grid) { m_grid = grid; }
|
||||
|
||||
bool isVisibleForInState(Player const* u, bool inVisibleList) const;
|
||||
|
||||
Loot loot; // remove insignia ONLY at BG
|
||||
Player* lootRecipient;
|
||||
bool lootForBody;
|
||||
|
||||
void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); }
|
||||
void Yell(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYell(textId,language,TargetGuid); }
|
||||
void TextEmote(int32 textId, uint64 TargetGuid) { MonsterTextEmote(textId,TargetGuid); }
|
||||
void Whisper(int32 textId,uint64 receiver) { MonsterWhisper(textId,receiver); }
|
||||
void YellToZone(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYellToZone(textId,language,TargetGuid); }
|
||||
|
||||
private:
|
||||
CorpseType m_type;
|
||||
time_t m_time;
|
||||
GridPair m_grid; // gride for corpse position for fast search
|
||||
};
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,738 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef TRINITYCORE_CREATURE_H
|
||||
#define TRINITYCORE_CREATURE_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "Unit.h"
|
||||
#include "UpdateMask.h"
|
||||
#include "ItemPrototype.h"
|
||||
#include "LootMgr.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "Cell.h"
|
||||
|
||||
#include <list>
|
||||
|
||||
struct SpellEntry;
|
||||
|
||||
class CreatureAI;
|
||||
class Quest;
|
||||
class Player;
|
||||
class WorldSession;
|
||||
class CreatureGroup;
|
||||
|
||||
enum CreatureFlagsExtra
|
||||
{
|
||||
CREATURE_FLAG_EXTRA_INSTANCE_BIND = 0x00000001, // creature kill bind instance with killer and killer's group
|
||||
CREATURE_FLAG_EXTRA_CIVILIAN = 0x00000002, // not aggro (ignore faction/reputation hostility)
|
||||
CREATURE_FLAG_EXTRA_NO_PARRY = 0x00000004, // creature can't parry
|
||||
CREATURE_FLAG_EXTRA_NO_PARRY_HASTEN = 0x00000008, // creature can't counter-attack at parry
|
||||
CREATURE_FLAG_EXTRA_NO_BLOCK = 0x00000010, // creature can't block
|
||||
CREATURE_FLAG_EXTRA_NO_CRUSH = 0x00000020, // creature can't do crush attacks
|
||||
CREATURE_FLAG_EXTRA_NO_XP_AT_KILL = 0x00000040, // creature kill not provide XP
|
||||
CREATURE_FLAG_EXTRA_TRIGGER = 0x00000080, // trigger creature
|
||||
CREATURE_FLAG_EXTRA_NO_TAUNT = 0x00000100, // creature is immune to taunt auras and effect attack me
|
||||
CREATURE_FLAG_EXTRA_WORLDEVENT = 0x00004000, // custom flag for world event creatures (left room for merging)
|
||||
//CREATURE_FLAG_EXTRA_CHARM_AI = 0x00008000, // use ai when charmed
|
||||
CREATURE_FLAG_EXTRA_NO_CRIT = 0x00020000, // creature can't do critical strikes
|
||||
CREATURE_FLAG_EXTRA_NO_SKILLGAIN = 0x00040000, // creature won't increase weapon skills
|
||||
CREATURE_FLAG_EXTRA_TAUNT_DIMINISH = 0x00080000, // Taunt is a subject to diminishing returns on this creautre
|
||||
CREATURE_FLAG_EXTRA_ALL_DIMINISH = 0x00100000, // Creature is subject to all diminishing returns as player are
|
||||
};
|
||||
|
||||
// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform
|
||||
#if defined(__GNUC__)
|
||||
#pragma pack(1)
|
||||
#else
|
||||
#pragma pack(push,1)
|
||||
#endif
|
||||
|
||||
#define MAX_KILL_CREDIT 2
|
||||
#define CREATURE_REGEN_INTERVAL 2 * IN_MILISECONDS
|
||||
|
||||
// from `creature_template` table
|
||||
struct CreatureInfo
|
||||
{
|
||||
uint32 Entry;
|
||||
uint32 DifficultyEntry[MAX_DIFFICULTY - 1];
|
||||
uint32 KillCredit[MAX_KILL_CREDIT];
|
||||
uint32 Modelid1;
|
||||
uint32 Modelid2;
|
||||
uint32 Modelid3;
|
||||
uint32 Modelid4;
|
||||
char* Name;
|
||||
char* SubName;
|
||||
char* IconName;
|
||||
uint32 GossipMenuId;
|
||||
uint8 minlevel;
|
||||
uint8 maxlevel;
|
||||
uint32 expansion;
|
||||
uint32 faction_A;
|
||||
uint32 faction_H;
|
||||
uint32 npcflag;
|
||||
float speed_walk;
|
||||
float speed_run;
|
||||
float scale;
|
||||
uint32 rank;
|
||||
float mindmg;
|
||||
float maxdmg;
|
||||
uint32 dmgschool;
|
||||
uint32 attackpower;
|
||||
float dmg_multiplier;
|
||||
uint32 baseattacktime;
|
||||
uint32 rangeattacktime;
|
||||
uint32 unit_class; // enum Classes. Note only 4 classes are known for creatures.
|
||||
uint32 unit_flags; // enum UnitFlags mask values
|
||||
uint32 dynamicflags;
|
||||
uint32 family; // enum CreatureFamily values (optional)
|
||||
uint32 trainer_type;
|
||||
uint32 trainer_spell;
|
||||
uint32 trainer_class;
|
||||
uint32 trainer_race;
|
||||
float minrangedmg;
|
||||
float maxrangedmg;
|
||||
uint32 rangedattackpower;
|
||||
uint32 type; // enum CreatureType values
|
||||
uint32 type_flags; // enum CreatureTypeFlags mask values
|
||||
uint32 lootid;
|
||||
uint32 pickpocketLootId;
|
||||
uint32 SkinLootId;
|
||||
int32 resistance1;
|
||||
int32 resistance2;
|
||||
int32 resistance3;
|
||||
int32 resistance4;
|
||||
int32 resistance5;
|
||||
int32 resistance6;
|
||||
uint32 spells[CREATURE_MAX_SPELLS];
|
||||
uint32 PetSpellDataId;
|
||||
uint32 VehicleId;
|
||||
uint32 mingold;
|
||||
uint32 maxgold;
|
||||
char const* AIName;
|
||||
uint32 MovementType;
|
||||
uint32 InhabitType;
|
||||
float ModHealth;
|
||||
float ModMana;
|
||||
float ModArmor;
|
||||
bool RacialLeader;
|
||||
uint32 questItems[6];
|
||||
uint32 movementId;
|
||||
bool RegenHealth;
|
||||
uint32 equipmentId;
|
||||
uint32 MechanicImmuneMask;
|
||||
uint32 flags_extra;
|
||||
uint32 ScriptID;
|
||||
uint32 GetRandomValidModelId() const;
|
||||
uint32 GetFirstValidModelId() const;
|
||||
|
||||
// helpers
|
||||
SkillType GetRequiredLootSkill() const
|
||||
{
|
||||
if (type_flags & CREATURE_TYPEFLAGS_HERBLOOT)
|
||||
return SKILL_HERBALISM;
|
||||
else if (type_flags & CREATURE_TYPEFLAGS_MININGLOOT)
|
||||
return SKILL_MINING;
|
||||
else if (type_flags & CREATURE_TYPEFLAGS_ENGINEERLOOT)
|
||||
return SKILL_ENGINERING;
|
||||
else
|
||||
return SKILL_SKINNING; // normal case
|
||||
}
|
||||
|
||||
bool isTameable(bool exotic) const
|
||||
{
|
||||
if (type != CREATURE_TYPE_BEAST || family == 0 || (type_flags & CREATURE_TYPEFLAGS_TAMEABLE) == 0)
|
||||
return false;
|
||||
|
||||
// if can tame exotic then can tame any temable
|
||||
return exotic || (type_flags & CREATURE_TYPEFLAGS_EXOTIC) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
// Represents max amount of expansions.
|
||||
// TODO: Add MAX_EXPANSION constant.
|
||||
#define MAX_CREATURE_BASE_HP 3
|
||||
|
||||
// Defines base stats for creatures (used to calculate HP/mana/armor).
|
||||
struct CreatureBaseStats
|
||||
{
|
||||
uint32 BaseHealth[MAX_CREATURE_BASE_HP];
|
||||
uint32 BaseMana;
|
||||
uint32 BaseArmor;
|
||||
|
||||
// Helpers
|
||||
|
||||
uint32 GenerateHealth(CreatureInfo const* info) const
|
||||
{
|
||||
return uint32((BaseHealth[info->expansion] * info->ModHealth) + 0.5f);
|
||||
}
|
||||
|
||||
uint32 GenerateMana(CreatureInfo const* info) const
|
||||
{
|
||||
// Mana can be 0.
|
||||
if (!BaseMana)
|
||||
return 0;
|
||||
|
||||
return uint32((BaseMana * info->ModMana) + 0.5f);
|
||||
}
|
||||
|
||||
uint32 GenerateArmor(CreatureInfo const* info) const
|
||||
{
|
||||
return uint32((BaseArmor * info->ModArmor) + 0.5f);
|
||||
}
|
||||
|
||||
static CreatureBaseStats const* GetBaseStats(uint8 level, uint8 unitClass);
|
||||
};
|
||||
|
||||
typedef UNORDERED_MAP<uint16, CreatureBaseStats> CreatureBaseStatsMap;
|
||||
|
||||
struct CreatureLocale
|
||||
{
|
||||
std::vector<std::string> Name;
|
||||
std::vector<std::string> SubName;
|
||||
};
|
||||
|
||||
struct GossipMenuItemsLocale
|
||||
{
|
||||
std::vector<std::string> OptionText;
|
||||
std::vector<std::string> BoxText;
|
||||
};
|
||||
|
||||
struct PointOfInterestLocale
|
||||
{
|
||||
std::vector<std::string> IconName;
|
||||
};
|
||||
|
||||
struct EquipmentInfo
|
||||
{
|
||||
uint32 entry;
|
||||
uint32 equipentry[3];
|
||||
};
|
||||
|
||||
// from `creature` table
|
||||
struct CreatureData
|
||||
{
|
||||
explicit CreatureData() : dbData(true) {}
|
||||
uint32 id; // entry in creature_template
|
||||
uint16 mapid;
|
||||
uint16 phaseMask;
|
||||
uint32 displayid;
|
||||
int32 equipmentId;
|
||||
float posX;
|
||||
float posY;
|
||||
float posZ;
|
||||
float orientation;
|
||||
uint32 spawntimesecs;
|
||||
float spawndist;
|
||||
uint32 currentwaypoint;
|
||||
uint32 curhealth;
|
||||
uint32 curmana;
|
||||
bool is_dead;
|
||||
uint8 movementType;
|
||||
uint8 spawnMask;
|
||||
bool dbData;
|
||||
};
|
||||
|
||||
struct CreatureDataAddonAura
|
||||
{
|
||||
uint32 spell_id;
|
||||
uint8 effectMask;
|
||||
};
|
||||
|
||||
// from `creature_addon` table
|
||||
struct CreatureDataAddon
|
||||
{
|
||||
uint32 guidOrEntry;
|
||||
uint32 path_id;
|
||||
uint32 mount;
|
||||
uint32 bytes1;
|
||||
uint32 bytes2;
|
||||
uint32 emote;
|
||||
CreatureDataAddonAura const* auras; // loaded as char* "spell1 eff1 spell2 eff2 ... "
|
||||
};
|
||||
|
||||
struct CreatureModelInfo
|
||||
{
|
||||
uint32 modelid;
|
||||
float bounding_radius;
|
||||
float combat_reach;
|
||||
uint8 gender;
|
||||
uint32 modelid_other_gender;
|
||||
};
|
||||
|
||||
enum InhabitTypeValues
|
||||
{
|
||||
INHABIT_GROUND = 1,
|
||||
INHABIT_WATER = 2,
|
||||
INHABIT_AIR = 4,
|
||||
INHABIT_ANYWHERE = INHABIT_GROUND | INHABIT_WATER | INHABIT_AIR
|
||||
};
|
||||
|
||||
// Enums used by StringTextData::Type (CreatureEventAI)
|
||||
enum ChatType
|
||||
{
|
||||
CHAT_TYPE_SAY = 0,
|
||||
CHAT_TYPE_YELL = 1,
|
||||
CHAT_TYPE_TEXT_EMOTE = 2,
|
||||
CHAT_TYPE_BOSS_EMOTE = 3,
|
||||
CHAT_TYPE_WHISPER = 4,
|
||||
CHAT_TYPE_BOSS_WHISPER = 5,
|
||||
CHAT_TYPE_ZONE_YELL = 6
|
||||
};
|
||||
|
||||
// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform
|
||||
#if defined(__GNUC__)
|
||||
#pragma pack()
|
||||
#else
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
// Vendors
|
||||
struct VendorItem
|
||||
{
|
||||
VendorItem(uint32 _item, int32 _maxcount, uint32 _incrtime, uint32 _ExtendedCost)
|
||||
: item(_item), maxcount(_maxcount), incrtime(_incrtime), ExtendedCost(_ExtendedCost) {}
|
||||
|
||||
uint32 item;
|
||||
int32 maxcount; // 0 for infinity item amount
|
||||
uint32 incrtime; // time for restore items amount if maxcount != 0
|
||||
uint32 ExtendedCost;
|
||||
};
|
||||
typedef std::vector<VendorItem*> VendorItemList;
|
||||
|
||||
struct VendorItemData
|
||||
{
|
||||
VendorItemList m_items;
|
||||
|
||||
VendorItem* GetItem(uint32 slot) const
|
||||
{
|
||||
if (slot >= m_items.size()) return NULL;
|
||||
return m_items[slot];
|
||||
}
|
||||
bool Empty() const { return m_items.empty(); }
|
||||
uint8 GetItemCount() const { return m_items.size(); }
|
||||
void AddItem(uint32 item, int32 maxcount, uint32 ptime, uint32 ExtendedCost)
|
||||
{
|
||||
m_items.push_back(new VendorItem(item, maxcount, ptime, ExtendedCost));
|
||||
}
|
||||
bool RemoveItem(uint32 item_id);
|
||||
VendorItem const* FindItemCostPair(uint32 item_id, uint32 extendedCost) const;
|
||||
void Clear()
|
||||
{
|
||||
for (VendorItemList::const_iterator itr = m_items.begin(); itr != m_items.end(); ++itr)
|
||||
delete (*itr);
|
||||
m_items.clear();
|
||||
}
|
||||
};
|
||||
|
||||
struct VendorItemCount
|
||||
{
|
||||
explicit VendorItemCount(uint32 _item, uint32 _count)
|
||||
: itemId(_item), count(_count), lastIncrementTime(time(NULL)) {}
|
||||
|
||||
uint32 itemId;
|
||||
uint32 count;
|
||||
time_t lastIncrementTime;
|
||||
};
|
||||
|
||||
typedef std::list<VendorItemCount> VendorItemCounts;
|
||||
|
||||
struct TrainerSpell
|
||||
{
|
||||
TrainerSpell() : spell(0), spellCost(0), reqSkill(0), reqSkillValue(0), reqLevel(0)
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_SPELL_EFFECTS ; ++i)
|
||||
learnedSpell[i] = 0;
|
||||
}
|
||||
|
||||
uint32 spell;
|
||||
uint32 spellCost;
|
||||
uint32 reqSkill;
|
||||
uint32 reqSkillValue;
|
||||
uint32 reqLevel;
|
||||
uint32 learnedSpell[3];
|
||||
|
||||
// helpers
|
||||
bool IsCastable() const { return learnedSpell[0] != spell; }
|
||||
};
|
||||
|
||||
typedef UNORDERED_MAP<uint32 /*spellid*/, TrainerSpell> TrainerSpellMap;
|
||||
|
||||
struct TrainerSpellData
|
||||
{
|
||||
TrainerSpellData() : trainerType(0) {}
|
||||
|
||||
TrainerSpellMap spellList;
|
||||
uint32 trainerType; // trainer type based at trainer spells, can be different from creature_template value.
|
||||
// req. for correct show non-prof. trainers like weaponmaster, allowed values 0 and 2.
|
||||
TrainerSpell const* Find(uint32 spell_id) const;
|
||||
void Clear() { spellList.clear(); }
|
||||
};
|
||||
|
||||
typedef std::map<uint32,time_t> CreatureSpellCooldowns;
|
||||
|
||||
// max different by z coordinate for creature aggro reaction
|
||||
#define CREATURE_Z_ATTACK_RANGE 3
|
||||
|
||||
#define MAX_VENDOR_ITEMS 150 // Limitation in 3.x.x item count in SMSG_LIST_INVENTORY
|
||||
|
||||
class Creature : public Unit, public GridObject<Creature>
|
||||
{
|
||||
public:
|
||||
|
||||
explicit Creature();
|
||||
virtual ~Creature();
|
||||
|
||||
void AddToWorld();
|
||||
void RemoveFromWorld();
|
||||
|
||||
void DisappearAndDie();
|
||||
|
||||
bool Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 vehId, uint32 team, float x, float y, float z, float ang, const CreatureData *data = NULL);
|
||||
bool LoadCreaturesAddon(bool reload = false);
|
||||
void SelectLevel(const CreatureInfo *cinfo);
|
||||
void LoadEquipment(uint32 equip_entry, bool force=false);
|
||||
|
||||
uint32 GetDBTableGUIDLow() const { return m_DBTableGuid; }
|
||||
char const* GetSubName() const { return GetCreatureInfo()->SubName; }
|
||||
|
||||
void Update(uint32 time); // overwrited Unit::Update
|
||||
void GetRespawnCoord(float &x, float &y, float &z, float* ori = NULL, float* dist =NULL) const;
|
||||
uint32 GetEquipmentId() const { return GetCreatureInfo()->equipmentId; }
|
||||
|
||||
void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; }
|
||||
bool isRacialLeader() const { return GetCreatureInfo()->RacialLeader; }
|
||||
bool isCivilian() const { return GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_CIVILIAN; }
|
||||
bool isTrigger() const { return GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER; }
|
||||
bool canWalk() const { return GetCreatureInfo()->InhabitType & INHABIT_GROUND; }
|
||||
bool canSwim() const { return GetCreatureInfo()->InhabitType & INHABIT_WATER; }
|
||||
//bool canFly() const { return GetCreatureInfo()->InhabitType & INHABIT_AIR; }
|
||||
void SetReactState(ReactStates st) { m_reactState = st; }
|
||||
ReactStates GetReactState() { return m_reactState; }
|
||||
bool HasReactState(ReactStates state) const { return (m_reactState == state); }
|
||||
///// TODO RENAME THIS!!!!!
|
||||
bool isCanTrainingOf(Player* player, bool msg) const;
|
||||
bool isCanInteractWithBattleMaster(Player* player, bool msg) const;
|
||||
bool isCanTrainingAndResetTalentsOf(Player* pPlayer) const;
|
||||
bool canCreatureAttack(Unit const *pVictim, bool force = true) const;
|
||||
bool IsImmunedToSpell(SpellEntry const* spellInfo);
|
||||
// redefine Unit::IsImmunedToSpell
|
||||
bool IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const;
|
||||
// redefine Unit::IsImmunedToSpellEffect
|
||||
bool isElite() const
|
||||
{
|
||||
if (isPet())
|
||||
return false;
|
||||
|
||||
uint32 rank = GetCreatureInfo()->rank;
|
||||
return rank != CREATURE_ELITE_NORMAL && rank != CREATURE_ELITE_RARE;
|
||||
}
|
||||
|
||||
bool isWorldBoss() const
|
||||
{
|
||||
if (isPet())
|
||||
return false;
|
||||
|
||||
return GetCreatureInfo()->rank == CREATURE_ELITE_WORLDBOSS;
|
||||
}
|
||||
|
||||
uint8 getLevelForTarget(Unit const* target) const; // overwrite Unit::getLevelForTarget for boss level support
|
||||
|
||||
bool IsInEvadeMode() const { return hasUnitState(UNIT_STAT_EVADE); }
|
||||
|
||||
bool AIM_Initialize(CreatureAI* ai = NULL);
|
||||
void Motion_Initialize();
|
||||
|
||||
void AI_SendMoveToPacket(float x, float y, float z, uint32 time, uint32 MovementFlags, uint8 type);
|
||||
CreatureAI * AI() const { return (CreatureAI*)i_AI; }
|
||||
|
||||
uint32 GetShieldBlockValue() const //dunno mob block value
|
||||
{
|
||||
return (getLevel()/2 + uint32(GetStat(STAT_STRENGTH)/20));
|
||||
}
|
||||
|
||||
SpellSchoolMask GetMeleeDamageSchoolMask() const { return m_meleeDamageSchoolMask; }
|
||||
void SetMeleeDamageSchool(SpellSchools school) { m_meleeDamageSchoolMask = SpellSchoolMask(1 << school); }
|
||||
|
||||
void _AddCreatureSpellCooldown(uint32 spell_id, time_t end_time);
|
||||
void _AddCreatureCategoryCooldown(uint32 category, time_t apply_time);
|
||||
void AddCreatureSpellCooldown(uint32 spellid);
|
||||
bool HasSpellCooldown(uint32 spell_id) const;
|
||||
bool HasCategoryCooldown(uint32 spell_id) const;
|
||||
|
||||
bool HasSpell(uint32 spellID) const;
|
||||
|
||||
bool UpdateEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data=NULL);
|
||||
bool UpdateStats(Stats stat);
|
||||
bool UpdateAllStats();
|
||||
void UpdateResistances(uint32 school);
|
||||
void UpdateArmor();
|
||||
void UpdateMaxHealth();
|
||||
void UpdateMaxPower(Powers power);
|
||||
void UpdateAttackPowerAndDamage(bool ranged = false);
|
||||
void UpdateDamagePhysical(WeaponAttackType attType);
|
||||
uint32 GetCurrentEquipmentId() { return m_equipmentId; }
|
||||
float GetSpellDamageMod(int32 Rank);
|
||||
|
||||
VendorItemData const* GetVendorItems() const;
|
||||
uint32 GetVendorItemCurrentCount(VendorItem const* vItem);
|
||||
uint32 UpdateVendorItemCurrentCount(VendorItem const* vItem, uint32 used_count);
|
||||
|
||||
TrainerSpellData const* GetTrainerSpells() const;
|
||||
|
||||
CreatureInfo const *GetCreatureInfo() const { return m_creatureInfo; }
|
||||
CreatureData const *GetCreatureData() const { return m_creatureData; }
|
||||
CreatureDataAddon const* GetCreatureAddon() const;
|
||||
|
||||
std::string GetAIName() const;
|
||||
std::string GetScriptName() const;
|
||||
uint32 GetScriptId() const;
|
||||
|
||||
void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); }
|
||||
void Yell(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYell(textId,language,TargetGuid); }
|
||||
void TextEmote(int32 textId, uint64 TargetGuid, bool IsBossEmote = false) { MonsterTextEmote(textId,TargetGuid,IsBossEmote); }
|
||||
void Whisper(int32 textId, uint64 receiver, bool IsBossWhisper = false) { MonsterWhisper(textId,receiver,IsBossWhisper); }
|
||||
void YellToZone(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYellToZone(textId,language,TargetGuid); }
|
||||
|
||||
// overwrite WorldObject function for proper name localization
|
||||
const char* GetNameForLocaleIdx(int32 locale_idx) const;
|
||||
|
||||
void setDeathState(DeathState s); // overwrite virtual Unit::setDeathState
|
||||
bool FallGround();
|
||||
|
||||
bool LoadFromDB(uint32 guid, Map *map);
|
||||
void SaveToDB();
|
||||
// overwrited in Pet
|
||||
virtual void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask);
|
||||
virtual void DeleteFromDB(); // overwrited in Pet
|
||||
|
||||
Loot loot;
|
||||
bool lootForPickPocketed;
|
||||
bool lootForBody;
|
||||
Player *GetLootRecipient() const;
|
||||
bool hasLootRecipient() const { return m_lootRecipient != 0; }
|
||||
bool isTappedBy(Player *player) const; // return true if the creature is tapped by the player or a member of his party.
|
||||
|
||||
void SetLootRecipient (Unit* unit);
|
||||
void AllLootRemovedFromCorpse();
|
||||
|
||||
uint16 GetLootMode() { return m_LootMode; }
|
||||
bool HasLootMode(uint16 lootMode) { return m_LootMode & lootMode; }
|
||||
void SetLootMode(uint16 lootMode) { m_LootMode = lootMode; }
|
||||
void AddLootMode(uint16 lootMode) { m_LootMode |= lootMode; }
|
||||
void RemoveLootMode(uint16 lootMode) { m_LootMode &= ~lootMode; }
|
||||
void ResetLootMode() { m_LootMode = LOOT_MODE_DEFAULT; }
|
||||
|
||||
SpellEntry const *reachWithSpellAttack(Unit *pVictim);
|
||||
SpellEntry const *reachWithSpellCure(Unit *pVictim);
|
||||
|
||||
uint32 m_spells[CREATURE_MAX_SPELLS];
|
||||
CreatureSpellCooldowns m_CreatureSpellCooldowns;
|
||||
CreatureSpellCooldowns m_CreatureCategoryCooldowns;
|
||||
uint32 m_GlobalCooldown;
|
||||
|
||||
bool canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList = false, bool is3dDistance = true) const;
|
||||
bool canStartAttack(Unit const* u, bool force) const;
|
||||
float GetAttackDistance(Unit const* pl) const;
|
||||
|
||||
void SendAIReaction(AiReaction reactionType);
|
||||
|
||||
Unit* SelectNearestTarget(float dist = 0) const;
|
||||
Unit* SelectNearestTargetInAttackDistance(float dist = 0) const;
|
||||
|
||||
void DoFleeToGetAssistance();
|
||||
void CallForHelp(float fRadius);
|
||||
void CallAssistance();
|
||||
void SetNoCallAssistance(bool val) { m_AlreadyCallAssistance = val; }
|
||||
void SetNoSearchAssistance(bool val) { m_AlreadySearchedAssistance = val; }
|
||||
bool HasSearchedAssistance() { return m_AlreadySearchedAssistance; }
|
||||
bool CanAssistTo(const Unit* u, const Unit* enemy, bool checkfaction = true) const;
|
||||
bool _IsTargetAcceptable(const Unit* target) const;
|
||||
|
||||
MovementGeneratorType GetDefaultMovementType() const { return m_defaultMovementType; }
|
||||
void SetDefaultMovementType(MovementGeneratorType mgt) { m_defaultMovementType = mgt; }
|
||||
|
||||
// for use only in LoadHelper, Map::Add Map::CreatureCellRelocation
|
||||
Cell const& GetCurrentCell() const { return m_currentCell; }
|
||||
void SetCurrentCell(Cell const& cell) { m_currentCell = cell; }
|
||||
|
||||
bool IsVisibleInGridForPlayer(Player const* pl) const;
|
||||
|
||||
void RemoveCorpse();
|
||||
bool isDeadByDefault() const { return m_isDeadByDefault; };
|
||||
|
||||
void ForcedDespawn(uint32 timeMSToDespawn = 0);
|
||||
|
||||
time_t const& GetRespawnTime() const { return m_respawnTime; }
|
||||
time_t GetRespawnTimeEx() const;
|
||||
void SetRespawnTime(uint32 respawn) { m_respawnTime = respawn ? time(NULL) + respawn : 0; }
|
||||
void Respawn(bool force = false);
|
||||
void SaveRespawnTime();
|
||||
|
||||
uint32 GetRespawnDelay() const { return m_respawnDelay; }
|
||||
void SetRespawnDelay(uint32 delay) { m_respawnDelay = delay; }
|
||||
|
||||
float GetRespawnRadius() const { return m_respawnradius; }
|
||||
void SetRespawnRadius(float dist) { m_respawnradius = dist; }
|
||||
|
||||
// Linked Creature Respawning System
|
||||
time_t GetLinkedCreatureRespawnTime() const;
|
||||
const CreatureData* GetLinkedRespawnCreatureData() const;
|
||||
|
||||
uint32 m_groupLootTimer; // (msecs)timer used for group loot
|
||||
uint64 lootingGroupGUID; // used to find group which is looting corpse
|
||||
|
||||
void SendZoneUnderAttackMessage(Player* attacker);
|
||||
|
||||
void SetInCombatWithZone();
|
||||
|
||||
bool hasQuest(uint32 quest_id) const;
|
||||
bool hasInvolvedQuest(uint32 quest_id) const;
|
||||
|
||||
bool isRegeneratingHealth() { return m_regenHealth; }
|
||||
virtual uint8 GetPetAutoSpellSize() const { return CREATURE_MAX_SPELLS; }
|
||||
virtual uint32 GetPetAutoSpellOnPos(uint8 pos) const
|
||||
{
|
||||
if (pos >= CREATURE_MAX_SPELLS || m_charmInfo->GetCharmSpell(pos)->GetType() != ACT_ENABLED)
|
||||
return 0;
|
||||
else
|
||||
return m_charmInfo->GetCharmSpell(pos)->GetAction();
|
||||
}
|
||||
|
||||
void SetHomePosition(float x, float y, float z, float o) { m_homePosition.Relocate(x, y, z, o); }
|
||||
void SetHomePosition(const Position &pos) { m_homePosition.Relocate(pos); }
|
||||
void GetHomePosition(float &x, float &y, float &z, float &ori) { m_homePosition.GetPosition(x, y, z, ori); }
|
||||
Position GetHomePosition() { return m_homePosition; }
|
||||
|
||||
uint32 GetGlobalCooldown() const { return m_GlobalCooldown; }
|
||||
|
||||
uint32 GetWaypointPath(){return m_path_id;}
|
||||
void LoadPath(uint32 pathid) { m_path_id = pathid; }
|
||||
|
||||
uint32 GetCurrentWaypointID(){return m_waypointID;}
|
||||
void UpdateWaypointID(uint32 wpID){m_waypointID = wpID;}
|
||||
|
||||
void SearchFormation();
|
||||
CreatureGroup *GetFormation() {return m_formation;}
|
||||
void SetFormation(CreatureGroup *formation) {m_formation = formation;}
|
||||
|
||||
Unit *SelectVictim();
|
||||
void SetDeadByDefault (bool death_state) {m_isDeadByDefault = death_state;}
|
||||
|
||||
void SetDisableReputationGain(bool disable) { DisableReputationGain = disable; }
|
||||
bool IsReputationGainDisabled() { return DisableReputationGain; }
|
||||
bool IsDamageEnoughForLootingAndReward() const { return m_PlayerDamageReq == 0; }
|
||||
void LowerPlayerDamageReq(uint32 unDamage)
|
||||
{
|
||||
if (m_PlayerDamageReq)
|
||||
m_PlayerDamageReq > unDamage ? m_PlayerDamageReq -= unDamage : m_PlayerDamageReq = 0;
|
||||
}
|
||||
void ResetPlayerDamageReq() { m_PlayerDamageReq = GetHealth() / 2; }
|
||||
uint32 m_PlayerDamageReq;
|
||||
|
||||
void SetOriginalEntry(uint32 entry) { m_originalEntry = entry; }
|
||||
|
||||
static float _GetDamageMod(int32 Rank);
|
||||
|
||||
float m_SightDistance, m_CombatDistance;
|
||||
|
||||
protected:
|
||||
bool CreateFromProto(uint32 guidlow, uint32 Entry, uint32 vehId, uint32 team, const CreatureData *data = NULL);
|
||||
bool InitEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data=NULL);
|
||||
|
||||
// vendor items
|
||||
VendorItemCounts m_vendorItemCounts;
|
||||
|
||||
void _RealtimeSetCreatureInfo();
|
||||
|
||||
static float _GetHealthMod(int32 Rank);
|
||||
|
||||
uint32 m_lootMoney;
|
||||
uint64 m_lootRecipient;
|
||||
|
||||
/// Timers
|
||||
uint32 m_deathTimer; // (msecs)timer for death or corpse disappearance
|
||||
time_t m_respawnTime; // (secs) time of next respawn
|
||||
uint32 m_respawnDelay; // (secs) delay between corpse disappearance and respawning
|
||||
uint32 m_corpseDelay; // (secs) delay between death and corpse disappearance
|
||||
float m_respawnradius;
|
||||
|
||||
ReactStates m_reactState; // for AI, not charmInfo
|
||||
void RegenerateMana();
|
||||
void RegenerateHealth();
|
||||
void Regenerate(Powers power);
|
||||
MovementGeneratorType m_defaultMovementType;
|
||||
Cell m_currentCell; // store current cell where creature listed
|
||||
uint32 m_DBTableGuid; ///< For new or temporary creatures is 0 for saved it is lowguid
|
||||
uint32 m_equipmentId;
|
||||
|
||||
bool m_AlreadyCallAssistance;
|
||||
bool m_AlreadySearchedAssistance;
|
||||
bool m_regenHealth;
|
||||
bool m_AI_locked;
|
||||
bool m_isDeadByDefault;
|
||||
|
||||
SpellSchoolMask m_meleeDamageSchoolMask;
|
||||
uint32 m_originalEntry;
|
||||
|
||||
Position m_homePosition;
|
||||
|
||||
bool DisableReputationGain;
|
||||
|
||||
CreatureInfo const* m_creatureInfo; // in difficulty mode > 0 can different from ObjMgr::GetCreatureTemplate(GetEntry())
|
||||
CreatureData const* m_creatureData;
|
||||
|
||||
uint16 m_LootMode; // bitmask, default LOOT_MODE_DEFAULT, determines what loot will be lootable
|
||||
|
||||
private:
|
||||
//WaypointMovementGenerator vars
|
||||
uint32 m_waypointID;
|
||||
uint32 m_path_id;
|
||||
|
||||
//Formation var
|
||||
CreatureGroup *m_formation;
|
||||
};
|
||||
|
||||
class AssistDelayEvent : public BasicEvent
|
||||
{
|
||||
public:
|
||||
AssistDelayEvent(const uint64& victim, Unit& owner) : BasicEvent(), m_victim(victim), m_owner(owner) { }
|
||||
|
||||
bool Execute(uint64 e_time, uint32 p_time);
|
||||
void AddAssistant(const uint64& guid) { m_assistants.push_back(guid); }
|
||||
private:
|
||||
AssistDelayEvent();
|
||||
|
||||
uint64 m_victim;
|
||||
std::list<uint64> m_assistants;
|
||||
Unit& m_owner;
|
||||
};
|
||||
|
||||
class ForcedDespawnDelayEvent : public BasicEvent
|
||||
{
|
||||
public:
|
||||
ForcedDespawnDelayEvent(Creature& owner) : BasicEvent(), m_owner(owner) { }
|
||||
bool Execute(uint64 e_time, uint32 p_time);
|
||||
|
||||
private:
|
||||
Creature& m_owner;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "CreatureAI.h"
|
||||
#include "CreatureAIImpl.h"
|
||||
#include "Creature.h"
|
||||
#include "World.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "Vehicle.h"
|
||||
|
||||
//Disable CreatureAI when charmed
|
||||
void CreatureAI::OnCharmed(bool /*apply*/)
|
||||
{
|
||||
//me->IsAIEnabled = !apply;*/
|
||||
me->NeedChangeAI = true;
|
||||
me->IsAIEnabled = false;
|
||||
}
|
||||
|
||||
AISpellInfoType * UnitAI::AISpellInfo;
|
||||
AISpellInfoType * GetAISpellInfo(uint32 i) { return &CreatureAI::AISpellInfo[i]; }
|
||||
|
||||
void CreatureAI::DoZoneInCombat(Creature* creature)
|
||||
{
|
||||
if (!creature)
|
||||
creature = me;
|
||||
|
||||
if (!creature->CanHaveThreatList())
|
||||
return;
|
||||
|
||||
Map *map = creature->GetMap();
|
||||
if (!map->IsDungeon()) //use IsDungeon instead of Instanceable, in case battlegrounds will be instantiated
|
||||
{
|
||||
sLog.outError("DoZoneInCombat call for map that isn't an instance (creature entry = %d)", creature->GetTypeId() == TYPEID_UNIT ? creature->ToCreature()->GetEntry() : 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!creature->HasReactState(REACT_PASSIVE) && !creature->getVictim())
|
||||
{
|
||||
if (Unit *target = creature->SelectNearestTarget(50))
|
||||
creature->AI()->AttackStart(target);
|
||||
else if (creature->isSummon())
|
||||
{
|
||||
if (Unit *summoner = creature->ToTempSummon()->GetSummoner())
|
||||
{
|
||||
Unit *target = summoner->getAttackerForHelper();
|
||||
if (!target && summoner->CanHaveThreatList() && !summoner->getThreatManager().isThreatListEmpty())
|
||||
target = summoner->getThreatManager().getHostilTarget();
|
||||
if (target && (creature->IsFriendlyTo(summoner) || creature->IsHostileTo(target)))
|
||||
creature->AI()->AttackStart(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!creature->HasReactState(REACT_PASSIVE) && !creature->getVictim())
|
||||
{
|
||||
sLog.outError("DoZoneInCombat called for creature that has empty threat list (creature entry = %u)", creature->GetEntry());
|
||||
return;
|
||||
}
|
||||
|
||||
Map::PlayerList const &PlList = map->GetPlayers();
|
||||
|
||||
if (PlList.isEmpty())
|
||||
return;
|
||||
|
||||
for (Map::PlayerList::const_iterator i = PlList.begin(); i != PlList.end(); ++i)
|
||||
{
|
||||
if (Player* pPlayer = i->getSource())
|
||||
{
|
||||
if (pPlayer->isGameMaster())
|
||||
continue;
|
||||
|
||||
if (pPlayer->isAlive())
|
||||
{
|
||||
creature->SetInCombatWith(pPlayer);
|
||||
pPlayer->SetInCombatWith(creature);
|
||||
creature->AddThreat(pPlayer, 0.0f);
|
||||
}
|
||||
|
||||
/* Causes certain things to never leave the threat list (Priest Lightwell, etc):
|
||||
for (Unit::ControlList::const_iterator itr = pPlayer->m_Controlled.begin(); itr != pPlayer->m_Controlled.end(); ++itr)
|
||||
{
|
||||
creature->SetInCombatWith(*itr);
|
||||
(*itr)->SetInCombatWith(creature);
|
||||
creature->AddThreat(*itr, 0.0f);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// scripts does not take care about MoveInLineOfSight loops
|
||||
// MoveInLineOfSight can be called inside another MoveInLineOfSight and cause stack overflow
|
||||
void CreatureAI::MoveInLineOfSight_Safe(Unit *who)
|
||||
{
|
||||
if (m_MoveInLineOfSight_locked == true)
|
||||
return;
|
||||
m_MoveInLineOfSight_locked = true;
|
||||
MoveInLineOfSight(who);
|
||||
m_MoveInLineOfSight_locked = false;
|
||||
}
|
||||
|
||||
void CreatureAI::MoveInLineOfSight(Unit *who)
|
||||
{
|
||||
if (me->getVictim())
|
||||
return;
|
||||
|
||||
if (me->GetCreatureType() == CREATURE_TYPE_NON_COMBAT_PET) // non-combat pets should just stand there and look good;)
|
||||
return;
|
||||
|
||||
if (me->canStartAttack(who, false))
|
||||
AttackStart(who);
|
||||
//else if (who->getVictim() && me->IsFriendlyTo(who)
|
||||
// && me->IsWithinDistInMap(who, sWorld.getConfig(CONFIG_CREATURE_FAMILY_ASSISTANCE_RADIUS))
|
||||
// && me->canStartAttack(who->getVictim(), true)) // TODO: if we use true, it will not attack it when it arrives
|
||||
// me->GetMotionMaster()->MoveChase(who->getVictim());
|
||||
}
|
||||
|
||||
void CreatureAI::EnterEvadeMode()
|
||||
{
|
||||
if (!_EnterEvadeMode())
|
||||
return;
|
||||
|
||||
sLog.outDebug("Creature %u enters evade mode.", me->GetEntry());
|
||||
|
||||
if (!me->GetVehicle()) // otherwise me will be in evade mode forever
|
||||
{
|
||||
if (Unit *owner = me->GetCharmerOrOwner())
|
||||
{
|
||||
me->GetMotionMaster()->Clear(false);
|
||||
me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, me->GetFollowAngle(), MOTION_SLOT_ACTIVE);
|
||||
}
|
||||
else
|
||||
me->GetMotionMaster()->MoveTargetedHome();
|
||||
}
|
||||
|
||||
Reset();
|
||||
|
||||
if (me->IsVehicle()) // use the same sequence of addtoworld, aireset may remove all summons!
|
||||
me->GetVehicleKit()->Reset();
|
||||
}
|
||||
|
||||
/*void CreatureAI::AttackedBy(Unit* attacker)
|
||||
{
|
||||
if (!me->getVictim())
|
||||
AttackStart(attacker);
|
||||
}*/
|
||||
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_CREATUREAI_H
|
||||
#define TRINITY_CREATUREAI_H
|
||||
|
||||
#include "UnitAI.h"
|
||||
#include "Common.h"
|
||||
|
||||
class WorldObject;
|
||||
class Unit;
|
||||
class Creature;
|
||||
class Player;
|
||||
struct SpellEntry;
|
||||
|
||||
#define TIME_INTERVAL_LOOK 5000
|
||||
#define VISIBILITY_RANGE 10000
|
||||
|
||||
//Spell targets used by SelectSpell
|
||||
enum SelectTargetType
|
||||
{
|
||||
SELECT_TARGET_DONTCARE = 0, //All target types allowed
|
||||
|
||||
SELECT_TARGET_SELF, //Only Self casting
|
||||
|
||||
SELECT_TARGET_SINGLE_ENEMY, //Only Single Enemy
|
||||
SELECT_TARGET_AOE_ENEMY, //Only AoE Enemy
|
||||
SELECT_TARGET_ANY_ENEMY, //AoE or Single Enemy
|
||||
|
||||
SELECT_TARGET_SINGLE_FRIEND, //Only Single Friend
|
||||
SELECT_TARGET_AOE_FRIEND, //Only AoE Friend
|
||||
SELECT_TARGET_ANY_FRIEND, //AoE or Single Friend
|
||||
};
|
||||
|
||||
//Spell Effects used by SelectSpell
|
||||
enum SelectEffect
|
||||
{
|
||||
SELECT_EFFECT_DONTCARE = 0, //All spell effects allowed
|
||||
SELECT_EFFECT_DAMAGE, //Spell does damage
|
||||
SELECT_EFFECT_HEALING, //Spell does healing
|
||||
SELECT_EFFECT_AURA, //Spell applies an aura
|
||||
};
|
||||
|
||||
enum SCEquip
|
||||
{
|
||||
EQUIP_NO_CHANGE = -1,
|
||||
EQUIP_UNEQUIP = 0
|
||||
};
|
||||
|
||||
class CreatureAI : public UnitAI
|
||||
{
|
||||
protected:
|
||||
Creature * const me;
|
||||
|
||||
bool UpdateVictim();
|
||||
bool UpdateVictimWithGaze();
|
||||
bool UpdateCombatState();
|
||||
|
||||
void SetGazeOn(Unit *target);
|
||||
|
||||
Creature *DoSummon(uint32 uiEntry, const Position &pos, uint32 uiDespawntime = 30000, TempSummonType uiType = TEMPSUMMON_CORPSE_TIMED_DESPAWN);
|
||||
Creature *DoSummon(uint32 uiEntry, WorldObject *obj, float fRadius = 5.0f, uint32 uiDespawntime = 30000, TempSummonType uiType = TEMPSUMMON_CORPSE_TIMED_DESPAWN);
|
||||
Creature *DoSummonFlyer(uint32 uiEntry, WorldObject *obj, float fZ, float fRadius = 5.0f, uint32 uiDespawntime = 30000, TempSummonType uiType = TEMPSUMMON_CORPSE_TIMED_DESPAWN);
|
||||
|
||||
public:
|
||||
explicit CreatureAI(Creature *c) : UnitAI((Unit*)c), me(c), m_MoveInLineOfSight_locked(false) {}
|
||||
|
||||
virtual ~CreatureAI() {}
|
||||
|
||||
/// == Reactions At =================================
|
||||
|
||||
// Called if IsVisible(Unit *who) is true at each *who move, reaction at visibility zone enter
|
||||
void MoveInLineOfSight_Safe(Unit *who);
|
||||
|
||||
// Called for reaction at stopping attack at no attackers or targets
|
||||
virtual void EnterEvadeMode();
|
||||
|
||||
// Called for reaction at enter to combat if not in combat yet (enemy can be NULL)
|
||||
virtual void EnterCombat(Unit* /*enemy*/) {}
|
||||
|
||||
// Called at any Damage from any attacker (before damage apply)
|
||||
// Note: it for recalculation damage or special reaction at damage
|
||||
// for attack reaction use AttackedBy called for not DOT damage in Unit::DealDamage also
|
||||
virtual void DamageTaken(Unit * /*done_by*/, uint32 & /*damage*/) {}
|
||||
|
||||
// Called when the creature is killed
|
||||
virtual void JustDied(Unit *) {}
|
||||
|
||||
// Called when the creature kills a unit
|
||||
virtual void KilledUnit(Unit *) {}
|
||||
|
||||
// Called when the creature summon successfully other creature
|
||||
virtual void JustSummoned(Creature*) {}
|
||||
virtual void IsSummonedBy(Unit * /*summoner*/) {}
|
||||
|
||||
virtual void SummonedCreatureDespawn(Creature* /*unit*/) {}
|
||||
|
||||
// Called when hit by a spell
|
||||
virtual void SpellHit(Unit*, const SpellEntry*) {}
|
||||
|
||||
// Called when spell hits a target
|
||||
virtual void SpellHitTarget(Unit* /*target*/, const SpellEntry*) {}
|
||||
|
||||
// Called to get trigger target for aura effect
|
||||
virtual Unit * GetAuraEffectTriggerTarget(uint32 /*spellId*/, uint8 /*effIndex*/) {return NULL;}
|
||||
|
||||
// Called when the creature is target of hostile action: swing, hostile spell landed, fear/etc)
|
||||
//virtual void AttackedBy(Unit* attacker);
|
||||
virtual bool IsEscorted() { return false; }
|
||||
|
||||
// Called when creature is spawned or respawned (for reseting variables)
|
||||
virtual void JustRespawned() { Reset(); }
|
||||
|
||||
// Called at waypoint reached or point movement finished
|
||||
virtual void MovementInform(uint32 /*MovementType*/, uint32 /*Data*/) {}
|
||||
|
||||
void OnCharmed(bool apply);
|
||||
|
||||
//virtual void SpellClick(Player *player) {}
|
||||
|
||||
// Called at reaching home after evade
|
||||
virtual void JustReachedHome() {}
|
||||
|
||||
void DoZoneInCombat(Creature* pUnit = NULL);
|
||||
|
||||
// Called at text emote receive from player
|
||||
virtual void ReceiveEmote(Player* /*pPlayer*/, uint32 /*text_emote*/) {}
|
||||
|
||||
/// == Triggered Actions Requested ==================
|
||||
|
||||
// Called when creature attack expected (if creature can and no have current victim)
|
||||
// Note: for reaction at hostile action must be called AttackedBy function.
|
||||
//virtual void AttackStart(Unit *) {}
|
||||
|
||||
// Called at World update tick
|
||||
//virtual void UpdateAI(const uint32 /*diff*/) {}
|
||||
|
||||
/// == State checks =================================
|
||||
|
||||
// Is unit visible for MoveInLineOfSight
|
||||
//virtual bool IsVisible(Unit *) const { return false; }
|
||||
|
||||
// called when the corpse of this creature gets removed
|
||||
virtual void CorpseRemoved(uint32 & /*respawnDelay*/) {}
|
||||
|
||||
// Called when victim entered water and creature can not enter water
|
||||
//virtual bool canReachByRangeAttack(Unit*) { return false; }
|
||||
|
||||
/// == Fields =======================================
|
||||
|
||||
// Pointer to controlled by AI creature
|
||||
//Creature* const me;
|
||||
|
||||
virtual void PassengerBoarded(Unit * /*who*/, int8 /*seatId*/, bool /*apply*/) {}
|
||||
|
||||
protected:
|
||||
virtual void MoveInLineOfSight(Unit *);
|
||||
|
||||
bool _EnterEvadeMode();
|
||||
|
||||
private:
|
||||
bool m_MoveInLineOfSight_locked;
|
||||
};
|
||||
|
||||
enum Permitions
|
||||
{
|
||||
PERMIT_BASE_NO = -1,
|
||||
PERMIT_BASE_IDLE = 1,
|
||||
PERMIT_BASE_REACTIVE = 100,
|
||||
PERMIT_BASE_PROACTIVE = 200,
|
||||
PERMIT_BASE_FACTION_SPECIFIC = 400,
|
||||
PERMIT_BASE_SPECIAL = 800
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef TRINITY_CREATUREAIFACTORY_H
|
||||
#define TRINITY_CREATUREAIFACTORY_H
|
||||
|
||||
//#include "Policies/Singleton.h"
|
||||
#include "Dynamic/ObjectRegistry.h"
|
||||
#include "Dynamic/FactoryHolder.h"
|
||||
|
||||
struct SelectableAI : public FactoryHolder<CreatureAI>, public Permissible<Creature>
|
||||
{
|
||||
SelectableAI(const char *id) : FactoryHolder<CreatureAI>(id) {}
|
||||
};
|
||||
|
||||
template<class REAL_AI>
|
||||
struct CreatureAIFactory : public SelectableAI
|
||||
{
|
||||
CreatureAIFactory(const char *name) : SelectableAI(name) {}
|
||||
|
||||
CreatureAI* Create(void *) const;
|
||||
|
||||
int Permit(const Creature *c) const { return REAL_AI::Permissible(c); }
|
||||
};
|
||||
|
||||
template<class REAL_AI>
|
||||
inline CreatureAI*
|
||||
CreatureAIFactory<REAL_AI>::Create(void *data) const
|
||||
{
|
||||
Creature* creature = reinterpret_cast<Creature *>(data);
|
||||
return (new REAL_AI(creature));
|
||||
}
|
||||
|
||||
typedef FactoryHolder<CreatureAI> CreatureAICreator;
|
||||
typedef FactoryHolder<CreatureAI>::FactoryHolderRegistry CreatureAIRegistry;
|
||||
typedef FactoryHolder<CreatureAI>::FactoryHolderRepository CreatureAIRepository;
|
||||
#endif
|
||||
@@ -0,0 +1,638 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef CREATUREAIIMPL_H
|
||||
#define CREATUREAIIMPL_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "Platform/Define.h"
|
||||
#include "TemporarySummon.h"
|
||||
#include "CreatureAI.h"
|
||||
#include "SpellMgr.h"
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
const T& RAND(const T& v1, const T& v2)
|
||||
{
|
||||
return (urand(0,1)) ? v1 : v2;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
const T& RAND(const T& v1, const T& v2, const T& v3)
|
||||
{
|
||||
switch (urand(0,2))
|
||||
{
|
||||
default:
|
||||
case 0: return v1;
|
||||
case 1: return v2;
|
||||
case 2: return v3;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4)
|
||||
{
|
||||
switch (urand(0,3))
|
||||
{
|
||||
default:
|
||||
case 0: return v1;
|
||||
case 1: return v2;
|
||||
case 2: return v3;
|
||||
case 3: return v4;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5)
|
||||
{
|
||||
switch (urand(0,4))
|
||||
{
|
||||
default:
|
||||
case 0: return v1;
|
||||
case 1: return v2;
|
||||
case 2: return v3;
|
||||
case 3: return v4;
|
||||
case 4: return v5;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6)
|
||||
{
|
||||
switch (urand(0,5))
|
||||
{
|
||||
default:
|
||||
case 0: return v1;
|
||||
case 1: return v2;
|
||||
case 2: return v3;
|
||||
case 3: return v4;
|
||||
case 4: return v5;
|
||||
case 5: return v6;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7)
|
||||
{
|
||||
switch (urand(0,6))
|
||||
{
|
||||
default:
|
||||
case 0: return v1;
|
||||
case 1: return v2;
|
||||
case 2: return v3;
|
||||
case 3: return v4;
|
||||
case 4: return v5;
|
||||
case 5: return v6;
|
||||
case 6: return v7;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8)
|
||||
{
|
||||
switch (urand(0,7))
|
||||
{
|
||||
default:
|
||||
case 0: return v1;
|
||||
case 1: return v2;
|
||||
case 2: return v3;
|
||||
case 3: return v4;
|
||||
case 4: return v5;
|
||||
case 5: return v6;
|
||||
case 6: return v7;
|
||||
case 7: return v8;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
|
||||
const T& v9)
|
||||
{
|
||||
switch (urand(0,8))
|
||||
{
|
||||
default:
|
||||
case 0: return v1;
|
||||
case 1: return v2;
|
||||
case 2: return v3;
|
||||
case 3: return v4;
|
||||
case 4: return v5;
|
||||
case 5: return v6;
|
||||
case 6: return v7;
|
||||
case 7: return v8;
|
||||
case 8: return v9;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
|
||||
const T& v9, const T& v10)
|
||||
{
|
||||
switch (urand(0,9))
|
||||
{
|
||||
default:
|
||||
case 0: return v1;
|
||||
case 1: return v2;
|
||||
case 2: return v3;
|
||||
case 3: return v4;
|
||||
case 4: return v5;
|
||||
case 5: return v6;
|
||||
case 6: return v7;
|
||||
case 7: return v8;
|
||||
case 8: return v9;
|
||||
case 9: return v10;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
|
||||
const T& v9, const T& v10, const T& v11)
|
||||
{
|
||||
switch (urand(0,10))
|
||||
{
|
||||
default:
|
||||
case 0: return v1;
|
||||
case 1: return v2;
|
||||
case 2: return v3;
|
||||
case 3: return v4;
|
||||
case 4: return v5;
|
||||
case 5: return v6;
|
||||
case 6: return v7;
|
||||
case 7: return v8;
|
||||
case 8: return v9;
|
||||
case 9: return v10;
|
||||
case 10: return v11;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
|
||||
const T& v9, const T& v10, const T& v11, const T& v12)
|
||||
{
|
||||
switch (urand(0,11))
|
||||
{
|
||||
default:
|
||||
case 0: return v1;
|
||||
case 1: return v2;
|
||||
case 2: return v3;
|
||||
case 3: return v4;
|
||||
case 4: return v5;
|
||||
case 5: return v6;
|
||||
case 6: return v7;
|
||||
case 7: return v8;
|
||||
case 8: return v9;
|
||||
case 9: return v10;
|
||||
case 10: return v11;
|
||||
case 11: return v12;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
|
||||
const T& v9, const T& v10, const T& v11, const T& v12, const T& v13)
|
||||
{
|
||||
switch (urand(0,12))
|
||||
{
|
||||
default:
|
||||
case 0: return v1;
|
||||
case 1: return v2;
|
||||
case 2: return v3;
|
||||
case 3: return v4;
|
||||
case 4: return v5;
|
||||
case 5: return v6;
|
||||
case 6: return v7;
|
||||
case 7: return v8;
|
||||
case 8: return v9;
|
||||
case 9: return v10;
|
||||
case 10: return v11;
|
||||
case 11: return v12;
|
||||
case 12: return v13;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
|
||||
const T& v9, const T& v10, const T& v11, const T& v12, const T& v13, const T& v14)
|
||||
{
|
||||
switch (urand(0,13))
|
||||
{
|
||||
default:
|
||||
case 0: return v1;
|
||||
case 1: return v2;
|
||||
case 2: return v3;
|
||||
case 3: return v4;
|
||||
case 4: return v5;
|
||||
case 5: return v6;
|
||||
case 6: return v7;
|
||||
case 7: return v8;
|
||||
case 8: return v9;
|
||||
case 9: return v10;
|
||||
case 10: return v11;
|
||||
case 11: return v12;
|
||||
case 12: return v13;
|
||||
case 13: return v14;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
|
||||
const T& v9, const T& v10, const T& v11, const T& v12, const T& v13, const T& v14, const T& v15)
|
||||
{
|
||||
switch (urand(0,14))
|
||||
{
|
||||
default:
|
||||
case 0: return v1;
|
||||
case 1: return v2;
|
||||
case 2: return v3;
|
||||
case 3: return v4;
|
||||
case 4: return v5;
|
||||
case 5: return v6;
|
||||
case 6: return v7;
|
||||
case 7: return v8;
|
||||
case 8: return v9;
|
||||
case 9: return v10;
|
||||
case 10: return v11;
|
||||
case 11: return v12;
|
||||
case 12: return v13;
|
||||
case 13: return v14;
|
||||
case 14: return v15;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
|
||||
const T& v9, const T& v10, const T& v11, const T& v12, const T& v13, const T& v14, const T& v15, const T& v16)
|
||||
{
|
||||
switch (urand(0,15))
|
||||
{
|
||||
default:
|
||||
case 0: return v1;
|
||||
case 1: return v2;
|
||||
case 2: return v3;
|
||||
case 3: return v4;
|
||||
case 4: return v5;
|
||||
case 5: return v6;
|
||||
case 6: return v7;
|
||||
case 7: return v8;
|
||||
case 8: return v9;
|
||||
case 9: return v10;
|
||||
case 10: return v11;
|
||||
case 11: return v12;
|
||||
case 12: return v13;
|
||||
case 13: return v14;
|
||||
case 14: return v15;
|
||||
case 15: return v16;
|
||||
}
|
||||
}
|
||||
|
||||
class EventMap : private std::map<uint32, uint32>
|
||||
{
|
||||
private:
|
||||
uint32 m_time, m_phase;
|
||||
public:
|
||||
explicit EventMap() : m_phase(0), m_time(0) {}
|
||||
|
||||
uint32 GetTimer() const { return m_time; }
|
||||
|
||||
void Reset() { clear(); m_time = 0; m_phase = 0; }
|
||||
|
||||
void Update(uint32 time) { m_time += time; }
|
||||
|
||||
void SetPhase(uint32 phase)
|
||||
{
|
||||
if (phase && phase < 9)
|
||||
m_phase = (1 << (phase + 24));
|
||||
}
|
||||
|
||||
void ScheduleEvent(uint32 eventId, uint32 time, uint32 gcd = 0, uint32 phase = 0)
|
||||
{
|
||||
time += m_time;
|
||||
if (gcd && gcd < 9)
|
||||
eventId |= (1 << (gcd + 16));
|
||||
if (phase && phase < 9)
|
||||
eventId |= (1 << (phase + 24));
|
||||
iterator itr = find(time);
|
||||
while (itr != end())
|
||||
{
|
||||
++time;
|
||||
itr = find(time);
|
||||
}
|
||||
insert(std::make_pair(time, eventId));
|
||||
}
|
||||
|
||||
void RescheduleEvent(uint32 eventId, uint32 time, uint32 gcd = 0, uint32 phase = 0)
|
||||
{
|
||||
CancelEvent(eventId);
|
||||
ScheduleEvent(eventId, time, gcd, phase);
|
||||
}
|
||||
|
||||
void RepeatEvent(uint32 time)
|
||||
{
|
||||
if (empty())
|
||||
return;
|
||||
uint32 eventId = begin()->second;
|
||||
erase(begin());
|
||||
time += m_time;
|
||||
iterator itr = find(time);
|
||||
while (itr != end())
|
||||
{
|
||||
++time;
|
||||
itr = find(time);
|
||||
}
|
||||
insert(std::make_pair(time, eventId));
|
||||
}
|
||||
|
||||
void PopEvent()
|
||||
{
|
||||
erase(begin());
|
||||
}
|
||||
|
||||
uint32 ExecuteEvent()
|
||||
{
|
||||
while (!empty())
|
||||
{
|
||||
if (begin()->first > m_time)
|
||||
return 0;
|
||||
else if (m_phase && (begin()->second & 0xFF000000) && !(begin()->second & m_phase))
|
||||
erase(begin());
|
||||
else
|
||||
{
|
||||
uint32 eventId = (begin()->second & 0x0000FFFF);
|
||||
erase(begin());
|
||||
return eventId;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 GetEvent()
|
||||
{
|
||||
while (!empty())
|
||||
{
|
||||
if (begin()->first > m_time)
|
||||
return 0;
|
||||
else if (m_phase && (begin()->second & 0xFF000000) && !(begin()->second & m_phase))
|
||||
erase(begin());
|
||||
else
|
||||
return (begin()->second & 0x0000FFFF);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Delay all events
|
||||
void DelayEvents(uint32 delay)
|
||||
{
|
||||
if (delay < m_time)
|
||||
m_time -= delay;
|
||||
else
|
||||
m_time = 0;
|
||||
}
|
||||
|
||||
// Delay all events having the specified Global Cooldown.
|
||||
void DelayEvents(uint32 delay, uint32 gcd)
|
||||
{
|
||||
uint32 nextTime = m_time + delay;
|
||||
gcd = (1 << (gcd + 16));
|
||||
for (iterator itr = begin(); itr != end() && itr->first < nextTime;)
|
||||
{
|
||||
if (itr->second & gcd)
|
||||
{
|
||||
ScheduleEvent(itr->second, itr->first-m_time+delay);
|
||||
erase(itr);
|
||||
itr = begin();
|
||||
}
|
||||
else
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
|
||||
void CancelEvent(uint32 eventId)
|
||||
{
|
||||
for (iterator itr = begin(); itr != end();)
|
||||
{
|
||||
if (eventId == (itr->second & 0x0000FFFF))
|
||||
{
|
||||
erase(itr);
|
||||
itr = begin();
|
||||
}
|
||||
else
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
|
||||
void CancelEventsByGCD(uint32 gcd)
|
||||
{
|
||||
gcd = (1 << (gcd + 16));
|
||||
|
||||
for (iterator itr = begin(); itr != end();)
|
||||
{
|
||||
if (itr->second & gcd)
|
||||
{
|
||||
erase(itr);
|
||||
itr = begin();
|
||||
}
|
||||
else
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
enum AITarget
|
||||
{
|
||||
AITARGET_SELF,
|
||||
AITARGET_VICTIM,
|
||||
AITARGET_ENEMY,
|
||||
AITARGET_ALLY,
|
||||
AITARGET_BUFF,
|
||||
AITARGET_DEBUFF,
|
||||
};
|
||||
|
||||
enum AICondition
|
||||
{
|
||||
AICOND_AGGRO,
|
||||
AICOND_COMBAT,
|
||||
AICOND_DIE,
|
||||
};
|
||||
|
||||
#define AI_DEFAULT_COOLDOWN 5000
|
||||
|
||||
struct AISpellInfoType
|
||||
{
|
||||
AISpellInfoType() : target(AITARGET_SELF), condition(AICOND_COMBAT)
|
||||
, cooldown(AI_DEFAULT_COOLDOWN), realCooldown(0), maxRange(0.0f){}
|
||||
AITarget target;
|
||||
AICondition condition;
|
||||
uint32 cooldown;
|
||||
uint32 realCooldown;
|
||||
float maxRange;
|
||||
};
|
||||
|
||||
AISpellInfoType * GetAISpellInfo(uint32 i);
|
||||
|
||||
inline void CreatureAI::SetGazeOn(Unit *target)
|
||||
{
|
||||
if (me->canAttack(target))
|
||||
{
|
||||
AttackStart(target);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool CreatureAI::UpdateVictimWithGaze()
|
||||
{
|
||||
if (!me->isInCombat())
|
||||
return false;
|
||||
|
||||
if (me->HasReactState(REACT_PASSIVE))
|
||||
{
|
||||
if (me->getVictim())
|
||||
return true;
|
||||
else
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
}
|
||||
|
||||
if (Unit *victim = me->SelectVictim())
|
||||
AttackStart(victim);
|
||||
return me->getVictim();
|
||||
}
|
||||
|
||||
inline bool CreatureAI::UpdateCombatState()
|
||||
{
|
||||
if (!me->isInCombat())
|
||||
return false;
|
||||
|
||||
if (!me->HasReactState(REACT_PASSIVE))
|
||||
{
|
||||
if (Unit *victim = me->SelectVictim())
|
||||
AttackStart(victim);
|
||||
return me->getVictim();
|
||||
}
|
||||
else if (me->getThreatManager().isThreatListEmpty())
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool CreatureAI::UpdateVictim()
|
||||
{
|
||||
if (!me->isInCombat())
|
||||
return false;
|
||||
|
||||
if (!me->HasReactState(REACT_PASSIVE))
|
||||
{
|
||||
if (Unit *victim = me->SelectVictim())
|
||||
AttackStart(victim);
|
||||
return me->getVictim();
|
||||
}
|
||||
else if (me->getThreatManager().isThreatListEmpty())
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
inline bool CreatureAI::UpdateVictim()
|
||||
{
|
||||
if (!me->isInCombat())
|
||||
return false;
|
||||
if (Unit *victim = me->SelectVictim())
|
||||
AttackStart(victim);
|
||||
return me->getVictim();
|
||||
}
|
||||
*/
|
||||
|
||||
inline bool CreatureAI::_EnterEvadeMode()
|
||||
{
|
||||
if (!me->isAlive())
|
||||
return false;
|
||||
|
||||
// sometimes bosses stuck in combat?
|
||||
me->RemoveAllAuras();
|
||||
me->DeleteThreatList();
|
||||
me->CombatStop(true);
|
||||
me->LoadCreaturesAddon();
|
||||
me->SetLootRecipient(NULL);
|
||||
me->ResetPlayerDamageReq();
|
||||
|
||||
if (me->IsInEvadeMode())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void UnitAI::DoCast(Unit* victim, uint32 spellId, bool triggered)
|
||||
{
|
||||
if (!victim || (me->hasUnitState(UNIT_STAT_CASTING) && !triggered))
|
||||
return;
|
||||
|
||||
me->CastSpell(victim, spellId, triggered);
|
||||
}
|
||||
|
||||
inline void UnitAI::DoCastVictim(uint32 spellId, bool triggered)
|
||||
{
|
||||
me->CastSpell(me->getVictim(), spellId, triggered);
|
||||
}
|
||||
|
||||
inline void UnitAI::DoCastAOE(uint32 spellId, bool triggered)
|
||||
{
|
||||
if (!triggered && me->hasUnitState(UNIT_STAT_CASTING))
|
||||
return;
|
||||
|
||||
me->CastSpell((Unit*)NULL, spellId, triggered);
|
||||
}
|
||||
|
||||
inline Creature *CreatureAI::DoSummon(uint32 uiEntry, const Position &pos, uint32 uiDespawntime, TempSummonType uiType)
|
||||
{
|
||||
return me->SummonCreature(uiEntry, pos, uiType, uiDespawntime);
|
||||
}
|
||||
|
||||
inline Creature *CreatureAI::DoSummon(uint32 uiEntry, WorldObject* obj, float fRadius, uint32 uiDespawntime, TempSummonType uiType)
|
||||
{
|
||||
Position pos;
|
||||
obj->GetRandomNearPosition(pos, fRadius);
|
||||
return me->SummonCreature(uiEntry, pos, uiType, uiDespawntime);
|
||||
}
|
||||
|
||||
inline Creature *CreatureAI::DoSummonFlyer(uint32 uiEntry, WorldObject *obj, float _fZ, float fRadius, uint32 uiDespawntime, TempSummonType uiType)
|
||||
{
|
||||
Position pos;
|
||||
obj->GetRandomNearPosition(pos, fRadius);
|
||||
pos.m_positionZ += _fZ;
|
||||
return me->SummonCreature(uiEntry, pos, uiType, uiDespawntime);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "PassiveAI.h"
|
||||
#include "ReactorAI.h"
|
||||
#include "CombatAI.h"
|
||||
#include "GuardAI.h"
|
||||
#include "PetAI.h"
|
||||
#include "TotemAI.h"
|
||||
#include "CreatureEventAI.h"
|
||||
#include "RandomMovementGenerator.h"
|
||||
#include "MovementGeneratorImpl.h"
|
||||
#include "CreatureAIRegistry.h"
|
||||
#include "WaypointMovementGenerator.h"
|
||||
#include "CreatureAIFactory.h"
|
||||
|
||||
//#include "CreatureAIImpl.h"
|
||||
namespace AIRegistry
|
||||
{
|
||||
void Initialize()
|
||||
{
|
||||
(new CreatureAIFactory<NullCreatureAI>("NullCreatureAI"))->RegisterSelf();
|
||||
(new CreatureAIFactory<TriggerAI>("TriggerAI"))->RegisterSelf();
|
||||
(new CreatureAIFactory<AggressorAI>("AggressorAI"))->RegisterSelf();
|
||||
(new CreatureAIFactory<ReactorAI>("ReactorAI"))->RegisterSelf();
|
||||
(new CreatureAIFactory<PassiveAI>("PassiveAI"))->RegisterSelf();
|
||||
(new CreatureAIFactory<CritterAI>("CritterAI"))->RegisterSelf();
|
||||
(new CreatureAIFactory<GuardAI>("GuardAI"))->RegisterSelf();
|
||||
(new CreatureAIFactory<PetAI>("PetAI"))->RegisterSelf();
|
||||
(new CreatureAIFactory<TotemAI>("TotemAI"))->RegisterSelf();
|
||||
(new CreatureAIFactory<CombatAI>("CombatAI"))->RegisterSelf();
|
||||
(new CreatureAIFactory<ArchorAI>("ArchorAI"))->RegisterSelf();
|
||||
(new CreatureAIFactory<TurretAI>("TurretAI"))->RegisterSelf();
|
||||
(new CreatureAIFactory<CreatureEventAI>("EventAI"))->RegisterSelf();
|
||||
(new CreatureAIFactory<AOEAI>("AOEAI"))->RegisterSelf();
|
||||
(new CreatureAIFactory<VehicleAI>("VehicleAI"))->RegisterSelf();
|
||||
|
||||
(new MovementGeneratorFactory<RandomMovementGenerator<Creature> >(RANDOM_MOTION_TYPE))->RegisterSelf();
|
||||
(new MovementGeneratorFactory<WaypointMovementGenerator<Creature> >(WAYPOINT_MOTION_TYPE))->RegisterSelf();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_CREATUREAIREGISTRY_H
|
||||
#define TRINITY_CREATUREAIREGISTRY_H
|
||||
|
||||
namespace AIRegistry
|
||||
{
|
||||
void Initialize(void);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Creature.h"
|
||||
#include "CreatureAISelector.h"
|
||||
#include "PassiveAI.h"
|
||||
#include "Policies/SingletonImp.h"
|
||||
#include "MovementGenerator.h"
|
||||
#include "Pet.h"
|
||||
#include "TemporarySummon.h"
|
||||
#include "CreatureAIFactory.h"
|
||||
#include "ScriptMgr.h"
|
||||
|
||||
INSTANTIATE_SINGLETON_1(CreatureAIRegistry);
|
||||
INSTANTIATE_SINGLETON_1(MovementGeneratorRegistry);
|
||||
|
||||
namespace FactorySelector
|
||||
{
|
||||
CreatureAI* selectAI(Creature *creature)
|
||||
{
|
||||
const CreatureAICreator *ai_factory = NULL;
|
||||
CreatureAIRegistry &ai_registry(CreatureAIRepository::Instance());
|
||||
|
||||
if (creature->isPet())
|
||||
ai_factory = ai_registry.GetRegistryItem("PetAI");
|
||||
|
||||
//scriptname in db
|
||||
if (!ai_factory)
|
||||
if (CreatureAI* scriptedAI = sScriptMgr.GetAI(creature))
|
||||
return scriptedAI;
|
||||
|
||||
// AIname in db
|
||||
std::string ainame=creature->GetAIName();
|
||||
if (!ai_factory && !ainame.empty())
|
||||
ai_factory = ai_registry.GetRegistryItem(ainame.c_str());
|
||||
|
||||
// select by NPC flags
|
||||
if (!ai_factory)
|
||||
{
|
||||
if (creature->IsVehicle())
|
||||
ai_factory = ai_registry.GetRegistryItem("VehicleAI");
|
||||
else if (creature->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN) && ((Guardian*)creature)->GetOwner()->GetTypeId() == TYPEID_PLAYER)
|
||||
ai_factory = ai_registry.GetRegistryItem("PetAI");
|
||||
else if (creature->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK))
|
||||
ai_factory = ai_registry.GetRegistryItem("NullCreatureAI");
|
||||
else if (creature->isGuard())
|
||||
ai_factory = ai_registry.GetRegistryItem("GuardAI");
|
||||
else if (creature->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN))
|
||||
ai_factory = ai_registry.GetRegistryItem("PetAI");
|
||||
else if (creature->isTotem())
|
||||
ai_factory = ai_registry.GetRegistryItem("TotemAI");
|
||||
else if (creature->isTrigger())
|
||||
{
|
||||
if (creature->m_spells[0])
|
||||
ai_factory = ai_registry.GetRegistryItem("TriggerAI");
|
||||
else
|
||||
ai_factory = ai_registry.GetRegistryItem("NullCreatureAI");
|
||||
}
|
||||
else if (creature->GetCreatureType() == CREATURE_TYPE_CRITTER && !creature->HasUnitTypeMask(UNIT_MASK_GUARDIAN))
|
||||
ai_factory = ai_registry.GetRegistryItem("CritterAI");
|
||||
}
|
||||
|
||||
// select by permit check
|
||||
if (!ai_factory)
|
||||
{
|
||||
int best_val = -1;
|
||||
typedef CreatureAIRegistry::RegistryMapType RMT;
|
||||
RMT const &l = ai_registry.GetRegisteredItems();
|
||||
for (RMT::const_iterator iter = l.begin(); iter != l.end(); ++iter)
|
||||
{
|
||||
const CreatureAICreator *factory = iter->second;
|
||||
const SelectableAI *p = dynamic_cast<const SelectableAI *>(factory);
|
||||
assert(p != NULL);
|
||||
int val = p->Permit(creature);
|
||||
if (val > best_val)
|
||||
{
|
||||
best_val = val;
|
||||
ai_factory = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// select NullCreatureAI if not another cases
|
||||
ainame = (ai_factory == NULL) ? "NullCreatureAI" : ai_factory->key();
|
||||
|
||||
DEBUG_LOG("Creature %u used AI is %s.", creature->GetGUIDLow(), ainame.c_str());
|
||||
return (ai_factory == NULL ? new NullCreatureAI(creature) : ai_factory->Create(creature));
|
||||
}
|
||||
|
||||
MovementGenerator* selectMovementGenerator(Creature *creature)
|
||||
{
|
||||
MovementGeneratorRegistry &mv_registry(MovementGeneratorRepository::Instance());
|
||||
assert(creature->GetCreatureInfo() != NULL);
|
||||
const MovementGeneratorCreator *mv_factory = mv_registry.GetRegistryItem(creature->GetDefaultMovementType());
|
||||
|
||||
/* if (mv_factory == NULL)
|
||||
{
|
||||
int best_val = -1;
|
||||
std::vector<std::string> l;
|
||||
mv_registry.GetRegisteredItems(l);
|
||||
for (std::vector<std::string>::iterator iter = l.begin(); iter != l.end(); ++iter)
|
||||
{
|
||||
const MovementGeneratorCreator *factory = mv_registry.GetRegistryItem((*iter).c_str());
|
||||
const SelectableMovement *p = dynamic_cast<const SelectableMovement *>(factory);
|
||||
assert(p != NULL);
|
||||
int val = p->Permit(creature);
|
||||
if (val > best_val)
|
||||
{
|
||||
best_val = val;
|
||||
mv_factory = p;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
return (mv_factory == NULL ? NULL : mv_factory->Create(creature));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_CREATUREAISELECTOR_H
|
||||
#define TRINITY_CREATUREAISELECTOR_H
|
||||
|
||||
class CreatureAI;
|
||||
class Creature;
|
||||
class MovementGenerator;
|
||||
|
||||
namespace FactorySelector
|
||||
{
|
||||
CreatureAI* selectAI(Creature *);
|
||||
MovementGenerator* selectMovementGenerator(Creature *);
|
||||
}
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,637 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_CREATURE_EAI_H
|
||||
#define TRINITY_CREATURE_EAI_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "Creature.h"
|
||||
#include "CreatureAI.h"
|
||||
#include "Unit.h"
|
||||
|
||||
class Player;
|
||||
class WorldObject;
|
||||
|
||||
#define EVENT_UPDATE_TIME 500
|
||||
#define MAX_ACTIONS 3
|
||||
#define MAX_PHASE 32
|
||||
|
||||
enum EventAI_Type
|
||||
{
|
||||
EVENT_T_TIMER = 0, // InitialMin, InitialMax, RepeatMin, RepeatMax
|
||||
EVENT_T_TIMER_OOC = 1, // InitialMin, InitialMax, RepeatMin, RepeatMax
|
||||
EVENT_T_HP = 2, // HPMax%, HPMin%, RepeatMin, RepeatMax
|
||||
EVENT_T_MANA = 3, // ManaMax%,ManaMin% RepeatMin, RepeatMax
|
||||
EVENT_T_AGGRO = 4, // NONE
|
||||
EVENT_T_KILL = 5, // RepeatMin, RepeatMax
|
||||
EVENT_T_DEATH = 6, // NONE
|
||||
EVENT_T_EVADE = 7, // NONE
|
||||
EVENT_T_SPELLHIT = 8, // SpellID, School, RepeatMin, RepeatMax
|
||||
EVENT_T_RANGE = 9, // MinDist, MaxDist, RepeatMin, RepeatMax
|
||||
EVENT_T_OOC_LOS = 10, // NoHostile, MaxRnage, RepeatMin, RepeatMax
|
||||
EVENT_T_SPAWNED = 11, // Condition, CondValue1
|
||||
EVENT_T_TARGET_HP = 12, // HPMax%, HPMin%, RepeatMin, RepeatMax
|
||||
EVENT_T_TARGET_CASTING = 13, // RepeatMin, RepeatMax
|
||||
EVENT_T_FRIENDLY_HP = 14, // HPDeficit, Radius, RepeatMin, RepeatMax
|
||||
EVENT_T_FRIENDLY_IS_CC = 15, // DispelType, Radius, RepeatMin, RepeatMax
|
||||
EVENT_T_FRIENDLY_MISSING_BUFF = 16, // SpellId, Radius, RepeatMin, RepeatMax
|
||||
EVENT_T_SUMMONED_UNIT = 17, // CreatureId, RepeatMin, RepeatMax
|
||||
EVENT_T_TARGET_MANA = 18, // ManaMax%, ManaMin%, RepeatMin, RepeatMax
|
||||
EVENT_T_QUEST_ACCEPT = 19, // QuestID
|
||||
EVENT_T_QUEST_COMPLETE = 20, //
|
||||
EVENT_T_REACHED_HOME = 21, // NONE
|
||||
EVENT_T_RECEIVE_EMOTE = 22, // EmoteId, Condition, CondValue1, CondValue2
|
||||
EVENT_T_BUFFED = 23, // Param1 = SpellID, Param2 = Number of Time STacked, Param3/4 Repeat Min/Max
|
||||
EVENT_T_TARGET_BUFFED = 24, // Param1 = SpellID, Param2 = Number of Time STacked, Param3/4 Repeat Min/Max
|
||||
EVENT_T_RESET = 35, // Is it called after combat, when the creature respawn and spawn. -- TRINITY ONLY
|
||||
|
||||
EVENT_T_END,
|
||||
};
|
||||
|
||||
enum EventAI_ActionType
|
||||
{
|
||||
ACTION_T_NONE = 0, // No action
|
||||
ACTION_T_TEXT = 1, // TextId1, optionally -TextId2, optionally -TextId3(if -TextId2 exist). If more than just -TextId1 is defined, randomize. Negative values.
|
||||
ACTION_T_SET_FACTION = 2, // FactionId (or 0 for default)
|
||||
ACTION_T_MORPH_TO_ENTRY_OR_MODEL = 3, // Creature_template entry(param1) OR ModelId (param2) (or 0 for both to demorph)
|
||||
ACTION_T_SOUND = 4, // SoundId
|
||||
ACTION_T_EMOTE = 5, // EmoteId
|
||||
ACTION_T_RANDOM_SAY = 6, // UNUSED
|
||||
ACTION_T_RANDOM_YELL = 7, // UNUSED
|
||||
ACTION_T_RANDOM_TEXTEMOTE = 8, // UNUSED
|
||||
ACTION_T_RANDOM_SOUND = 9, // SoundId1, SoundId2, SoundId3 (-1 in any field means no output if randomed that field)
|
||||
ACTION_T_RANDOM_EMOTE = 10, // EmoteId1, EmoteId2, EmoteId3 (-1 in any field means no output if randomed that field)
|
||||
ACTION_T_CAST = 11, // SpellId, Target, CastFlags
|
||||
ACTION_T_SUMMON = 12, // CreatureID, Target, Duration in ms
|
||||
ACTION_T_THREAT_SINGLE_PCT = 13, // Threat%, Target
|
||||
ACTION_T_THREAT_ALL_PCT = 14, // Threat%
|
||||
ACTION_T_QUEST_EVENT = 15, // QuestID, Target
|
||||
ACTION_T_CAST_EVENT = 16, // QuestID, SpellId, Target - must be removed as hack?
|
||||
ACTION_T_SET_UNIT_FIELD = 17, // Field_Number, Value, Target
|
||||
ACTION_T_SET_UNIT_FLAG = 18, // Flags (may be more than one field OR'd together), Target
|
||||
ACTION_T_REMOVE_UNIT_FLAG = 19, // Flags (may be more than one field OR'd together), Target
|
||||
ACTION_T_AUTO_ATTACK = 20, // AllowAttackState (0 = stop attack, anything else means continue attacking)
|
||||
ACTION_T_COMBAT_MOVEMENT = 21, // AllowCombatMovement (0 = stop combat based movement, anything else continue attacking)
|
||||
ACTION_T_SET_PHASE = 22, // Phase
|
||||
ACTION_T_INC_PHASE = 23, // Value (may be negative to decrement phase, should not be 0)
|
||||
ACTION_T_EVADE = 24, // No Params
|
||||
ACTION_T_FLEE_FOR_ASSIST = 25, // No Params
|
||||
ACTION_T_QUEST_EVENT_ALL = 26, // QuestID
|
||||
ACTION_T_CAST_EVENT_ALL = 27, // CreatureId, SpellId
|
||||
ACTION_T_REMOVEAURASFROMSPELL = 28, // Target, Spellid
|
||||
ACTION_T_RANGED_MOVEMENT = 29, // Distance, Angle
|
||||
ACTION_T_RANDOM_PHASE = 30, // PhaseId1, PhaseId2, PhaseId3
|
||||
ACTION_T_RANDOM_PHASE_RANGE = 31, // PhaseMin, PhaseMax
|
||||
ACTION_T_SUMMON_ID = 32, // CreatureId, Target, SpawnId
|
||||
ACTION_T_KILLED_MONSTER = 33, // CreatureId, Target
|
||||
ACTION_T_SET_INST_DATA = 34, // Field, Data
|
||||
ACTION_T_SET_INST_DATA64 = 35, // Field, Target
|
||||
ACTION_T_UPDATE_TEMPLATE = 36, // Entry, Team
|
||||
ACTION_T_DIE = 37, // No Params
|
||||
ACTION_T_ZONE_COMBAT_PULSE = 38, // No Params
|
||||
ACTION_T_CALL_FOR_HELP = 39, // Radius
|
||||
ACTION_T_SET_SHEATH = 40, // Sheath (0-passive,1-melee,2-ranged)
|
||||
ACTION_T_FORCE_DESPAWN = 41, // No Params
|
||||
ACTION_T_SET_INVINCIBILITY_HP_LEVEL = 42, // MinHpValue, format(0-flat,1-percent from max health)
|
||||
|
||||
ACTION_T_SET_PHASE_MASK = 97,
|
||||
ACTION_T_SET_STAND_STATE = 98,
|
||||
ACTION_T_MOVE_RANDOM_POINT = 99,
|
||||
ACTION_T_SET_VISIBILITY = 100,
|
||||
ACTION_T_SET_ACTIVE = 101, //Apply
|
||||
ACTION_T_SET_AGGRESSIVE = 102, //Apply
|
||||
ACTION_T_ATTACK_START_PULSE = 103, //Distance
|
||||
ACTION_T_SUMMON_GO = 104, //GameObjectID, DespawnTime in ms
|
||||
|
||||
ACTION_T_END = 105,
|
||||
};
|
||||
|
||||
enum Target
|
||||
{
|
||||
//Self (me)
|
||||
TARGET_T_SELF = 0, //Self cast
|
||||
|
||||
//Hostile targets (if pet then returns pet owner)
|
||||
TARGET_T_HOSTILE, //Our current target (ie: highest aggro)
|
||||
TARGET_T_HOSTILE_SECOND_AGGRO, //Second highest aggro (generaly used for cleaves and some special attacks)
|
||||
TARGET_T_HOSTILE_LAST_AGGRO, //Dead last on aggro (no idea what this could be used for)
|
||||
TARGET_T_HOSTILE_RANDOM, //Just any random target on our threat list
|
||||
TARGET_T_HOSTILE_RANDOM_NOT_TOP, //Any random target except top threat
|
||||
|
||||
//Invoker targets (if pet then returns pet owner)
|
||||
TARGET_T_ACTION_INVOKER, //Unit who caused this Event to occur (only works for EVENT_T_AGGRO, EVENT_T_KILL, EVENT_T_DEATH, EVENT_T_SPELLHIT, EVENT_T_OOC_LOS, EVENT_T_FRIENDLY_HP, EVENT_T_FRIENDLY_IS_CC, EVENT_T_FRIENDLY_MISSING_BUFF)
|
||||
|
||||
//Hostile targets (including pets)
|
||||
TARGET_T_HOSTILE_WPET, //Current target (can be a pet)
|
||||
TARGET_T_HOSTILE_WPET_SECOND_AGGRO, //Second highest aggro (generaly used for cleaves and some special attacks)
|
||||
TARGET_T_HOSTILE_WPET_LAST_AGGRO, //Dead last on aggro (no idea what this could be used for)
|
||||
TARGET_T_HOSTILE_WPET_RANDOM, //Just any random target on our threat list
|
||||
TARGET_T_HOSTILE_WPET_RANDOM_NOT_TOP, //Any random target except top threat
|
||||
|
||||
TARGET_T_ACTION_INVOKER_WPET,
|
||||
|
||||
TARGET_T_END
|
||||
};
|
||||
|
||||
enum CastFlags
|
||||
{
|
||||
CAST_INTURRUPT_PREVIOUS = 0x01, //Interrupt any spell casting
|
||||
CAST_TRIGGERED = 0x02, //Triggered (this makes spell cost zero mana and have no cast time)
|
||||
CAST_FORCE_CAST = 0x04, //Forces cast even if creature is out of mana or out of range
|
||||
CAST_NO_MELEE_IF_OOM = 0x08, //Prevents creature from entering melee if out of mana or out of range
|
||||
CAST_FORCE_TARGET_SELF = 0x10, //Forces the target to cast this spell on itself
|
||||
CAST_AURA_NOT_PRESENT = 0x20, //Only casts the spell if the target does not have an aura from the spell
|
||||
};
|
||||
|
||||
enum EventFlags
|
||||
{
|
||||
EFLAG_REPEATABLE = 0x01, //Event repeats
|
||||
EFLAG_DIFFICULTY_0 = 0x02, //Event only occurs in instance difficulty 0
|
||||
EFLAG_DIFFICULTY_1 = 0x04, //Event only occurs in instance difficulty 1
|
||||
EFLAG_DIFFICULTY_2 = 0x08, //Event only occurs in instance difficulty 2
|
||||
EFLAG_DIFFICULTY_3 = 0x10, //Event only occurs in instance difficulty 3
|
||||
EFLAG_RESERVED_5 = 0x20,
|
||||
EFLAG_RESERVED_6 = 0x40,
|
||||
EFLAG_DEBUG_ONLY = 0x80, //Event only occurs in debug build
|
||||
|
||||
EFLAG_DIFFICULTY_ALL = (EFLAG_DIFFICULTY_0|EFLAG_DIFFICULTY_1|EFLAG_DIFFICULTY_2|EFLAG_DIFFICULTY_3)
|
||||
};
|
||||
|
||||
enum SpawnedEventMode
|
||||
{
|
||||
SPAWNED_EVENT_ALWAY = 0,
|
||||
SPAWNED_EVENT_MAP = 1,
|
||||
SPAWNED_EVENT_ZONE = 2
|
||||
};
|
||||
|
||||
// String text additional data, used in (CreatureEventAI)
|
||||
struct StringTextData
|
||||
{
|
||||
uint32 SoundId;
|
||||
uint8 Type;
|
||||
uint32 Language;
|
||||
uint32 Emote;
|
||||
};
|
||||
// Text Maps
|
||||
typedef UNORDERED_MAP<int32, StringTextData> CreatureEventAI_TextMap;
|
||||
|
||||
struct CreatureEventAI_Action
|
||||
{
|
||||
EventAI_ActionType type: 16;
|
||||
union
|
||||
{
|
||||
// ACTION_T_TEXT = 1
|
||||
struct
|
||||
{
|
||||
int32 TextId1;
|
||||
int32 TextId2;
|
||||
int32 TextId3;
|
||||
} text;
|
||||
// ACTION_T_SET_FACTION = 2
|
||||
struct
|
||||
{
|
||||
uint32 factionId; // faction or 0 for default)
|
||||
} set_faction;
|
||||
// ACTION_T_MORPH_TO_ENTRY_OR_MODEL = 3
|
||||
struct
|
||||
{
|
||||
uint32 creatureId; // set one from fields (or 0 for both to demorph)
|
||||
uint32 modelId;
|
||||
} morph;
|
||||
// ACTION_T_SOUND = 4
|
||||
struct
|
||||
{
|
||||
uint32 soundId;
|
||||
} sound;
|
||||
// ACTION_T_EMOTE = 5
|
||||
struct
|
||||
{
|
||||
uint32 emoteId;
|
||||
} emote;
|
||||
// ACTION_T_RANDOM_SOUND = 9
|
||||
struct
|
||||
{
|
||||
int32 soundId1; // (-1 in any field means no output if randomed that field)
|
||||
int32 soundId2;
|
||||
int32 soundId3;
|
||||
} random_sound;
|
||||
// ACTION_T_RANDOM_EMOTE = 10
|
||||
struct
|
||||
{
|
||||
int32 emoteId1; // (-1 in any field means no output if randomed that field)
|
||||
int32 emoteId2;
|
||||
int32 emoteId3;
|
||||
} random_emote;
|
||||
// ACTION_T_CAST = 11
|
||||
struct
|
||||
{
|
||||
uint32 spellId;
|
||||
uint32 target;
|
||||
uint32 castFlags;
|
||||
} cast;
|
||||
// ACTION_T_SUMMON = 12
|
||||
struct
|
||||
{
|
||||
uint32 creatureId;
|
||||
uint32 target;
|
||||
uint32 duration;
|
||||
} summon;
|
||||
// ACTION_T_THREAT_SINGLE_PCT = 13
|
||||
struct
|
||||
{
|
||||
int32 percent;
|
||||
uint32 target;
|
||||
} threat_single_pct;
|
||||
// ACTION_T_THREAT_ALL_PCT = 14
|
||||
struct
|
||||
{
|
||||
int32 percent;
|
||||
} threat_all_pct;
|
||||
// ACTION_T_QUEST_EVENT = 15
|
||||
struct
|
||||
{
|
||||
uint32 questId;
|
||||
uint32 target;
|
||||
} quest_event;
|
||||
// ACTION_T_CAST_EVENT = 16
|
||||
struct
|
||||
{
|
||||
uint32 creatureId;
|
||||
uint32 spellId;
|
||||
uint32 target;
|
||||
} cast_event;
|
||||
// ACTION_T_SET_UNIT_FIELD = 17
|
||||
struct
|
||||
{
|
||||
uint32 field;
|
||||
uint32 value;
|
||||
uint32 target;
|
||||
} set_unit_field;
|
||||
// ACTION_T_SET_UNIT_FLAG = 18, // value provided mask bits that will be set
|
||||
// ACTION_T_REMOVE_UNIT_FLAG = 19, // value provided mask bits that will be clear
|
||||
struct
|
||||
{
|
||||
uint32 value;
|
||||
uint32 target;
|
||||
} unit_flag;
|
||||
// ACTION_T_AUTO_ATTACK = 20
|
||||
struct
|
||||
{
|
||||
uint32 state; // 0 = stop attack, anything else means continue attacking
|
||||
} auto_attack;
|
||||
// ACTION_T_COMBAT_MOVEMENT = 21
|
||||
struct
|
||||
{
|
||||
uint32 state; // 0 = stop combat based movement, anything else continue attacking
|
||||
uint32 melee; // if set: at stop send melee combat stop if in combat, use for terminate melee fighting state for switch to ranged
|
||||
} combat_movement;
|
||||
// ACTION_T_SET_PHASE = 22
|
||||
struct
|
||||
{
|
||||
uint32 phase;
|
||||
} set_phase;
|
||||
// ACTION_T_INC_PHASE = 23
|
||||
struct
|
||||
{
|
||||
int32 step;
|
||||
} set_inc_phase;
|
||||
// ACTION_T_QUEST_EVENT_ALL = 26
|
||||
struct
|
||||
{
|
||||
uint32 questId;
|
||||
} quest_event_all;
|
||||
// ACTION_T_CAST_EVENT_ALL = 27
|
||||
struct
|
||||
{
|
||||
uint32 creatureId;
|
||||
uint32 spellId;
|
||||
} cast_event_all;
|
||||
// ACTION_T_REMOVEAURASFROMSPELL = 28
|
||||
struct
|
||||
{
|
||||
uint32 target;
|
||||
uint32 spellId;
|
||||
} remove_aura;
|
||||
// ACTION_T_RANGED_MOVEMENT = 29
|
||||
struct
|
||||
{
|
||||
uint32 distance;
|
||||
int32 angle;
|
||||
} ranged_movement;
|
||||
// ACTION_T_RANDOM_PHASE = 30
|
||||
struct
|
||||
{
|
||||
uint32 phase1;
|
||||
uint32 phase2;
|
||||
uint32 phase3;
|
||||
} random_phase;
|
||||
// ACTION_T_RANDOM_PHASE_RANGE = 31
|
||||
struct
|
||||
{
|
||||
uint32 phaseMin;
|
||||
uint32 phaseMax;
|
||||
} random_phase_range;
|
||||
// ACTION_T_SUMMON_ID = 32
|
||||
struct
|
||||
{
|
||||
uint32 creatureId;
|
||||
uint32 target;
|
||||
uint32 spawnId;
|
||||
} summon_id;
|
||||
// ACTION_T_KILLED_MONSTER = 33
|
||||
struct
|
||||
{
|
||||
uint32 creatureId;
|
||||
uint32 target;
|
||||
} killed_monster;
|
||||
// ACTION_T_SET_INST_DATA = 34
|
||||
struct
|
||||
{
|
||||
uint32 field;
|
||||
uint32 value;
|
||||
} set_inst_data;
|
||||
// ACTION_T_SET_INST_DATA64 = 35
|
||||
struct
|
||||
{
|
||||
uint32 field;
|
||||
uint32 target;
|
||||
} set_inst_data64;
|
||||
// ACTION_T_UPDATE_TEMPLATE = 36
|
||||
struct
|
||||
{
|
||||
uint32 creatureId;
|
||||
uint32 team;
|
||||
} update_template;
|
||||
// ACTION_T_CALL_FOR_HELP = 39
|
||||
struct
|
||||
{
|
||||
uint32 radius;
|
||||
} call_for_help;
|
||||
// ACTION_T_SET_SHEATH = 40
|
||||
struct
|
||||
{
|
||||
uint32 sheath;
|
||||
} set_sheath;
|
||||
// ACTION_T_FORCE_DESPAWN = 41
|
||||
struct
|
||||
{
|
||||
uint32 msDelay;
|
||||
} forced_despawn;
|
||||
// ACTION_T_SET_INVINCIBILITY_HP_LEVEL = 42
|
||||
struct
|
||||
{
|
||||
uint32 hp_level;
|
||||
uint32 is_percent;
|
||||
} invincibility_hp_level;
|
||||
// RAW
|
||||
struct
|
||||
{
|
||||
uint32 param1;
|
||||
uint32 param2;
|
||||
uint32 param3;
|
||||
} raw;
|
||||
};
|
||||
};
|
||||
|
||||
struct CreatureEventAI_Event
|
||||
{
|
||||
uint32 event_id;
|
||||
|
||||
uint32 creature_id;
|
||||
|
||||
uint32 event_inverse_phase_mask;
|
||||
|
||||
EventAI_Type event_type : 16;
|
||||
uint8 event_chance : 8;
|
||||
uint8 event_flags : 8;
|
||||
|
||||
union
|
||||
{
|
||||
// EVENT_T_TIMER = 0
|
||||
// EVENT_T_TIMER_OOC = 1
|
||||
struct
|
||||
{
|
||||
uint32 initialMin;
|
||||
uint32 initialMax;
|
||||
uint32 repeatMin;
|
||||
uint32 repeatMax;
|
||||
} timer;
|
||||
// EVENT_T_HP = 2
|
||||
// EVENT_T_MANA = 3
|
||||
// EVENT_T_TARGET_HP = 12
|
||||
// EVENT_T_TARGET_MANA = 18
|
||||
struct
|
||||
{
|
||||
uint32 percentMax;
|
||||
uint32 percentMin;
|
||||
uint32 repeatMin;
|
||||
uint32 repeatMax;
|
||||
} percent_range;
|
||||
// EVENT_T_KILL = 5
|
||||
struct
|
||||
{
|
||||
uint32 repeatMin;
|
||||
uint32 repeatMax;
|
||||
} kill;
|
||||
// EVENT_T_SPELLHIT = 8
|
||||
struct
|
||||
{
|
||||
uint32 spellId;
|
||||
uint32 schoolMask; // -1 ( == 0xffffffff) is ok value for full mask, or must be more limited mask like (0 < 1) = 1 for normal/physical school
|
||||
uint32 repeatMin;
|
||||
uint32 repeatMax;
|
||||
} spell_hit;
|
||||
// EVENT_T_RANGE = 9
|
||||
struct
|
||||
{
|
||||
uint32 minDist;
|
||||
uint32 maxDist;
|
||||
uint32 repeatMin;
|
||||
uint32 repeatMax;
|
||||
} range;
|
||||
// EVENT_T_OOC_LOS = 10
|
||||
struct
|
||||
{
|
||||
uint32 noHostile;
|
||||
uint32 maxRange;
|
||||
uint32 repeatMin;
|
||||
uint32 repeatMax;
|
||||
} ooc_los;
|
||||
// EVENT_T_SPAWNED = 11
|
||||
struct
|
||||
{
|
||||
uint32 condition;
|
||||
uint32 conditionValue1;
|
||||
} spawned;
|
||||
// EVENT_T_TARGET_CASTING = 13
|
||||
struct
|
||||
{
|
||||
uint32 repeatMin;
|
||||
uint32 repeatMax;
|
||||
} target_casting;
|
||||
// EVENT_T_FRIENDLY_HP = 14
|
||||
struct
|
||||
{
|
||||
uint32 hpDeficit;
|
||||
uint32 radius;
|
||||
uint32 repeatMin;
|
||||
uint32 repeatMax;
|
||||
} friendly_hp;
|
||||
// EVENT_T_FRIENDLY_IS_CC = 15
|
||||
struct
|
||||
{
|
||||
uint32 dispelType; // unused ?
|
||||
uint32 radius;
|
||||
uint32 repeatMin;
|
||||
uint32 repeatMax;
|
||||
} friendly_is_cc;
|
||||
// EVENT_T_FRIENDLY_MISSING_BUFF = 16
|
||||
struct
|
||||
{
|
||||
uint32 spellId;
|
||||
uint32 radius;
|
||||
uint32 repeatMin;
|
||||
uint32 repeatMax;
|
||||
} friendly_buff;
|
||||
// EVENT_T_SUMMONED_UNIT = 17
|
||||
struct
|
||||
{
|
||||
uint32 creatureId;
|
||||
uint32 repeatMin;
|
||||
uint32 repeatMax;
|
||||
} summon_unit;
|
||||
// EVENT_T_QUEST_ACCEPT = 19
|
||||
// EVENT_T_QUEST_COMPLETE = 20
|
||||
struct
|
||||
{
|
||||
uint32 questId;
|
||||
} quest;
|
||||
// EVENT_T_RECEIVE_EMOTE = 22
|
||||
struct
|
||||
{
|
||||
uint32 emoteId;
|
||||
uint32 condition;
|
||||
uint32 conditionValue1;
|
||||
uint32 conditionValue2;
|
||||
} receive_emote;
|
||||
// EVENT_T_BUFFED = 23
|
||||
// EVENT_T_TARGET_BUFFED = 24
|
||||
struct
|
||||
{
|
||||
uint32 spellId;
|
||||
uint32 amount;
|
||||
uint32 repeatMin;
|
||||
uint32 repeatMax;
|
||||
} buffed;
|
||||
|
||||
// RAW
|
||||
struct
|
||||
{
|
||||
uint32 param1;
|
||||
uint32 param2;
|
||||
uint32 param3;
|
||||
uint32 param4;
|
||||
} raw;
|
||||
};
|
||||
|
||||
CreatureEventAI_Action action[MAX_ACTIONS];
|
||||
};
|
||||
//Event_Map
|
||||
typedef UNORDERED_MAP<uint32, std::vector<CreatureEventAI_Event> > CreatureEventAI_Event_Map;
|
||||
|
||||
struct CreatureEventAI_Summon
|
||||
{
|
||||
uint32 id;
|
||||
|
||||
float position_x;
|
||||
float position_y;
|
||||
float position_z;
|
||||
float orientation;
|
||||
uint32 SpawnTimeSecs;
|
||||
};
|
||||
|
||||
//EventSummon_Map
|
||||
typedef UNORDERED_MAP<uint32, CreatureEventAI_Summon> CreatureEventAI_Summon_Map;
|
||||
|
||||
struct CreatureEventAIHolder
|
||||
{
|
||||
CreatureEventAIHolder(CreatureEventAI_Event p) : Event(p), Time(0), Enabled(true){}
|
||||
|
||||
CreatureEventAI_Event Event;
|
||||
uint32 Time;
|
||||
bool Enabled;
|
||||
|
||||
// helper
|
||||
bool UpdateRepeatTimer(Creature* creature, uint32 repeatMin, uint32 repeatMax);
|
||||
};
|
||||
|
||||
class CreatureEventAI : public CreatureAI
|
||||
{
|
||||
|
||||
public:
|
||||
explicit CreatureEventAI(Creature *c);
|
||||
~CreatureEventAI()
|
||||
{
|
||||
CreatureEventAIList.clear();
|
||||
}
|
||||
void JustRespawned();
|
||||
void Reset();
|
||||
void JustReachedHome();
|
||||
void EnterCombat(Unit *enemy);
|
||||
void EnterEvadeMode();
|
||||
void JustDied(Unit* /*killer*/);
|
||||
void KilledUnit(Unit* victim);
|
||||
void JustSummoned(Creature* pUnit);
|
||||
void AttackStart(Unit *who);
|
||||
void MoveInLineOfSight(Unit *who);
|
||||
void SpellHit(Unit* pUnit, const SpellEntry* pSpell);
|
||||
void DamageTaken(Unit* done_by, uint32& damage);
|
||||
void UpdateAI(const uint32 diff);
|
||||
void ReceiveEmote(Player* pPlayer, uint32 text_emote);
|
||||
static int Permissible(const Creature *);
|
||||
|
||||
bool ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pActionInvoker = NULL);
|
||||
void ProcessAction(CreatureEventAI_Action const& action, uint32 rnd, uint32 EventId, Unit* pActionInvoker);
|
||||
inline uint32 GetRandActionParam(uint32 rnd, uint32 param1, uint32 param2, uint32 param3);
|
||||
inline int32 GetRandActionParam(uint32 rnd, int32 param1, int32 param2, int32 param3);
|
||||
inline Unit* GetTargetByType(uint32 Target, Unit* pActionInvoker);
|
||||
|
||||
void DoScriptText(int32 textEntry, WorldObject* pSource, Unit* target);
|
||||
bool CanCast(Unit* Target, SpellEntry const *Spell, bool Triggered);
|
||||
|
||||
bool SpawnedEventConditionsCheck(CreatureEventAI_Event const& event);
|
||||
|
||||
Unit* DoSelectLowestHpFriendly(float range, uint32 MinHPDiff);
|
||||
void DoFindFriendlyMissingBuff(std::list<Creature*>& _list, float range, uint32 spellid);
|
||||
void DoFindFriendlyCC(std::list<Creature*>& _list, float range);
|
||||
|
||||
//Holder for events (stores enabled, time, and eventid)
|
||||
std::list<CreatureEventAIHolder> CreatureEventAIList;
|
||||
uint32 EventUpdateTime; //Time between event updates
|
||||
uint32 EventDiff; //Time between the last event call
|
||||
bool bEmptyList;
|
||||
|
||||
//Variables used by Events themselves
|
||||
uint8 Phase; // Current phase, max 32 phases
|
||||
bool CombatMovementEnabled; // If we allow targeted movment gen (movement twoards top threat)
|
||||
bool MeleeEnabled; // If we allow melee auto attack
|
||||
float AttackDistance; // Distance to attack from
|
||||
float AttackAngle; // Angle of attack
|
||||
uint32 InvinceabilityHpLevel; // Minimal health level allowed at damage apply
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,745 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Common.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "Database/SQLStorage.h"
|
||||
#include "CreatureEventAI.h"
|
||||
#include "CreatureEventAIMgr.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "ProgressBar.h"
|
||||
#include "Policies/SingletonImp.h"
|
||||
#include "ObjectDefines.h"
|
||||
#include "GridDefines.h"
|
||||
#include "ConditionMgr.h"
|
||||
|
||||
INSTANTIATE_SINGLETON_1(CreatureEventAIMgr);
|
||||
|
||||
// -------------------
|
||||
void CreatureEventAIMgr::LoadCreatureEventAI_Texts()
|
||||
{
|
||||
// Drop Existing Text Map, only done once and we are ready to add data from multiple sources.
|
||||
m_CreatureEventAI_TextMap.clear();
|
||||
|
||||
// Load EventAI Text
|
||||
objmgr.LoadTrinityStrings(WorldDatabase,"creature_ai_texts",MIN_CREATURE_AI_TEXT_STRING_ID,MAX_CREATURE_AI_TEXT_STRING_ID);
|
||||
|
||||
// Gather Additional data from EventAI Texts
|
||||
QueryResult_AutoPtr result = WorldDatabase.Query("SELECT entry, sound, type, language, emote FROM creature_ai_texts");
|
||||
|
||||
sLog.outString("Loading EventAI Texts additional data...");
|
||||
if (result)
|
||||
{
|
||||
barGoLink bar(result->GetRowCount());
|
||||
uint32 count = 0;
|
||||
|
||||
do
|
||||
{
|
||||
bar.step();
|
||||
Field* fields = result->Fetch();
|
||||
StringTextData temp;
|
||||
|
||||
int32 i = fields[0].GetInt32();
|
||||
temp.SoundId = fields[1].GetInt32();
|
||||
temp.Type = fields[2].GetInt32();
|
||||
temp.Language = fields[3].GetInt32();
|
||||
temp.Emote = fields[4].GetInt32();
|
||||
|
||||
// range negative
|
||||
if (i > MIN_CREATURE_AI_TEXT_STRING_ID || i <= MAX_CREATURE_AI_TEXT_STRING_ID)
|
||||
{
|
||||
sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` is not in valid range(%d-%d)",i,MIN_CREATURE_AI_TEXT_STRING_ID,MAX_CREATURE_AI_TEXT_STRING_ID);
|
||||
continue;
|
||||
}
|
||||
|
||||
// range negative (don't must be happen, loaded from same table)
|
||||
if (!objmgr.GetTrinityStringLocale(i))
|
||||
{
|
||||
sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` not found",i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (temp.SoundId)
|
||||
{
|
||||
if (!sSoundEntriesStore.LookupEntry(temp.SoundId))
|
||||
sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` has Sound %u but sound does not exist.",i,temp.SoundId);
|
||||
}
|
||||
|
||||
if (!GetLanguageDescByID(temp.Language))
|
||||
sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` using Language %u but Language does not exist.",i,temp.Language);
|
||||
|
||||
if (temp.Type > CHAT_TYPE_ZONE_YELL)
|
||||
sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` has Type %u but this Chat Type does not exist.",i,temp.Type);
|
||||
|
||||
if (temp.Emote)
|
||||
{
|
||||
if (!sEmotesStore.LookupEntry(temp.Emote))
|
||||
sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` has Emote %u but emote does not exist.",i,temp.Emote);
|
||||
}
|
||||
|
||||
m_CreatureEventAI_TextMap[i] = temp;
|
||||
++count;
|
||||
} while (result->NextRow());
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded %u additional CreatureEventAI Texts data.", count);
|
||||
}
|
||||
else
|
||||
{
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded 0 additional CreatureEventAI Texts data. DB table `creature_ai_texts` is empty.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// -------------------
|
||||
void CreatureEventAIMgr::LoadCreatureEventAI_Summons()
|
||||
{
|
||||
|
||||
//Drop Existing EventSummon Map
|
||||
m_CreatureEventAI_Summon_Map.clear();
|
||||
|
||||
// Gather additional data for EventAI
|
||||
QueryResult_AutoPtr result = WorldDatabase.Query("SELECT id, position_x, position_y, position_z, orientation, spawntimesecs FROM creature_ai_summons");
|
||||
if (result)
|
||||
{
|
||||
barGoLink bar(result->GetRowCount());
|
||||
uint32 Count = 0;
|
||||
|
||||
do
|
||||
{
|
||||
bar.step();
|
||||
Field *fields = result->Fetch();
|
||||
|
||||
CreatureEventAI_Summon temp;
|
||||
|
||||
uint32 i = fields[0].GetUInt32();
|
||||
temp.position_x = fields[1].GetFloat();
|
||||
temp.position_y = fields[2].GetFloat();
|
||||
temp.position_z = fields[3].GetFloat();
|
||||
temp.orientation = fields[4].GetFloat();
|
||||
temp.SpawnTimeSecs = fields[5].GetUInt32();
|
||||
|
||||
if (!Trinity::IsValidMapCoord(temp.position_x,temp.position_y,temp.position_z,temp.orientation))
|
||||
{
|
||||
sLog.outErrorDb("CreatureEventAI: Summon id %u have wrong coordinates (%f,%f,%f,%f), skipping.", i,temp.position_x,temp.position_y,temp.position_z,temp.orientation);
|
||||
continue;
|
||||
}
|
||||
|
||||
//Add to map
|
||||
m_CreatureEventAI_Summon_Map[i] = temp;
|
||||
++Count;
|
||||
} while (result->NextRow());
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded %u CreatureEventAI summon definitions", Count);
|
||||
}
|
||||
else
|
||||
{
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded 0 CreatureEventAI Summon definitions. DB table `creature_ai_summons` is empty.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// -------------------
|
||||
void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
|
||||
{
|
||||
//Drop Existing EventAI List
|
||||
m_CreatureEventAI_Event_Map.clear();
|
||||
|
||||
// Gather event data
|
||||
QueryResult_AutoPtr result = WorldDatabase.Query("SELECT id, creature_id, event_type, event_inverse_phase_mask, event_chance, event_flags, "
|
||||
"event_param1, event_param2, event_param3, event_param4, "
|
||||
"action1_type, action1_param1, action1_param2, action1_param3, "
|
||||
"action2_type, action2_param1, action2_param2, action2_param3, "
|
||||
"action3_type, action3_param1, action3_param2, action3_param3 "
|
||||
"FROM creature_ai_scripts");
|
||||
if (result)
|
||||
{
|
||||
barGoLink bar(result->GetRowCount());
|
||||
uint32 Count = 0;
|
||||
|
||||
do
|
||||
{
|
||||
bar.step();
|
||||
Field *fields = result->Fetch();
|
||||
|
||||
CreatureEventAI_Event temp;
|
||||
temp.event_id = EventAI_Type(fields[0].GetUInt32());
|
||||
uint32 i = temp.event_id;
|
||||
|
||||
temp.creature_id = fields[1].GetUInt32();
|
||||
uint32 creature_id = temp.creature_id;
|
||||
|
||||
uint32 e_type = fields[2].GetUInt32();
|
||||
//Report any errors in event
|
||||
if (e_type >= EVENT_T_END)
|
||||
{
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u have wrong type (%u), skipping.", i,e_type);
|
||||
continue;
|
||||
}
|
||||
temp.event_type = EventAI_Type(e_type);
|
||||
|
||||
temp.event_inverse_phase_mask = fields[3].GetUInt32();
|
||||
temp.event_chance = fields[4].GetUInt8();
|
||||
temp.event_flags = fields[5].GetUInt8();
|
||||
temp.raw.param1 = fields[6].GetUInt32();
|
||||
temp.raw.param2 = fields[7].GetUInt32();
|
||||
temp.raw.param3 = fields[8].GetUInt32();
|
||||
temp.raw.param4 = fields[9].GetUInt32();
|
||||
|
||||
//Creature does not exist in database
|
||||
if (!sCreatureStorage.LookupEntry<CreatureInfo>(temp.creature_id))
|
||||
{
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u has script for non-existing creature entry (%u), skipping.", i, temp.creature_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
//No chance of this event occuring
|
||||
if (temp.event_chance == 0)
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u has 0 percent chance. Event will never trigger!", i);
|
||||
//Chance above 100, force it to be 100
|
||||
else if (temp.event_chance > 100)
|
||||
{
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using event %u with more than 100 percent chance. Adjusting to 100 percent.", temp.creature_id, i);
|
||||
temp.event_chance = 100;
|
||||
}
|
||||
|
||||
//Individual event checks
|
||||
switch (temp.event_type)
|
||||
{
|
||||
case EVENT_T_TIMER:
|
||||
case EVENT_T_TIMER_OOC:
|
||||
if (temp.timer.initialMax < temp.timer.initialMin)
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using timed event(%u) with param2 < param1 (InitialMax < InitialMin). Event will never repeat.", temp.creature_id, i);
|
||||
if (temp.timer.repeatMax < temp.timer.repeatMin)
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
|
||||
break;
|
||||
case EVENT_T_HP:
|
||||
case EVENT_T_MANA:
|
||||
case EVENT_T_TARGET_HP:
|
||||
case EVENT_T_TARGET_MANA:
|
||||
if (temp.percent_range.percentMax > 100)
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using percentage event(%u) with param2 (MinPercent) > 100. Event will never trigger! ", temp.creature_id, i);
|
||||
|
||||
if (temp.percent_range.percentMax <= temp.percent_range.percentMin)
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using percentage event(%u) with param1 <= param2 (MaxPercent <= MinPercent). Event will never trigger! ", temp.creature_id, i);
|
||||
|
||||
if (temp.event_flags & EFLAG_REPEATABLE && !temp.percent_range.repeatMin && !temp.percent_range.repeatMax)
|
||||
{
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u has param3 and param4=0 (RepeatMin/RepeatMax) but cannot be repeatable without timers. Removing EFLAG_REPEATABLE for event %u.", temp.creature_id, i);
|
||||
temp.event_flags &= ~EFLAG_REPEATABLE;
|
||||
}
|
||||
break;
|
||||
case EVENT_T_SPELLHIT:
|
||||
if (temp.spell_hit.spellId)
|
||||
{
|
||||
SpellEntry const* pSpell = sSpellStore.LookupEntry(temp.spell_hit.spellId);
|
||||
if (!pSpell)
|
||||
{
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u has non-existant SpellID(%u) defined in event %u.", temp.creature_id, temp.spell_hit.spellId, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((temp.spell_hit.schoolMask & pSpell->SchoolMask) != pSpell->SchoolMask)
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u has param1(spellId %u) but param2 is not -1 and not equal to spell's school mask. Event %u can never trigger.", temp.creature_id, temp.spell_hit.schoolMask, i);
|
||||
}
|
||||
|
||||
if (!temp.spell_hit.schoolMask)
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u is using invalid SpellSchoolMask(%u) defined in event %u.", temp.creature_id, temp.spell_hit.schoolMask, i);
|
||||
|
||||
if (temp.spell_hit.repeatMax < temp.spell_hit.repeatMin)
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
|
||||
break;
|
||||
case EVENT_T_RANGE:
|
||||
if (temp.range.maxDist < temp.range.minDist)
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with param2 < param1 (MaxDist < MinDist). Event will never repeat.", temp.creature_id, i);
|
||||
if (temp.range.repeatMax < temp.range.repeatMin)
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
|
||||
break;
|
||||
case EVENT_T_OOC_LOS:
|
||||
if (temp.ooc_los.repeatMax < temp.ooc_los.repeatMin)
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
|
||||
break;
|
||||
case EVENT_T_SPAWNED:
|
||||
switch(temp.spawned.condition)
|
||||
{
|
||||
case SPAWNED_EVENT_ALWAY:
|
||||
break;
|
||||
case SPAWNED_EVENT_MAP:
|
||||
if (!sMapStore.LookupEntry(temp.spawned.conditionValue1))
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using spawned event(%u) with param1 = %u 'map specific' but with not existed map (%u) in param2. Event will never repeat.", temp.creature_id, i, temp.spawned.condition, temp.spawned.conditionValue1);
|
||||
break;
|
||||
case SPAWNED_EVENT_ZONE:
|
||||
if (!GetAreaEntryByAreaID(temp.spawned.conditionValue1))
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using spawned event(%u) with param1 = %u 'area specific' but with not existed area (%u) in param2. Event will never repeat.", temp.creature_id, i, temp.spawned.condition, temp.spawned.conditionValue1);
|
||||
default:
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using invalid spawned event %u mode (%u) in param1", temp.creature_id, i, temp.spawned.condition);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case EVENT_T_FRIENDLY_HP:
|
||||
if (temp.friendly_hp.repeatMax < temp.friendly_hp.repeatMin)
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
|
||||
break;
|
||||
case EVENT_T_FRIENDLY_IS_CC:
|
||||
if (temp.friendly_is_cc.repeatMax < temp.friendly_is_cc.repeatMin)
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
|
||||
break;
|
||||
case EVENT_T_FRIENDLY_MISSING_BUFF:
|
||||
{
|
||||
SpellEntry const* pSpell = sSpellStore.LookupEntry(temp.spell_hit.spellId);
|
||||
if (!pSpell)
|
||||
{
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u has non-existant SpellID(%u) defined in event %u.", temp.creature_id, temp.spell_hit.spellId, i);
|
||||
continue;
|
||||
}
|
||||
if (temp.friendly_buff.repeatMax < temp.friendly_buff.repeatMin)
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
|
||||
break;
|
||||
}
|
||||
case EVENT_T_KILL:
|
||||
if (temp.kill.repeatMax < temp.kill.repeatMin)
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with param2 < param1 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
|
||||
break;
|
||||
case EVENT_T_TARGET_CASTING:
|
||||
if (temp.target_casting.repeatMax < temp.target_casting.repeatMin)
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with param2 < param1 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
|
||||
break;
|
||||
case EVENT_T_SUMMONED_UNIT:
|
||||
if (!sCreatureStorage.LookupEntry<CreatureInfo>(temp.summon_unit.creatureId))
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with not existed creature template id (%u) in param1, skipped.", temp.creature_id, i, temp.summon_unit.creatureId);
|
||||
if (temp.summon_unit.repeatMax < temp.summon_unit.repeatMin)
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with param2 < param1 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
|
||||
break;
|
||||
case EVENT_T_QUEST_ACCEPT:
|
||||
case EVENT_T_QUEST_COMPLETE:
|
||||
if (!objmgr.GetQuestTemplate(temp.quest.questId))
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with not existed qyest id (%u) in param1, skipped.", temp.creature_id, i, temp.quest.questId);
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u using not implemented event (%u) in event %u.", temp.creature_id, temp.event_id, i);
|
||||
continue;
|
||||
|
||||
case EVENT_T_AGGRO:
|
||||
case EVENT_T_DEATH:
|
||||
case EVENT_T_EVADE:
|
||||
case EVENT_T_REACHED_HOME:
|
||||
{
|
||||
if (temp.event_flags & EFLAG_REPEATABLE)
|
||||
{
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u has EFLAG_REPEATABLE set. Event can never be repeatable. Removing flag for event %u.", temp.creature_id, i);
|
||||
temp.event_flags &= ~EFLAG_REPEATABLE;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case EVENT_T_RECEIVE_EMOTE:
|
||||
{
|
||||
if (!sEmotesTextStore.LookupEntry(temp.receive_emote.emoteId))
|
||||
{
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: param1 (EmoteTextId: %u) are not valid.",temp.creature_id, i, temp.receive_emote.emoteId);
|
||||
continue;
|
||||
}
|
||||
if (temp.receive_emote.condition)
|
||||
{
|
||||
Condition* cond = new Condition();
|
||||
cond->mConditionType = ConditionType(temp.receive_emote.condition);
|
||||
cond->mConditionValue1 = temp.receive_emote.conditionValue1;
|
||||
cond->mConditionValue2 = temp.receive_emote.conditionValue2;
|
||||
if (!sConditionMgr.isConditionTypeValid(cond))
|
||||
{
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: param2 (Condition: %u) are not valid.",temp.creature_id, i, temp.receive_emote.condition);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(temp.event_flags & EFLAG_REPEATABLE))
|
||||
{
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: EFLAG_REPEATABLE not set. Event must always be repeatable. Flag applied.", temp.creature_id, i);
|
||||
temp.event_flags |= EFLAG_REPEATABLE;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case EVENT_T_BUFFED:
|
||||
case EVENT_T_TARGET_BUFFED:
|
||||
{
|
||||
SpellEntry const* pSpell = sSpellStore.LookupEntry(temp.buffed.spellId);
|
||||
if (!pSpell)
|
||||
{
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u has non-existant SpellID(%u) defined in event %u.", temp.creature_id, temp.spell_hit.spellId, i);
|
||||
continue;
|
||||
}
|
||||
if (temp.buffed.repeatMax < temp.buffed.repeatMin)
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
sLog.outErrorDb("CreatureEventAI: Creature %u using not checked at load event (%u) in event %u. Need check code update?", temp.creature_id, temp.event_id, i);
|
||||
break;
|
||||
}
|
||||
|
||||
for (uint32 j = 0; j < MAX_ACTIONS; j++)
|
||||
{
|
||||
uint16 action_type = fields[10+(j*4)].GetUInt16();
|
||||
if (action_type >= ACTION_T_END)
|
||||
{
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u has incorrect action type (%u), replace by ACTION_T_NONE.", i, j+1, action_type);
|
||||
temp.action[j].type = ACTION_T_NONE;
|
||||
continue;
|
||||
}
|
||||
|
||||
CreatureEventAI_Action& action = temp.action[j];
|
||||
|
||||
action.type = EventAI_ActionType(action_type);
|
||||
action.raw.param1 = fields[11+(j*4)].GetUInt32();
|
||||
action.raw.param2 = fields[12+(j*4)].GetUInt32();
|
||||
action.raw.param3 = fields[13+(j*4)].GetUInt32();
|
||||
|
||||
//Report any errors in actions
|
||||
switch (action.type)
|
||||
{
|
||||
case ACTION_T_NONE:
|
||||
break;
|
||||
case ACTION_T_TEXT:
|
||||
{
|
||||
if (action.text.TextId1 < 0)
|
||||
{
|
||||
if (m_CreatureEventAI_TextMap.find(action.text.TextId1) == m_CreatureEventAI_TextMap.end())
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 refrences non-existing entry in texts table.", i, j+1);
|
||||
}
|
||||
if (action.text.TextId2 < 0)
|
||||
{
|
||||
if (m_CreatureEventAI_TextMap.find(action.text.TextId2) == m_CreatureEventAI_TextMap.end())
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param2 refrences non-existing entry in texts table.", i, j+1);
|
||||
|
||||
if (!action.text.TextId1)
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u has param2, but param1 is not set. Required for randomized text.", i, j+1);
|
||||
}
|
||||
if (action.text.TextId3 < 0)
|
||||
{
|
||||
if (m_CreatureEventAI_TextMap.find(action.text.TextId3) == m_CreatureEventAI_TextMap.end())
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param3 refrences non-existing entry in texts table.", i, j+1);
|
||||
|
||||
if (!action.text.TextId1 || !action.text.TextId2)
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u has param3, but param1 and/or param2 is not set. Required for randomized text.", i, j+1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ACTION_T_SET_FACTION:
|
||||
if (action.set_faction.factionId !=0 && !sFactionStore.LookupEntry(action.set_faction.factionId))
|
||||
{
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent FactionId %u.", i, j+1, action.set_faction.factionId);
|
||||
action.set_faction.factionId = 0;
|
||||
}
|
||||
break;
|
||||
case ACTION_T_MORPH_TO_ENTRY_OR_MODEL:
|
||||
if (action.morph.creatureId !=0 || action.morph.modelId !=0)
|
||||
{
|
||||
if (action.morph.creatureId && !sCreatureStorage.LookupEntry<CreatureInfo>(action.morph.creatureId))
|
||||
{
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant Creature entry %u.", i, j+1, action.morph.creatureId);
|
||||
action.morph.creatureId = 0;
|
||||
}
|
||||
|
||||
if (action.morph.modelId)
|
||||
{
|
||||
if (action.morph.creatureId)
|
||||
{
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u have unused ModelId %u with also set creature id %u.", i, j+1, action.morph.modelId,action.morph.creatureId);
|
||||
action.morph.modelId = 0;
|
||||
}
|
||||
else if (!sCreatureDisplayInfoStore.LookupEntry(action.morph.modelId))
|
||||
{
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant ModelId %u.", i, j+1, action.morph.modelId);
|
||||
action.morph.modelId = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ACTION_T_SOUND:
|
||||
if (!sSoundEntriesStore.LookupEntry(action.sound.soundId))
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant SoundID %u.", i, j+1, action.sound.soundId);
|
||||
break;
|
||||
case ACTION_T_EMOTE:
|
||||
if (!sEmotesStore.LookupEntry(action.emote.emoteId))
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 (EmoteId: %u) are not valid.", i, j+1, action.emote.emoteId);
|
||||
break;
|
||||
case ACTION_T_RANDOM_SOUND:
|
||||
if (!sSoundEntriesStore.LookupEntry(action.random_sound.soundId1))
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 uses non-existant SoundID %u.", i, j+1, action.random_sound.soundId1);
|
||||
if (action.random_sound.soundId2 >= 0 && !sSoundEntriesStore.LookupEntry(action.random_sound.soundId2))
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param2 uses non-existant SoundID %u.", i, j+1, action.random_sound.soundId2);
|
||||
if (action.random_sound.soundId3 >= 0 && !sSoundEntriesStore.LookupEntry(action.random_sound.soundId3))
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param3 uses non-existant SoundID %u.", i, j+1, action.random_sound.soundId3);
|
||||
break;
|
||||
case ACTION_T_RANDOM_EMOTE:
|
||||
if (!sEmotesStore.LookupEntry(action.random_emote.emoteId1))
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 (EmoteId: %u) are not valid.", i, j+1, action.random_emote.emoteId1);
|
||||
if (action.random_emote.emoteId2 >= 0 && !sEmotesStore.LookupEntry(action.random_emote.emoteId2))
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param2 (EmoteId: %u) are not valid.", i, j+1, action.random_emote.emoteId2);
|
||||
if (action.random_emote.emoteId3 >= 0 && !sEmotesStore.LookupEntry(action.random_emote.emoteId3))
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param3 (EmoteId: %u) are not valid.", i, j+1, action.random_emote.emoteId3);
|
||||
break;
|
||||
case ACTION_T_CAST:
|
||||
{
|
||||
const SpellEntry *spell = sSpellStore.LookupEntry(action.cast.spellId);
|
||||
if (!spell)
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent SpellID %u.", i, j+1, action.cast.spellId);
|
||||
/* FIXME: temp.raw.param3 not have event tipes with recovery time in it....
|
||||
else
|
||||
{
|
||||
if (spell->RecoveryTime > 0 && temp.event_flags & EFLAG_REPEATABLE)
|
||||
{
|
||||
//output as debug for now, also because there's no general rule all spells have RecoveryTime
|
||||
if (temp.event_param3 < spell->RecoveryTime)
|
||||
sLog.outDebug("CreatureEventAI: Event %u Action %u uses SpellID %u but cooldown is longer(%u) than minumum defined in event param3(%u).", i, j+1,action.cast.spellId, spell->RecoveryTime, temp.event_param3);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
//Cast is always triggered if target is forced to cast on self
|
||||
if (action.cast.castFlags & CAST_FORCE_TARGET_SELF)
|
||||
action.cast.castFlags |= CAST_TRIGGERED;
|
||||
|
||||
if (action.cast.target >= TARGET_T_END)
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
|
||||
break;
|
||||
}
|
||||
case ACTION_T_SUMMON:
|
||||
if (!sCreatureStorage.LookupEntry<CreatureInfo>(action.summon.creatureId))
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent creature entry %u.", i, j+1, action.summon.creatureId);
|
||||
|
||||
if (action.summon.target >= TARGET_T_END)
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
|
||||
break;
|
||||
case ACTION_T_THREAT_SINGLE_PCT:
|
||||
if (std::abs(action.threat_single_pct.percent) > 100)
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses invalid percent value %u.", i, j+1, action.threat_single_pct.percent);
|
||||
if (action.threat_single_pct.target >= TARGET_T_END)
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
|
||||
break;
|
||||
case ACTION_T_THREAT_ALL_PCT:
|
||||
if (std::abs(action.threat_all_pct.percent) > 100)
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses invalid percent value %u.", i, j+1, action.threat_all_pct.percent);
|
||||
break;
|
||||
case ACTION_T_QUEST_EVENT:
|
||||
if (Quest const* qid = objmgr.GetQuestTemplate(action.quest_event.questId))
|
||||
{
|
||||
if (!qid->HasFlag(QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT))
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u. SpecialFlags for quest entry %u does not include |2, Action will not have any effect.", i, j+1, action.quest_event.questId);
|
||||
}
|
||||
else
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent Quest entry %u.", i, j+1, action.quest_event.questId);
|
||||
|
||||
if (action.quest_event.target >= TARGET_T_END)
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
|
||||
|
||||
break;
|
||||
case ACTION_T_CAST_EVENT:
|
||||
if (!sCreatureStorage.LookupEntry<CreatureInfo>(action.cast_event.creatureId))
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent creature entry %u.", i, j+1, action.cast_event.creatureId);
|
||||
if (!sSpellStore.LookupEntry(action.cast_event.spellId))
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent SpellID %u.", i, j+1, action.cast_event.spellId);
|
||||
if (action.cast_event.target >= TARGET_T_END)
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
|
||||
break;
|
||||
case ACTION_T_SET_UNIT_FIELD:
|
||||
if (action.set_unit_field.field < OBJECT_END || action.set_unit_field.field >= UNIT_END)
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 (UNIT_FIELD*). Index out of range for intended use.", i, j+1);
|
||||
if (action.set_unit_field.target >= TARGET_T_END)
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
|
||||
break;
|
||||
case ACTION_T_SET_UNIT_FLAG:
|
||||
case ACTION_T_REMOVE_UNIT_FLAG:
|
||||
if (action.unit_flag.target >= TARGET_T_END)
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
|
||||
break;
|
||||
case ACTION_T_SET_PHASE:
|
||||
if (action.set_phase.phase >= MAX_PHASE)
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set phase >= %u. Phase mask cannot be used past phase %u.", i, j+1, MAX_PHASE, MAX_PHASE-1);
|
||||
break;
|
||||
case ACTION_T_INC_PHASE:
|
||||
if (action.set_inc_phase.step == 0)
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u is incrementing phase by 0. Was this intended?", i, j+1);
|
||||
else if (std::abs(action.set_inc_phase.step) > MAX_PHASE-1)
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u is change phase by too large for any use %i.", i, j+1, action.set_inc_phase.step);
|
||||
break;
|
||||
case ACTION_T_QUEST_EVENT_ALL:
|
||||
if (Quest const* qid = objmgr.GetQuestTemplate(action.quest_event_all.questId))
|
||||
{
|
||||
if (!qid->HasFlag(QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT))
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u. SpecialFlags for quest entry %u does not include |2, Action will not have any effect.", i, j+1, action.quest_event_all.questId);
|
||||
}
|
||||
else
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent Quest entry %u.", i, j+1, action.quest_event_all.questId);
|
||||
break;
|
||||
case ACTION_T_CAST_EVENT_ALL:
|
||||
if (!sCreatureStorage.LookupEntry<CreatureInfo>(action.cast_event_all.creatureId))
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent creature entry %u.", i, j+1, action.cast_event_all.creatureId);
|
||||
if (!sSpellStore.LookupEntry(action.cast_event_all.spellId))
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent SpellID %u.", i, j+1, action.cast_event_all.spellId);
|
||||
break;
|
||||
case ACTION_T_REMOVEAURASFROMSPELL:
|
||||
if (!sSpellStore.LookupEntry(action.remove_aura.spellId))
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent SpellID %u.", i, j+1, action.remove_aura.spellId);
|
||||
if (action.remove_aura.target >= TARGET_T_END)
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
|
||||
break;
|
||||
case ACTION_T_RANDOM_PHASE: //PhaseId1, PhaseId2, PhaseId3
|
||||
if (action.random_phase.phase1 >= MAX_PHASE)
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set phase1 >= %u. Phase mask cannot be used past phase %u.", i, j+1, MAX_PHASE, MAX_PHASE-1);
|
||||
if (action.random_phase.phase2 >= MAX_PHASE)
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set phase2 >= %u. Phase mask cannot be used past phase %u.", i, j+1, MAX_PHASE, MAX_PHASE-1);
|
||||
if (action.random_phase.phase3 >= MAX_PHASE)
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set phase3 >= %u. Phase mask cannot be used past phase %u.", i, j+1, MAX_PHASE, MAX_PHASE-1);
|
||||
break;
|
||||
case ACTION_T_RANDOM_PHASE_RANGE: //PhaseMin, PhaseMax
|
||||
if (action.random_phase_range.phaseMin >= MAX_PHASE)
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set phaseMin >= %u. Phase mask cannot be used past phase %u.", i, j+1, MAX_PHASE, MAX_PHASE-1);
|
||||
if (action.random_phase_range.phaseMin >= MAX_PHASE)
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set phaseMax >= %u. Phase mask cannot be used past phase %u.", i, j+1, MAX_PHASE, MAX_PHASE-1);
|
||||
if (action.random_phase_range.phaseMin >= action.random_phase_range.phaseMax)
|
||||
{
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set phaseMax <= phaseMin.", i, j+1);
|
||||
std::swap(action.random_phase_range.phaseMin,action.random_phase_range.phaseMax);
|
||||
// equal case processed at call
|
||||
}
|
||||
break;
|
||||
case ACTION_T_SUMMON_ID:
|
||||
if (!sCreatureStorage.LookupEntry<CreatureInfo>(action.summon_id.creatureId))
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, action.summon_id.creatureId);
|
||||
if (action.summon_id.target >= TARGET_T_END)
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
|
||||
if (m_CreatureEventAI_Summon_Map.find(action.summon_id.spawnId) == m_CreatureEventAI_Summon_Map.end())
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u summons missing CreatureEventAI_Summon %u", i, j+1, action.summon_id.spawnId);
|
||||
break;
|
||||
case ACTION_T_KILLED_MONSTER:
|
||||
if (!sCreatureStorage.LookupEntry<CreatureInfo>(action.killed_monster.creatureId))
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, action.killed_monster.creatureId);
|
||||
if (action.killed_monster.target >= TARGET_T_END)
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
|
||||
break;
|
||||
case ACTION_T_SET_INST_DATA:
|
||||
if (!(temp.event_flags & EFLAG_DIFFICULTY_ALL))
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u. Cannot set instance data without difficulty event flags.", i, j+1);
|
||||
if (action.set_inst_data.value > 4/*SPECIAL*/)
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set instance data above encounter state 4. Custom case?", i, j+1);
|
||||
break;
|
||||
case ACTION_T_SET_INST_DATA64:
|
||||
if (!(temp.event_flags & EFLAG_DIFFICULTY_ALL))
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u. Cannot set instance data without difficulty event flags.", i, j+1);
|
||||
if (action.set_inst_data64.target >= TARGET_T_END)
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
|
||||
break;
|
||||
case ACTION_T_UPDATE_TEMPLATE:
|
||||
if (!sCreatureStorage.LookupEntry<CreatureInfo>(action.update_template.creatureId))
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, action.update_template.creatureId);
|
||||
break;
|
||||
case ACTION_T_SET_SHEATH:
|
||||
if (action.set_sheath.sheath >= MAX_SHEATH_STATE)
|
||||
{
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses wrong sheath state %u.", i, j+1, action.set_sheath.sheath);
|
||||
action.set_sheath.sheath = SHEATH_STATE_UNARMED;
|
||||
}
|
||||
break;
|
||||
case ACTION_T_SET_INVINCIBILITY_HP_LEVEL:
|
||||
if (action.invincibility_hp_level.is_percent)
|
||||
{
|
||||
if (action.invincibility_hp_level.hp_level > 100)
|
||||
{
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses wrong percent value %u.", i, j+1, action.invincibility_hp_level.hp_level);
|
||||
action.invincibility_hp_level.hp_level = 100;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ACTION_T_EVADE: //No Params
|
||||
case ACTION_T_FLEE_FOR_ASSIST: //No Params
|
||||
case ACTION_T_DIE: //No Params
|
||||
case ACTION_T_ZONE_COMBAT_PULSE: //No Params
|
||||
case ACTION_T_FORCE_DESPAWN: //No Params
|
||||
case ACTION_T_AUTO_ATTACK: //AllowAttackState (0 = stop attack, anything else means continue attacking)
|
||||
case ACTION_T_COMBAT_MOVEMENT: //AllowCombatMovement (0 = stop combat based movement, anything else continue attacking)
|
||||
case ACTION_T_RANGED_MOVEMENT: //Distance, Angle
|
||||
case ACTION_T_CALL_FOR_HELP: //Distance
|
||||
break;
|
||||
|
||||
case ACTION_T_RANDOM_SAY:
|
||||
case ACTION_T_RANDOM_YELL:
|
||||
case ACTION_T_RANDOM_TEXTEMOTE:
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u currently unused ACTION type. Did you forget to update database?", i, j+1);
|
||||
break;
|
||||
|
||||
case ACTION_T_MOVE_RANDOM_POINT:
|
||||
case ACTION_T_SET_STAND_STATE:
|
||||
case ACTION_T_SET_PHASE_MASK:
|
||||
case ACTION_T_SET_VISIBILITY:
|
||||
case ACTION_T_SET_ACTIVE:
|
||||
case ACTION_T_SET_AGGRESSIVE:
|
||||
case ACTION_T_ATTACK_START_PULSE:
|
||||
case ACTION_T_SUMMON_GO:
|
||||
break;
|
||||
|
||||
default:
|
||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u have currently not checked at load action type (%u). Need check code update?", i, j+1, temp.action[j].type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Add to list
|
||||
m_CreatureEventAI_Event_Map[creature_id].push_back(temp);
|
||||
++Count;
|
||||
|
||||
if (CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(temp.creature_id))
|
||||
{
|
||||
if (!cInfo->AIName || !cInfo->AIName[0])
|
||||
{
|
||||
//sLog.outErrorDb("CreatureEventAI: Creature Entry %u has EventAI script but its AIName is empty. Set to EventAI as default.", cInfo->Entry);
|
||||
size_t len = strlen("EventAI")+1;
|
||||
const_cast<CreatureInfo*>(cInfo)->AIName = new char[len];
|
||||
strncpy(const_cast<char*>(cInfo->AIName), "EventAI", len);
|
||||
}
|
||||
if (strcmp(cInfo->AIName, "EventAI"))
|
||||
{
|
||||
//sLog.outErrorDb("CreatureEventAI: Creature Entry %u has EventAI script but it has AIName %s. EventAI script will be overriden.", cInfo->Entry, cInfo->AIName);
|
||||
}
|
||||
if (cInfo->ScriptID)
|
||||
{
|
||||
//sLog.outErrorDb("CreatureEventAI: Creature Entry %u has EventAI script but it also has C++ script. EventAI script will be overriden.", cInfo->Entry);
|
||||
}
|
||||
}
|
||||
} while (result->NextRow());
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded %u CreatureEventAI scripts", Count);
|
||||
}
|
||||
else
|
||||
{
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded 0 CreatureEventAI scripts. DB table `creature_ai_scripts` is empty.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_CREATURE_EAI_MGR_H
|
||||
#define TRINITY_CREATURE_EAI_MGR_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "CreatureEventAI.h"
|
||||
|
||||
class CreatureEventAIMgr
|
||||
{
|
||||
public:
|
||||
CreatureEventAIMgr(){};
|
||||
~CreatureEventAIMgr(){};
|
||||
|
||||
void LoadCreatureEventAI_Texts();
|
||||
void LoadCreatureEventAI_Summons();
|
||||
void LoadCreatureEventAI_Scripts();
|
||||
|
||||
CreatureEventAI_Event_Map const& GetCreatureEventAIMap() const { return m_CreatureEventAI_Event_Map; }
|
||||
CreatureEventAI_Summon_Map const& GetCreatureEventAISummonMap() const { return m_CreatureEventAI_Summon_Map; }
|
||||
CreatureEventAI_TextMap const& GetCreatureEventAITextMap() const { return m_CreatureEventAI_TextMap; }
|
||||
|
||||
private:
|
||||
CreatureEventAI_Event_Map m_CreatureEventAI_Event_Map;
|
||||
CreatureEventAI_Summon_Map m_CreatureEventAI_Summon_Map;
|
||||
CreatureEventAI_TextMap m_CreatureEventAI_TextMap;
|
||||
};
|
||||
|
||||
#define CreatureEAI_Mgr Trinity::Singleton<CreatureEventAIMgr>::Instance()
|
||||
#endif
|
||||
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Creature.h"
|
||||
#include "CreatureGroups.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "ProgressBar.h"
|
||||
#include "Policies/SingletonImp.h"
|
||||
#include "CreatureAI.h"
|
||||
|
||||
#define MAX_DESYNC 5.0f
|
||||
|
||||
INSTANTIATE_SINGLETON_1(CreatureGroupManager);
|
||||
|
||||
CreatureGroupInfoType CreatureGroupMap;
|
||||
|
||||
void CreatureGroupManager::AddCreatureToGroup(uint32 groupId, Creature *member)
|
||||
{
|
||||
Map *map = member->FindMap();
|
||||
if (!map)
|
||||
return;
|
||||
|
||||
CreatureGroupHolderType::iterator itr = map->CreatureGroupHolder.find(groupId);
|
||||
|
||||
//Add member to an existing group
|
||||
if (itr != map->CreatureGroupHolder.end())
|
||||
{
|
||||
sLog.outDebug("Group found: %u, inserting creature GUID: %u, Group InstanceID %u", groupId, member->GetGUIDLow(), member->GetInstanceId());
|
||||
itr->second->AddMember(member);
|
||||
}
|
||||
//Create new group
|
||||
else
|
||||
{
|
||||
sLog.outDebug("Group not found: %u. Creating new group.", groupId);
|
||||
CreatureGroup* group = new CreatureGroup(groupId);
|
||||
map->CreatureGroupHolder[groupId] = group;
|
||||
group->AddMember(member);
|
||||
}
|
||||
}
|
||||
|
||||
void CreatureGroupManager::RemoveCreatureFromGroup(CreatureGroup *group, Creature *member)
|
||||
{
|
||||
sLog.outDebug("Deleting member pointer to GUID: %u from group %u", group->GetId(), member->GetDBTableGUIDLow());
|
||||
group->RemoveMember(member);
|
||||
|
||||
if (group->isEmpty())
|
||||
{
|
||||
Map *map = member->FindMap();
|
||||
if (!map)
|
||||
return;
|
||||
|
||||
sLog.outDebug("Deleting group with InstanceID %u", member->GetInstanceId());
|
||||
map->CreatureGroupHolder.erase(group->GetId());
|
||||
delete group;
|
||||
}
|
||||
}
|
||||
|
||||
void CreatureGroupManager::LoadCreatureFormations()
|
||||
{
|
||||
//Clear existing map
|
||||
CreatureGroupMap.clear();
|
||||
|
||||
//Check Integrity of the table
|
||||
QueryResult_AutoPtr result = WorldDatabase.Query("SELECT MAX(leaderGUID) FROM creature_formations");
|
||||
|
||||
if (!result)
|
||||
{
|
||||
sLog.outErrorDb(" ...an error occured while loading the table creature_formations (maybe it doesn't exist ?)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
//Get group data
|
||||
result = WorldDatabase.Query("SELECT leaderGUID, memberGUID, dist, angle, groupAI FROM creature_formations ORDER BY leaderGUID");
|
||||
|
||||
if (!result)
|
||||
{
|
||||
sLog.outErrorDb("The table creature_formations is empty or corrupted");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 total_records = result->GetRowCount();
|
||||
barGoLink bar(total_records);
|
||||
Field *fields;
|
||||
|
||||
FormationInfo *group_member;
|
||||
//Loading data...
|
||||
do
|
||||
{
|
||||
fields = result->Fetch();
|
||||
|
||||
bar.step();
|
||||
//Load group member data
|
||||
group_member = new FormationInfo;
|
||||
group_member->leaderGUID = fields[0].GetUInt32();
|
||||
uint32 memberGUID = fields[1].GetUInt32();
|
||||
group_member->groupAI = fields[4].GetUInt8();
|
||||
//If creature is group leader we may skip loading of dist/angle
|
||||
if (group_member->leaderGUID != memberGUID)
|
||||
{
|
||||
group_member->follow_dist = fields[2].GetFloat();
|
||||
group_member->follow_angle = fields[3].GetFloat() * M_PI / 180;
|
||||
}
|
||||
else
|
||||
{
|
||||
group_member->follow_dist = 0;
|
||||
group_member->follow_angle = 0;
|
||||
}
|
||||
|
||||
// check data correctness
|
||||
{
|
||||
QueryResult_AutoPtr result = WorldDatabase.PQuery("SELECT guid FROM creature WHERE guid = %u", group_member->leaderGUID);
|
||||
if (!result)
|
||||
{
|
||||
sLog.outErrorDb("creature_formations table leader guid %u incorrect (not exist)", group_member->leaderGUID);
|
||||
delete group_member;
|
||||
continue;
|
||||
}
|
||||
|
||||
result = WorldDatabase.PQuery("SELECT guid FROM creature WHERE guid = %u", memberGUID);
|
||||
if (!result)
|
||||
{
|
||||
sLog.outErrorDb("creature_formations table member guid %u incorrect (not exist)", memberGUID);
|
||||
delete group_member;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
CreatureGroupMap[memberGUID] = group_member;
|
||||
}
|
||||
while (result->NextRow()) ;
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded %u creatures in formations", total_records);
|
||||
sLog.outString();
|
||||
}
|
||||
|
||||
void CreatureGroup::AddMember(Creature *member)
|
||||
{
|
||||
sLog.outDebug("CreatureGroup::AddMember: Adding unit GUID: %u.", member->GetGUIDLow());
|
||||
|
||||
//Check if it is a leader
|
||||
if (member->GetDBTableGUIDLow() == m_groupID)
|
||||
{
|
||||
sLog.outDebug("Unit GUID: %u is formation leader. Adding group.", member->GetGUIDLow());
|
||||
m_leader = member;
|
||||
}
|
||||
|
||||
m_members[member] = CreatureGroupMap.find(member->GetDBTableGUIDLow())->second;
|
||||
member->SetFormation(this);
|
||||
}
|
||||
|
||||
void CreatureGroup::RemoveMember(Creature *member)
|
||||
{
|
||||
if (m_leader == member)
|
||||
m_leader = NULL;
|
||||
|
||||
m_members.erase(member);
|
||||
member->SetFormation(NULL);
|
||||
}
|
||||
|
||||
void CreatureGroup::MemberAttackStart(Creature *member, Unit *target)
|
||||
{
|
||||
uint8 groupAI = CreatureGroupMap[member->GetDBTableGUIDLow()]->groupAI;
|
||||
if (!groupAI)
|
||||
return;
|
||||
|
||||
if (groupAI == 1 && member != m_leader)
|
||||
return;
|
||||
|
||||
for (CreatureGroupMemberType::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
|
||||
{
|
||||
if (m_leader) // avoid crash if leader was killed and reset.
|
||||
sLog.outDebug("GROUP ATTACK: group instance id %u calls member instid %u", m_leader->GetInstanceId(), member->GetInstanceId());
|
||||
|
||||
//Skip one check
|
||||
if (itr->first == member)
|
||||
continue;
|
||||
|
||||
if (!itr->first->isAlive())
|
||||
continue;
|
||||
|
||||
if (itr->first->getVictim())
|
||||
continue;
|
||||
|
||||
if (itr->first->canAttack(target) && itr->first->AI())
|
||||
itr->first->AI()->AttackStart(target);
|
||||
}
|
||||
}
|
||||
|
||||
void CreatureGroup::FormationReset(bool dismiss)
|
||||
{
|
||||
for (CreatureGroupMemberType::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
|
||||
{
|
||||
if (itr->first != m_leader && itr->first->isAlive())
|
||||
{
|
||||
if (dismiss)
|
||||
itr->first->GetMotionMaster()->Initialize();
|
||||
else
|
||||
itr->first->GetMotionMaster()->MoveIdle(MOTION_SLOT_IDLE);
|
||||
sLog.outDebug("Set %s movement for member GUID: %u", dismiss ? "default" : "idle", itr->first->GetGUIDLow());
|
||||
}
|
||||
}
|
||||
m_Formed = !dismiss;
|
||||
}
|
||||
|
||||
void CreatureGroup::LeaderMoveTo(float x, float y, float z)
|
||||
{
|
||||
if (!m_leader)
|
||||
return;
|
||||
|
||||
float pathangle = atan2(m_leader->GetPositionY() - y, m_leader->GetPositionX() - x);
|
||||
|
||||
for (CreatureGroupMemberType::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
|
||||
{
|
||||
Creature *member = itr->first;
|
||||
if (member == m_leader || !member->isAlive() || member->getVictim())
|
||||
continue;
|
||||
|
||||
float angle = itr->second->follow_angle;
|
||||
float dist = itr->second->follow_dist;
|
||||
|
||||
float dx = x + cos(angle + pathangle) * dist;
|
||||
float dy = y + sin(angle + pathangle) * dist;
|
||||
float dz = z;
|
||||
|
||||
Trinity::NormalizeMapCoord(dx);
|
||||
Trinity::NormalizeMapCoord(dy);
|
||||
|
||||
member->UpdateGroundPositionZ(dx, dy, dz);
|
||||
|
||||
if (member->IsWithinDist(m_leader, dist + MAX_DESYNC))
|
||||
member->SetUnitMovementFlags(m_leader->GetUnitMovementFlags());
|
||||
else
|
||||
member->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
|
||||
|
||||
member->GetMotionMaster()->MovePoint(0, dx, dy, dz);
|
||||
member->SetHomePosition(dx, dy, dz, pathangle);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _FORMATIONS_H
|
||||
#define _FORMATIONS_H
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
class CreatureGroup;
|
||||
|
||||
struct FormationInfo
|
||||
{
|
||||
uint32 leaderGUID;
|
||||
float follow_dist;
|
||||
float follow_angle;
|
||||
uint8 groupAI;
|
||||
};
|
||||
|
||||
class CreatureGroupManager
|
||||
{
|
||||
public:
|
||||
void AddCreatureToGroup(uint32 group_id, Creature *creature);
|
||||
void RemoveCreatureFromGroup(CreatureGroup *group, Creature *creature);
|
||||
void LoadCreatureFormations();
|
||||
};
|
||||
|
||||
typedef UNORDERED_MAP<uint32/*memberDBGUID*/, FormationInfo*> CreatureGroupInfoType;
|
||||
|
||||
extern CreatureGroupInfoType CreatureGroupMap;
|
||||
|
||||
class CreatureGroup
|
||||
{
|
||||
private:
|
||||
Creature *m_leader; //Important do not forget sometimes to work with pointers instead synonims :D:D
|
||||
typedef std::map<Creature*, FormationInfo*> CreatureGroupMemberType;
|
||||
CreatureGroupMemberType m_members;
|
||||
|
||||
uint32 m_groupID;
|
||||
bool m_Formed;
|
||||
|
||||
public:
|
||||
//Group cannot be created empty
|
||||
explicit CreatureGroup(uint32 id) : m_groupID(id), m_leader(NULL), m_Formed(false) {}
|
||||
~CreatureGroup() { sLog.outDebug("Destroying group"); }
|
||||
|
||||
Creature* getLeader() const { return m_leader; }
|
||||
uint32 GetId() const { return m_groupID; }
|
||||
bool isEmpty() const { return m_members.empty(); }
|
||||
bool isFormed() const { return m_Formed; }
|
||||
|
||||
void AddMember(Creature *member);
|
||||
void RemoveMember(Creature *member);
|
||||
void FormationReset(bool dismiss);
|
||||
|
||||
void LeaderMoveTo(float x, float y, float z);
|
||||
void MemberAttackStart(Creature* member, Unit *target);
|
||||
};
|
||||
|
||||
#define formation_mgr Trinity::Singleton<CreatureGroupManager>::Instance()
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,397 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef DBCENUMS_H
|
||||
#define DBCENUMS_H
|
||||
|
||||
// Client expected level limitation, like as used in DBC item max levels for "until max player level"
|
||||
// use as default max player level, must be fit max level for used client
|
||||
// also see MAX_LEVEL and STRONG_MAX_LEVEL define
|
||||
#define DEFAULT_MAX_LEVEL 80
|
||||
|
||||
// client supported max level for player/pets/etc. Avoid overflow or client stability affected.
|
||||
// also see GT_MAX_LEVEL define
|
||||
#define MAX_LEVEL 100
|
||||
|
||||
// Server side limitation. Base at used code requirements.
|
||||
// also see MAX_LEVEL and GT_MAX_LEVEL define
|
||||
#define STRONG_MAX_LEVEL 255
|
||||
|
||||
enum BattleGroundBracketId // bracketId for level ranges
|
||||
{
|
||||
BG_BRACKET_ID_FIRST = 0,
|
||||
BG_BRACKET_ID_LAST = 15
|
||||
};
|
||||
|
||||
// must be max value in PvPDificulty slot+1
|
||||
#define MAX_BATTLEGROUND_BRACKETS 16
|
||||
|
||||
enum AreaTeams
|
||||
{
|
||||
AREATEAM_NONE = 0,
|
||||
AREATEAM_ALLY = 2,
|
||||
AREATEAM_HORDE = 4
|
||||
};
|
||||
|
||||
enum AchievementFaction
|
||||
{
|
||||
ACHIEVEMENT_FACTION_HORDE = 0,
|
||||
ACHIEVEMENT_FACTION_ALLIANCE = 1,
|
||||
ACHIEVEMENT_FACTION_ANY = -1,
|
||||
};
|
||||
|
||||
enum AchievementFlags
|
||||
{
|
||||
ACHIEVEMENT_FLAG_COUNTER = 0x00000001, // Just count statistic (never stop and complete)
|
||||
ACHIEVEMENT_FLAG_TRACKING = 0x00000002, // Not sent to client - internal use only
|
||||
ACHIEVEMENT_FLAG_STORE_MAX_VALUE = 0x00000004, // Store only max value? used only in "Reach level xx"
|
||||
ACHIEVEMENT_FLAG_SUMM = 0x00000008, // Use summ criteria value from all reqirements (and calculate max value)
|
||||
ACHIEVEMENT_FLAG_MAX_USED = 0x00000010, // Show max criteria (and calculate max value ??)
|
||||
ACHIEVEMENT_FLAG_REQ_COUNT = 0x00000020, // Use not zero req count (and calculate max value)
|
||||
ACHIEVEMENT_FLAG_AVERAGE = 0x00000040, // Show as average value (value / time_in_days) depend from other flag (by def use last criteria value)
|
||||
ACHIEVEMENT_FLAG_BAR = 0x00000080, // Show as progress bar (value / max vale) depend from other flag (by def use last criteria value)
|
||||
ACHIEVEMENT_FLAG_REALM_FIRST_REACH = 0x00000100, //
|
||||
ACHIEVEMENT_FLAG_REALM_FIRST_KILL = 0x00000200, //
|
||||
};
|
||||
|
||||
enum AchievementCriteriaCondition
|
||||
{
|
||||
ACHIEVEMENT_CRITERIA_CONDITION_NONE = 0,
|
||||
ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH = 1,
|
||||
ACHIEVEMENT_CRITERIA_CONDITION_UNK1 = 2, // only used in "Complete a daily quest every day for five consecutive days"
|
||||
ACHIEVEMENT_CRITERIA_CONDITION_MAP = 3, // requires you to be on specific map
|
||||
ACHIEVEMENT_CRITERIA_CONDITION_NO_LOOSE = 4, // only used in "Win 10 arenas without losing"
|
||||
ACHIEVEMENT_CRITERIA_CONDITION_UNK2 = 9, // unk
|
||||
ACHIEVEMENT_CRITERIA_CONDITION_UNK3 = 13, // unk
|
||||
};
|
||||
|
||||
enum AchievementCriteriaCompletionFlags
|
||||
{
|
||||
ACHIEVEMENT_CRITERIA_FLAG_SHOW_PROGRESS_BAR = 0x00000001, // Show progress as bar
|
||||
ACHIEVEMENT_CRITERIA_FLAG_HIDE_CRITERIA = 0x00000002, // Not show criteria in client
|
||||
ACHIEVEMENT_CRITERIA_FLAG_UNK3 = 0x00000004, // BG related??
|
||||
ACHIEVEMENT_CRITERIA_FLAG_UNK4 = 0x00000008, //
|
||||
ACHIEVEMENT_CRITERIA_FLAG_UNK5 = 0x00000010, // not used
|
||||
ACHIEVEMENT_CRITERIA_FLAG_MONEY_COUNTER = 0x00000020, // Displays counter as money
|
||||
};
|
||||
|
||||
enum AchievementCriteriaTimedTypes
|
||||
{
|
||||
ACHIEVEMENT_TIMED_TYPE_EVENT = 1, // Timer is started by internal event with id in timerStartEvent
|
||||
ACHIEVEMENT_TIMED_TYPE_QUEST = 2, // Timer is started by acceting quest with entry in timerStartEvent
|
||||
ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER = 5, // Timer is started by casting a spell with entry in timerStartEvent
|
||||
ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET = 6, // Timer is started by being target of spell with entry in timerStartEvent
|
||||
ACHIEVEMENT_TIMED_TYPE_CREATURE = 7, // Timer is started by killing creature with entry in timerStartEvent
|
||||
ACHIEVEMENT_TIMED_TYPE_ITEM = 9, // Timer is started by using item with entry in timerStartEvent
|
||||
|
||||
ACHIEVEMENT_TIMED_TYPE_MAX,
|
||||
};
|
||||
|
||||
enum AchievementCriteriaTypes
|
||||
{
|
||||
ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE = 0,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_WIN_BG = 1,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL = 5,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL = 7,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT = 8,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT = 9,
|
||||
// you have to complete a daily quest x times in a row
|
||||
ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY = 10,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE = 11,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE = 13,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST = 14,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND= 15,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP= 16,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_DEATH= 17,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON = 18,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID = 19,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE = 20,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER = 23,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING = 24,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM = 26,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST = 27,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET = 28,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL= 29,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE = 30,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA = 31,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA = 32,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA = 33,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL = 34,
|
||||
// TODO: this criteria has additional conditions which can not be found in the dbcs
|
||||
ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL = 35,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM = 36,
|
||||
// TODO: the archievements 1162 and 1163 requires a special rating which can't be found in the dbc
|
||||
ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA = 37,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING = 38,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_REACH_TEAM_RATING = 39,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL = 40,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM = 41,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM= 42,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA = 43,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_OWN_RANK= 44,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT= 45,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION= 46,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION= 47,
|
||||
// noted: rewarded as soon as the player payed, not at taking place at the seat
|
||||
ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP= 48,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM = 49,
|
||||
// TODO: itemlevel is mentioned in text but not present in dbc
|
||||
ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT = 50,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT= 51,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS = 52,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_HK_RACE = 53,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE = 54,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE = 55,
|
||||
// TODO: in some cases map not present, and in some cases need do without die
|
||||
ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS = 56,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM = 57,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS = 59,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS = 60,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS = 61,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD = 62,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING = 63,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER = 65,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL = 66,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY = 67,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT = 68,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2= 69,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL= 70,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT = 72,
|
||||
// TODO: title id is not mentioned in dbc
|
||||
ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE = 74,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS= 75,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL = 76,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL = 77,
|
||||
// TODO: creature type (demon, undead etc.) is not stored in dbc
|
||||
ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE = 78,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS= 80,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION= 82,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID= 83,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS= 84,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD = 85,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_GOLD_VALUE_OWNED = 86,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION = 87,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION = 88,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS = 89,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM = 90,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM = 91,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED = 93,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED = 94,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALTH = 95,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_POWER = 96,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_STAT = 97,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_SPELLPOWER = 98,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_ARMOR = 99,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_RATING = 100,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_DEALT = 101,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_RECEIVED = 102,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED = 103,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CASTED = 104,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED = 105,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALING_RECEIVED = 106,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED = 107,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN = 108,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE = 109,
|
||||
// TODO: target entry is missing
|
||||
ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2 = 110,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE= 112,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL = 113,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS = 114,
|
||||
// 0..115 => 116 criteria types total
|
||||
ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS = 115,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS = 119,
|
||||
// 120
|
||||
// 121
|
||||
// 122
|
||||
// 123
|
||||
// 0..123 => 124 criteria types total
|
||||
ACHIEVEMENT_CRITERIA_TYPE_TOTAL = 124,
|
||||
};
|
||||
|
||||
enum AreaFlags
|
||||
{
|
||||
AREA_FLAG_SNOW = 0x00000001, // snow (only Dun Morogh, Naxxramas, Razorfen Downs and Winterspring)
|
||||
AREA_FLAG_UNK1 = 0x00000002, // may be necropolis?
|
||||
AREA_FLAG_UNK2 = 0x00000004, // Only used for areas on map 571 (development before)
|
||||
AREA_FLAG_SLAVE_CAPITAL = 0x00000008, // city and city subsones
|
||||
AREA_FLAG_UNK3 = 0x00000010, // can't find common meaning
|
||||
AREA_FLAG_SLAVE_CAPITAL2 = 0x00000020, // slave capital city flag?
|
||||
AREA_FLAG_UNK4 = 0x00000040, // many zones have this flag
|
||||
AREA_FLAG_ARENA = 0x00000080, // arena, both instanced and world arenas
|
||||
AREA_FLAG_CAPITAL = 0x00000100, // main capital city flag
|
||||
AREA_FLAG_CITY = 0x00000200, // only for one zone named "City" (where it located?)
|
||||
AREA_FLAG_OUTLAND = 0x00000400, // expansion zones? (only Eye of the Storm not have this flag, but have 0x00004000 flag)
|
||||
AREA_FLAG_SANCTUARY = 0x00000800, // sanctuary area (PvP disabled)
|
||||
AREA_FLAG_NEED_FLY = 0x00001000, // only Netherwing Ledge, Socrethar's Seat, Tempest Keep, The Arcatraz, The Botanica, The Mechanar, Sorrow Wing Point, Dragonspine Ridge, Netherwing Mines, Dragonmaw Base Camp, Dragonmaw Skyway
|
||||
AREA_FLAG_UNUSED1 = 0x00002000, // not used now (no area/zones with this flag set in 3.0.3)
|
||||
AREA_FLAG_OUTLAND2 = 0x00004000, // expansion zones? (only Circle of Blood Arena not have this flag, but have 0x00000400 flag)
|
||||
AREA_FLAG_PVP = 0x00008000, // pvp objective area? (Death's Door also has this flag although it's no pvp object area)
|
||||
AREA_FLAG_ARENA_INSTANCE = 0x00010000, // used by instanced arenas only
|
||||
AREA_FLAG_UNUSED2 = 0x00020000, // not used now (no area/zones with this flag set in 3.0.3)
|
||||
AREA_FLAG_UNK5 = 0x00040000, // only used for Amani Pass, Hatchet Hills
|
||||
AREA_FLAG_UNK6 = 0x00080000, // Valgarde and Acherus: The Ebon Hold
|
||||
AREA_FLAG_LOWLEVEL = 0x00100000, // used for some starting areas with area_level <= 15
|
||||
AREA_FLAG_TOWN = 0x00200000, // small towns with Inn
|
||||
AREA_FLAG_UNK7 = 0x00400000, // Warsong Hold, Acherus: The Ebon Hold, New Agamand Inn, Vengeance Landing Inn
|
||||
AREA_FLAG_UNK8 = 0x00800000, // Westguard Inn, Acherus: The Ebon Hold, Valgarde
|
||||
AREA_FLAG_OUTDOOR_PVP = 0x01000000, // Wintergrasp and it's subzones
|
||||
AREA_FLAG_INSIDE = 0x02000000, // used for determinating spell related inside/outside questions in Map::IsOutdoors
|
||||
AREA_FLAG_OUTSIDE = 0x04000000, // used for determinating spell related inside/outside questions in Map::IsOutdoors
|
||||
AREA_FLAG_OUTDOOR_PVP2 = 0x08000000, // Wintergrasp and it's subzones
|
||||
AREA_FLAG_NO_FLY_ZONE = 0x20000000 // Marks zones where you cannot fly
|
||||
};
|
||||
|
||||
enum Difficulty
|
||||
{
|
||||
REGULAR_DIFFICULTY = 0,
|
||||
|
||||
DUNGEON_DIFFICULTY_NORMAL = 0,
|
||||
DUNGEON_DIFFICULTY_HEROIC = 1,
|
||||
DUNGEON_DIFFICULTY_EPIC = 2,
|
||||
|
||||
RAID_DIFFICULTY_10MAN_NORMAL = 0,
|
||||
RAID_DIFFICULTY_25MAN_NORMAL = 1,
|
||||
RAID_DIFFICULTY_10MAN_HEROIC = 2,
|
||||
RAID_DIFFICULTY_25MAN_HEROIC = 3,
|
||||
};
|
||||
|
||||
#define MAX_DUNGEON_DIFFICULTY 3
|
||||
#define MAX_RAID_DIFFICULTY 4
|
||||
#define MAX_DIFFICULTY 4
|
||||
|
||||
enum SpawnMask
|
||||
{
|
||||
SPAWNMASK_CONTINENT = (1 << REGULAR_DIFFICULTY),// any any maps without spawn modes
|
||||
|
||||
SPAWNMASK_DUNGEON_NORMAL = (1 << DUNGEON_DIFFICULTY_NORMAL),
|
||||
SPAWNMASK_DUNGEON_HEROIC = (1 << DUNGEON_DIFFICULTY_HEROIC),
|
||||
SPAWNMASK_DUNGEON_ALL = (SPAWNMASK_DUNGEON_NORMAL | SPAWNMASK_DUNGEON_HEROIC),
|
||||
|
||||
SPAWNMASK_RAID_10MAN_NORMAL = (1 << RAID_DIFFICULTY_10MAN_NORMAL),
|
||||
SPAWNMASK_RAID_25MAN_NORMAL = (1 << RAID_DIFFICULTY_25MAN_NORMAL),
|
||||
SPAWNMASK_RAID_NORMAL_ALL = (SPAWNMASK_RAID_10MAN_NORMAL | SPAWNMASK_RAID_25MAN_NORMAL),
|
||||
|
||||
SPAWNMASK_RAID_10MAN_HEROIC = (1 << RAID_DIFFICULTY_10MAN_HEROIC),
|
||||
SPAWNMASK_RAID_25MAN_HEROIC = (1 << RAID_DIFFICULTY_25MAN_HEROIC),
|
||||
SPAWNMASK_RAID_HEROIC_ALL = (SPAWNMASK_RAID_10MAN_HEROIC | SPAWNMASK_RAID_25MAN_HEROIC),
|
||||
|
||||
SPAWNMASK_RAID_ALL = (SPAWNMASK_RAID_NORMAL_ALL | SPAWNMASK_RAID_HEROIC_ALL),
|
||||
};
|
||||
|
||||
enum FactionTemplateFlags
|
||||
{
|
||||
FACTION_TEMPLATE_FLAG_PVP = 0x00000800, // flagged for PvP
|
||||
FACTION_TEMPLATE_FLAG_CONTESTED_GUARD = 0x00001000, // faction will attack players that were involved in PvP combats
|
||||
};
|
||||
|
||||
enum FactionMasks
|
||||
{
|
||||
FACTION_MASK_PLAYER = 1, // any player
|
||||
FACTION_MASK_ALLIANCE = 2, // player or creature from alliance team
|
||||
FACTION_MASK_HORDE = 4, // player or creature from horde team
|
||||
FACTION_MASK_MONSTER = 8 // aggressive creature from monster team
|
||||
// if none flags set then non-aggressive creature
|
||||
};
|
||||
|
||||
enum MapTypes // Lua_IsInInstance
|
||||
{
|
||||
MAP_COMMON = 0, // none
|
||||
MAP_INSTANCE = 1, // party
|
||||
MAP_RAID = 2, // raid
|
||||
MAP_BATTLEGROUND = 3, // pvp
|
||||
MAP_ARENA = 4 // arena
|
||||
};
|
||||
|
||||
enum AbilytyLearnType
|
||||
{
|
||||
ABILITY_LEARNED_ON_GET_PROFESSION_SKILL = 1,
|
||||
ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL = 2
|
||||
};
|
||||
|
||||
enum ItemEnchantmentType
|
||||
{
|
||||
ITEM_ENCHANTMENT_TYPE_NONE = 0,
|
||||
ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL = 1,
|
||||
ITEM_ENCHANTMENT_TYPE_DAMAGE = 2,
|
||||
ITEM_ENCHANTMENT_TYPE_EQUIP_SPELL = 3,
|
||||
ITEM_ENCHANTMENT_TYPE_RESISTANCE = 4,
|
||||
ITEM_ENCHANTMENT_TYPE_STAT = 5,
|
||||
ITEM_ENCHANTMENT_TYPE_TOTEM = 6,
|
||||
ITEM_ENCHANTMENT_TYPE_USE_SPELL = 7,
|
||||
ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET = 8
|
||||
};
|
||||
|
||||
enum TotemCategoryType
|
||||
{
|
||||
TOTEM_CATEGORY_TYPE_KNIFE = 1,
|
||||
TOTEM_CATEGORY_TYPE_TOTEM = 2,
|
||||
TOTEM_CATEGORY_TYPE_ROD = 3,
|
||||
TOTEM_CATEGORY_TYPE_PICK = 21,
|
||||
TOTEM_CATEGORY_TYPE_STONE = 22,
|
||||
TOTEM_CATEGORY_TYPE_HAMMER = 23,
|
||||
TOTEM_CATEGORY_TYPE_SPANNER = 24
|
||||
};
|
||||
|
||||
// SummonProperties.dbc, col 1
|
||||
enum SummonPropGroup
|
||||
{
|
||||
SUMMON_PROP_GROUP_UNKNOWN1 = 0, // 1160 spells in 3.0.3
|
||||
SUMMON_PROP_GROUP_UNKNOWN2 = 1, // 861 spells in 3.0.3
|
||||
SUMMON_PROP_GROUP_PETS = 2, // 52 spells in 3.0.3, pets mostly
|
||||
SUMMON_PROP_GROUP_CONTROLLABLE = 3, // 13 spells in 3.0.3, mostly controllable
|
||||
SUMMON_PROP_GROUP_UNKNOWN3 = 4 // 86 spells in 3.0.3, taxi/mounts
|
||||
};
|
||||
|
||||
// SummonProperties.dbc, col 3
|
||||
enum SummonPropType
|
||||
{
|
||||
SUMMON_PROP_TYPE_UNKNOWN = 0, // different summons, 1330 spells in 3.0.3
|
||||
SUMMON_PROP_TYPE_SUMMON = 1, // generic summons, 49 spells in 3.0.3
|
||||
SUMMON_PROP_TYPE_GUARDIAN = 2, // summon guardian, 393 spells in 3.0.3
|
||||
SUMMON_PROP_TYPE_ARMY = 3, // summon army, 5 spells in 3.0.3
|
||||
SUMMON_PROP_TYPE_TOTEM = 4, // summon totem, 169 spells in 3.0.3
|
||||
SUMMON_PROP_TYPE_CRITTER = 5, // critter/minipet, 195 spells in 3.0.3
|
||||
SUMMON_PROP_TYPE_DK = 6, // summon DRW/Ghoul, 2 spells in 3.0.3
|
||||
SUMMON_PROP_TYPE_BOMB = 7, // summon bot/bomb, 4 spells in 3.0.3
|
||||
SUMMON_PROP_TYPE_PHASING = 8, // something todo with DK prequest line, 2 spells in 3.0.3
|
||||
SUMMON_PROP_TYPE_SIEGE_VEH = 9, // summon different vehicles, 14 spells in 3.0.3
|
||||
SUMMON_PROP_TYPE_DRAKE_VEH = 10, // summon drake (vehicle), 3 spells
|
||||
SUMMON_PROP_TYPE_LIGHTWELL = 11 // summon lightwell, 6 spells in 3.0.3
|
||||
};
|
||||
|
||||
// SummonProperties.dbc, col 5
|
||||
enum SummonPropFlags
|
||||
{
|
||||
SUMMON_PROP_FLAG_NONE = 0x0000, // 1342 spells in 3.0.3
|
||||
SUMMON_PROP_FLAG_UNK1 = 0x0001, // 75 spells in 3.0.3, something unfriendly
|
||||
SUMMON_PROP_FLAG_UNK2 = 0x0002, // 616 spells in 3.0.3, something friendly
|
||||
SUMMON_PROP_FLAG_UNK3 = 0x0004, // 22 spells in 3.0.3, no idea...
|
||||
SUMMON_PROP_FLAG_UNK4 = 0x0008, // 49 spells in 3.0.3, some mounts
|
||||
SUMMON_PROP_FLAG_UNK5 = 0x0010, // 25 spells in 3.0.3, quest related?
|
||||
SUMMON_PROP_FLAG_UNK6 = 0x0020, // 0 spells in 3.0.3, unused
|
||||
SUMMON_PROP_FLAG_UNK7 = 0x0040, // 12 spells in 3.0.3, no idea
|
||||
SUMMON_PROP_FLAG_UNK8 = 0x0080, // 4 spells in 3.0.3, no idea
|
||||
SUMMON_PROP_FLAG_UNK9 = 0x0100, // 51 spells in 3.0.3, no idea, many quest related
|
||||
SUMMON_PROP_FLAG_UNK10 = 0x0200, // 51 spells in 3.0.3, something defensive
|
||||
SUMMON_PROP_FLAG_UNK11 = 0x0400, // 3 spells, requires something near?
|
||||
SUMMON_PROP_FLAG_UNK12 = 0x0800, // 30 spells in 3.0.3, no idea
|
||||
SUMMON_PROP_FLAG_UNK13 = 0x1000, // 8 spells in 3.0.3, siege vehicle
|
||||
SUMMON_PROP_FLAG_UNK14 = 0x2000, // 2 spells in 3.0.3, escort?
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,836 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "DBCStores.h"
|
||||
#include "Policies/SingletonImp.h"
|
||||
#include "Log.h"
|
||||
#include "ProgressBar.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "SpellMgr.h"
|
||||
|
||||
#include "DBCfmt.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
typedef std::map<uint16,uint32> AreaFlagByAreaID;
|
||||
typedef std::map<uint32,uint32> AreaFlagByMapID;
|
||||
|
||||
struct WMOAreaTableTripple
|
||||
{
|
||||
WMOAreaTableTripple(int32 r, int32 a, int32 g) : rootId(r), adtId(a), groupId(g)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator <(const WMOAreaTableTripple& b) const
|
||||
{
|
||||
return memcmp(this, &b, sizeof(WMOAreaTableTripple))<0;
|
||||
}
|
||||
|
||||
// ordered by entropy; that way memcmp will have a minimal medium runtime
|
||||
int32 groupId;
|
||||
int32 rootId;
|
||||
int32 adtId;
|
||||
};
|
||||
|
||||
typedef std::map<WMOAreaTableTripple, WMOAreaTableEntry const *> WMOAreaInfoByTripple;
|
||||
|
||||
DBCStorage <AreaTableEntry> sAreaStore(AreaTableEntryfmt);
|
||||
DBCStorage <AreaGroupEntry> sAreaGroupStore(AreaGroupEntryfmt);
|
||||
DBCStorage <AreaPOIEntry> sAreaPOIStore(AreaPOIEntryfmt);
|
||||
static AreaFlagByAreaID sAreaFlagByAreaID;
|
||||
static AreaFlagByMapID sAreaFlagByMapID; // for instances without generated *.map files
|
||||
|
||||
static WMOAreaInfoByTripple sWMOAreaInfoByTripple;
|
||||
|
||||
DBCStorage <AchievementEntry> sAchievementStore(Achievementfmt);
|
||||
DBCStorage <AchievementCriteriaEntry> sAchievementCriteriaStore(AchievementCriteriafmt);
|
||||
DBCStorage <AreaTriggerEntry> sAreaTriggerStore(AreaTriggerEntryfmt);
|
||||
DBCStorage <AuctionHouseEntry> sAuctionHouseStore(AuctionHouseEntryfmt);
|
||||
DBCStorage <BankBagSlotPricesEntry> sBankBagSlotPricesStore(BankBagSlotPricesEntryfmt);
|
||||
DBCStorage <BattlemasterListEntry> sBattlemasterListStore(BattlemasterListEntryfmt);
|
||||
DBCStorage <BarberShopStyleEntry> sBarberShopStyleStore(BarberShopStyleEntryfmt);
|
||||
DBCStorage <CharStartOutfitEntry> sCharStartOutfitStore(CharStartOutfitEntryfmt);
|
||||
DBCStorage <CharTitlesEntry> sCharTitlesStore(CharTitlesEntryfmt);
|
||||
DBCStorage <ChatChannelsEntry> sChatChannelsStore(ChatChannelsEntryfmt);
|
||||
DBCStorage <ChrClassesEntry> sChrClassesStore(ChrClassesEntryfmt);
|
||||
DBCStorage <ChrRacesEntry> sChrRacesStore(ChrRacesEntryfmt);
|
||||
DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore(CinematicSequencesEntryfmt);
|
||||
DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore(CreatureDisplayInfofmt);
|
||||
DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore(CreatureFamilyfmt);
|
||||
DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore(CreatureSpellDatafmt);
|
||||
DBCStorage <CreatureTypeEntry> sCreatureTypeStore(CreatureTypefmt);
|
||||
DBCStorage <CurrencyTypesEntry> sCurrencyTypesStore(CurrencyTypesfmt);
|
||||
|
||||
DBCStorage <DurabilityQualityEntry> sDurabilityQualityStore(DurabilityQualityfmt);
|
||||
DBCStorage <DurabilityCostsEntry> sDurabilityCostsStore(DurabilityCostsfmt);
|
||||
|
||||
DBCStorage <EmotesEntry> sEmotesStore(EmotesEntryfmt);
|
||||
DBCStorage <EmotesTextEntry> sEmotesTextStore(EmotesTextEntryfmt);
|
||||
|
||||
typedef std::map<uint32,SimpleFactionsList> FactionTeamMap;
|
||||
static FactionTeamMap sFactionTeamMap;
|
||||
DBCStorage <FactionEntry> sFactionStore(FactionEntryfmt);
|
||||
DBCStorage <FactionTemplateEntry> sFactionTemplateStore(FactionTemplateEntryfmt);
|
||||
|
||||
DBCStorage <GameObjectDisplayInfoEntry> sGameObjectDisplayInfoStore(GameObjectDisplayInfofmt);
|
||||
DBCStorage <GemPropertiesEntry> sGemPropertiesStore(GemPropertiesEntryfmt);
|
||||
DBCStorage <GlyphPropertiesEntry> sGlyphPropertiesStore(GlyphPropertiesfmt);
|
||||
DBCStorage <GlyphSlotEntry> sGlyphSlotStore(GlyphSlotfmt);
|
||||
|
||||
DBCStorage <GtBarberShopCostBaseEntry> sGtBarberShopCostBaseStore(GtBarberShopCostBasefmt);
|
||||
DBCStorage <GtCombatRatingsEntry> sGtCombatRatingsStore(GtCombatRatingsfmt);
|
||||
DBCStorage <GtChanceToMeleeCritBaseEntry> sGtChanceToMeleeCritBaseStore(GtChanceToMeleeCritBasefmt);
|
||||
DBCStorage <GtChanceToMeleeCritEntry> sGtChanceToMeleeCritStore(GtChanceToMeleeCritfmt);
|
||||
DBCStorage <GtChanceToSpellCritBaseEntry> sGtChanceToSpellCritBaseStore(GtChanceToSpellCritBasefmt);
|
||||
DBCStorage <GtChanceToSpellCritEntry> sGtChanceToSpellCritStore(GtChanceToSpellCritfmt);
|
||||
DBCStorage <GtOCTRegenHPEntry> sGtOCTRegenHPStore(GtOCTRegenHPfmt);
|
||||
//DBCStorage <GtOCTRegenMPEntry> sGtOCTRegenMPStore(GtOCTRegenMPfmt); -- not used currently
|
||||
DBCStorage <GtRegenHPPerSptEntry> sGtRegenHPPerSptStore(GtRegenHPPerSptfmt);
|
||||
DBCStorage <GtRegenMPPerSptEntry> sGtRegenMPPerSptStore(GtRegenMPPerSptfmt);
|
||||
|
||||
DBCStorage <HolidaysEntry> sHolidaysStore(Holidaysfmt);
|
||||
|
||||
DBCStorage <ItemEntry> sItemStore(Itemfmt);
|
||||
DBCStorage <ItemBagFamilyEntry> sItemBagFamilyStore(ItemBagFamilyfmt);
|
||||
//DBCStorage <ItemCondExtCostsEntry> sItemCondExtCostsStore(ItemCondExtCostsEntryfmt);
|
||||
//DBCStorage <ItemDisplayInfoEntry> sItemDisplayInfoStore(ItemDisplayTemplateEntryfmt); -- not used currently
|
||||
DBCStorage <ItemExtendedCostEntry> sItemExtendedCostStore(ItemExtendedCostEntryfmt);
|
||||
DBCStorage <ItemLimitCategoryEntry> sItemLimitCategoryStore(ItemLimitCategoryEntryfmt);
|
||||
DBCStorage <ItemRandomPropertiesEntry> sItemRandomPropertiesStore(ItemRandomPropertiesfmt);
|
||||
DBCStorage <ItemRandomSuffixEntry> sItemRandomSuffixStore(ItemRandomSuffixfmt);
|
||||
DBCStorage <ItemSetEntry> sItemSetStore(ItemSetEntryfmt);
|
||||
|
||||
DBCStorage <LFGDungeonEntry> sLFGDungeonStore(LFGDungeonEntryfmt);
|
||||
|
||||
DBCStorage <LockEntry> sLockStore(LockEntryfmt);
|
||||
|
||||
DBCStorage <MailTemplateEntry> sMailTemplateStore(MailTemplateEntryfmt);
|
||||
DBCStorage <MapEntry> sMapStore(MapEntryfmt);
|
||||
|
||||
// DBC used only for initialization sMapDifficultyMap at startup.
|
||||
DBCStorage <MapDifficultyEntry> sMapDifficultyStore(MapDifficultyEntryfmt); // only for loading
|
||||
MapDifficultyMap sMapDifficultyMap;
|
||||
|
||||
DBCStorage <MovieEntry> sMovieStore(MovieEntryfmt);
|
||||
|
||||
DBCStorage <PvPDifficultyEntry> sPvPDifficultyStore(PvPDifficultyfmt);
|
||||
|
||||
DBCStorage <QuestSortEntry> sQuestSortStore(QuestSortEntryfmt);
|
||||
DBCStorage <QuestXPEntry> sQuestXPStore(QuestXPfmt);
|
||||
DBCStorage <QuestFactionRewEntry> sQuestFactionRewardStore(QuestFactionRewardfmt);
|
||||
DBCStorage <RandomPropertiesPointsEntry> sRandomPropertiesPointsStore(RandomPropertiesPointsfmt);
|
||||
DBCStorage <ScalingStatDistributionEntry> sScalingStatDistributionStore(ScalingStatDistributionfmt);
|
||||
DBCStorage <ScalingStatValuesEntry> sScalingStatValuesStore(ScalingStatValuesfmt);
|
||||
|
||||
DBCStorage <SkillLineEntry> sSkillLineStore(SkillLinefmt);
|
||||
DBCStorage <SkillLineAbilityEntry> sSkillLineAbilityStore(SkillLineAbilityfmt);
|
||||
|
||||
DBCStorage <SoundEntriesEntry> sSoundEntriesStore(SoundEntriesfmt);
|
||||
|
||||
DBCStorage <SpellItemEnchantmentEntry> sSpellItemEnchantmentStore(SpellItemEnchantmentfmt);
|
||||
DBCStorage <SpellItemEnchantmentConditionEntry> sSpellItemEnchantmentConditionStore(SpellItemEnchantmentConditionfmt);
|
||||
DBCStorage <SpellEntry> sSpellStore(SpellEntryfmt);
|
||||
SpellCategoryStore sSpellCategoryStore;
|
||||
PetFamilySpellsStore sPetFamilySpellsStore;
|
||||
|
||||
DBCStorage <SpellCastTimesEntry> sSpellCastTimesStore(SpellCastTimefmt);
|
||||
DBCStorage <SpellDifficultyEntry> sSpellDifficultyStore(SpellDifficultyfmt);
|
||||
DBCStorage <SpellDurationEntry> sSpellDurationStore(SpellDurationfmt);
|
||||
DBCStorage <SpellFocusObjectEntry> sSpellFocusObjectStore(SpellFocusObjectfmt);
|
||||
DBCStorage <SpellRadiusEntry> sSpellRadiusStore(SpellRadiusfmt);
|
||||
DBCStorage <SpellRangeEntry> sSpellRangeStore(SpellRangefmt);
|
||||
DBCStorage <SpellRuneCostEntry> sSpellRuneCostStore(SpellRuneCostfmt);
|
||||
DBCStorage <SpellShapeshiftEntry> sSpellShapeshiftStore(SpellShapeshiftfmt);
|
||||
DBCStorage <StableSlotPricesEntry> sStableSlotPricesStore(StableSlotPricesfmt);
|
||||
DBCStorage <SummonPropertiesEntry> sSummonPropertiesStore(SummonPropertiesfmt);
|
||||
DBCStorage <TalentEntry> sTalentStore(TalentEntryfmt);
|
||||
TalentSpellPosMap sTalentSpellPosMap;
|
||||
DBCStorage <TalentTabEntry> sTalentTabStore(TalentTabEntryfmt);
|
||||
|
||||
// store absolute bit position for first rank for talent inspect
|
||||
static uint32 sTalentTabPages[MAX_CLASSES][3];
|
||||
|
||||
DBCStorage <TaxiNodesEntry> sTaxiNodesStore(TaxiNodesEntryfmt);
|
||||
TaxiMask sTaxiNodesMask;
|
||||
TaxiMask sOldContinentsNodesMask;
|
||||
|
||||
// DBC used only for initialization sTaxiPathSetBySource at startup.
|
||||
TaxiPathSetBySource sTaxiPathSetBySource;
|
||||
DBCStorage <TaxiPathEntry> sTaxiPathStore(TaxiPathEntryfmt);
|
||||
|
||||
// DBC used only for initialization sTaxiPathNodeStore at startup.
|
||||
TaxiPathNodesByPath sTaxiPathNodesByPath;
|
||||
static DBCStorage <TaxiPathNodeEntry> sTaxiPathNodeStore(TaxiPathNodeEntryfmt);
|
||||
|
||||
DBCStorage <TotemCategoryEntry> sTotemCategoryStore(TotemCategoryEntryfmt);
|
||||
DBCStorage <VehicleEntry> sVehicleStore(VehicleEntryfmt);
|
||||
DBCStorage <VehicleSeatEntry> sVehicleSeatStore(VehicleSeatEntryfmt);
|
||||
DBCStorage <WMOAreaTableEntry> sWMOAreaTableStore(WMOAreaTableEntryfmt);
|
||||
DBCStorage <WorldMapAreaEntry> sWorldMapAreaStore(WorldMapAreaEntryfmt);
|
||||
DBCStorage <WorldMapOverlayEntry> sWorldMapOverlayStore(WorldMapOverlayEntryfmt);
|
||||
DBCStorage <WorldSafeLocsEntry> sWorldSafeLocsStore(WorldSafeLocsEntryfmt);
|
||||
|
||||
typedef std::list<std::string> StoreProblemList;
|
||||
|
||||
static bool LoadDBC_assert_print(uint32 fsize,uint32 rsize, const std::string& filename)
|
||||
{
|
||||
sLog.outError("ERROR: Size of '%s' setted by format string (%u) not equal size of C++ structure (%u).",filename.c_str(),fsize,rsize);
|
||||
|
||||
// assert must fail after function call
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void LoadDBC(uint32& availableDbcLocales,barGoLink& bar, StoreProblemList& errlist, DBCStorage<T>& storage, const std::string& dbc_path, const std::string& filename, const std::string * custom_entries = NULL, const std::string * idname = NULL)
|
||||
{
|
||||
// compatibility format and C++ structure sizes
|
||||
assert(DBCFileLoader::GetFormatRecordSize(storage.GetFormat()) == sizeof(T) || LoadDBC_assert_print(DBCFileLoader::GetFormatRecordSize(storage.GetFormat()),sizeof(T),filename));
|
||||
|
||||
std::string dbc_filename = dbc_path + filename;
|
||||
SqlDbc * sql = NULL;
|
||||
if (custom_entries)
|
||||
sql = new SqlDbc(&filename,custom_entries, idname,storage.GetFormat());
|
||||
|
||||
if (storage.Load(dbc_filename.c_str(), sql))
|
||||
{
|
||||
bar.step();
|
||||
for (uint8 i = 0; i < MAX_LOCALE; ++i)
|
||||
{
|
||||
if (!(availableDbcLocales & (1 << i)))
|
||||
continue;
|
||||
|
||||
std::string dbc_filename_loc = dbc_path + localeNames[i] + "/" + filename;
|
||||
if (!storage.LoadStringsFrom(dbc_filename_loc.c_str()))
|
||||
availableDbcLocales &= ~(1<<i); // mark as not available for speedup next checks
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// sort problematic dbc to (1) non compatible and (2) non-existed
|
||||
FILE * f=fopen(dbc_filename.c_str(),"rb");
|
||||
if (f)
|
||||
{
|
||||
char buf[100];
|
||||
snprintf(buf,100," (exist, but have %d fields instead " SIZEFMTD ") Wrong client version DBC file?",storage.GetFieldCount(),strlen(storage.GetFormat()));
|
||||
errlist.push_back(dbc_filename + buf);
|
||||
fclose(f);
|
||||
}
|
||||
else
|
||||
errlist.push_back(dbc_filename);
|
||||
}
|
||||
if (sql)
|
||||
delete sql;
|
||||
}
|
||||
|
||||
void LoadDBCStores(const std::string& dataPath)
|
||||
{
|
||||
std::string dbcPath = dataPath+"dbc/";
|
||||
|
||||
const uint32 DBCFilesCount = 87;
|
||||
|
||||
barGoLink bar(DBCFilesCount);
|
||||
|
||||
StoreProblemList bad_dbc_files;
|
||||
uint32 availableDbcLocales = 0xFFFFFFFF;
|
||||
|
||||
LoadDBC(availableDbcLocales, bar, bad_dbc_files, sAreaStore, dbcPath, "AreaTable.dbc");
|
||||
|
||||
// must be after sAreaStore loading
|
||||
for (uint32 i = 0; i < sAreaStore.GetNumRows(); ++i) // areaflag numbered from 0
|
||||
{
|
||||
if (AreaTableEntry const* area = sAreaStore.LookupEntry(i))
|
||||
{
|
||||
// fill AreaId->DBC records
|
||||
sAreaFlagByAreaID.insert(AreaFlagByAreaID::value_type(uint16(area->ID),area->exploreFlag));
|
||||
|
||||
// fill MapId->DBC records (skip sub zones and continents)
|
||||
if (area->zone == 0 && area->mapid != 0 && area->mapid != 1 && area->mapid != 530 && area->mapid != 571)
|
||||
sAreaFlagByMapID.insert(AreaFlagByMapID::value_type(area->mapid,area->exploreFlag));
|
||||
}
|
||||
}
|
||||
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAchievementStore, dbcPath,"Achievement.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAchievementCriteriaStore, dbcPath,"Achievement_Criteria.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaTriggerStore, dbcPath,"AreaTrigger.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaGroupStore, dbcPath,"AreaGroup.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaPOIStore, dbcPath,"AreaPOI.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAuctionHouseStore, dbcPath,"AuctionHouse.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBankBagSlotPricesStore, dbcPath,"BankBagSlotPrices.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBattlemasterListStore, dbcPath,"BattlemasterList.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBarberShopStyleStore, dbcPath,"BarberShopStyle.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharStartOutfitStore, dbcPath,"CharStartOutfit.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharTitlesStore, dbcPath,"CharTitles.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChatChannelsStore, dbcPath,"ChatChannels.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrClassesStore, dbcPath,"ChrClasses.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrRacesStore, dbcPath,"ChrRaces.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCinematicSequencesStore, dbcPath,"CinematicSequences.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureDisplayInfoStore, dbcPath,"CreatureDisplayInfo.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureFamilyStore, dbcPath,"CreatureFamily.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureSpellDataStore, dbcPath,"CreatureSpellData.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureTypeStore, dbcPath,"CreatureType.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCurrencyTypesStore, dbcPath,"CurrencyTypes.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sDurabilityCostsStore, dbcPath,"DurabilityCosts.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sDurabilityQualityStore, dbcPath,"DurabilityQuality.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sEmotesStore, dbcPath,"Emotes.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sEmotesTextStore, dbcPath,"EmotesText.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sFactionStore, dbcPath,"Faction.dbc");
|
||||
for (uint32 i=0; i<sFactionStore.GetNumRows(); ++i)
|
||||
{
|
||||
FactionEntry const * faction = sFactionStore.LookupEntry(i);
|
||||
if (faction && faction->team)
|
||||
{
|
||||
SimpleFactionsList &flist = sFactionTeamMap[faction->team];
|
||||
flist.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sFactionTemplateStore, dbcPath,"FactionTemplate.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGameObjectDisplayInfoStore, dbcPath,"GameObjectDisplayInfo.dbc");
|
||||
for (uint32 i = 0; i < sGameObjectDisplayInfoStore.GetNumRows(); ++i)
|
||||
{
|
||||
if (GameObjectDisplayInfoEntry const * info = sGameObjectDisplayInfoStore.LookupEntry(i))
|
||||
{
|
||||
if (info->maxX < info->minX)
|
||||
std::swap(*(float*)(&info->maxX), *(float*)(&info->minX));
|
||||
if (info->maxY < info->minY)
|
||||
std::swap(*(float*)(&info->maxY), *(float*)(&info->minY));
|
||||
if (info->maxZ < info->minZ)
|
||||
std::swap(*(float*)(&info->maxZ), *(float*)(&info->minZ));
|
||||
}
|
||||
}
|
||||
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGemPropertiesStore, dbcPath,"GemProperties.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGlyphPropertiesStore, dbcPath,"GlyphProperties.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGlyphSlotStore, dbcPath,"GlyphSlot.dbc");
|
||||
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtBarberShopCostBaseStore,dbcPath,"gtBarberShopCostBase.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtCombatRatingsStore, dbcPath,"gtCombatRatings.dbc");
|
||||
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToMeleeCritBaseStore, dbcPath,"gtChanceToMeleeCritBase.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToMeleeCritStore, dbcPath,"gtChanceToMeleeCrit.dbc");
|
||||
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToSpellCritBaseStore, dbcPath,"gtChanceToSpellCritBase.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToSpellCritStore, dbcPath,"gtChanceToSpellCrit.dbc");
|
||||
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtOCTRegenHPStore, dbcPath,"gtOCTRegenHP.dbc");
|
||||
//LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtOCTRegenMPStore, dbcPath,"gtOCTRegenMP.dbc"); -- not used currently
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtRegenHPPerSptStore, dbcPath,"gtRegenHPPerSpt.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtRegenMPPerSptStore, dbcPath,"gtRegenMPPerSpt.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sHolidaysStore, dbcPath,"Holidays.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemStore, dbcPath,"Item.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemBagFamilyStore, dbcPath,"ItemBagFamily.dbc");
|
||||
//LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemDisplayInfoStore, dbcPath,"ItemDisplayInfo.dbc"); -- not used currently
|
||||
//LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemCondExtCostsStore, dbcPath,"ItemCondExtCosts.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemExtendedCostStore, dbcPath,"ItemExtendedCost.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemLimitCategoryStore, dbcPath,"ItemLimitCategory.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemRandomPropertiesStore,dbcPath,"ItemRandomProperties.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemRandomSuffixStore, dbcPath,"ItemRandomSuffix.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemSetStore, dbcPath,"ItemSet.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sLFGDungeonStore, dbcPath,"LFGDungeons.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sLockStore, dbcPath,"Lock.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMailTemplateStore, dbcPath,"MailTemplate.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMapStore, dbcPath,"Map.dbc");
|
||||
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMapDifficultyStore, dbcPath,"MapDifficulty.dbc");
|
||||
// fill data
|
||||
for (uint32 i = 1; i < sMapDifficultyStore.GetNumRows(); ++i)
|
||||
if (MapDifficultyEntry const* entry = sMapDifficultyStore.LookupEntry(i))
|
||||
sMapDifficultyMap[MAKE_PAIR32(entry->MapId,entry->Difficulty)] = MapDifficulty(entry->resetTime,entry->maxPlayers);
|
||||
sMapDifficultyStore.Clear();
|
||||
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMovieStore, dbcPath,"Movie.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestSortStore, dbcPath,"QuestSort.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sPvPDifficultyStore, dbcPath,"PvpDifficulty.dbc");
|
||||
for (uint32 i = 0; i < sPvPDifficultyStore.GetNumRows(); ++i)
|
||||
if (PvPDifficultyEntry const* entry = sPvPDifficultyStore.LookupEntry(i))
|
||||
if (entry->bracketId > MAX_BATTLEGROUND_BRACKETS)
|
||||
assert(false && "Need update MAX_BATTLEGROUND_BRACKETS by DBC data");
|
||||
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestXPStore, dbcPath,"QuestXP.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestFactionRewardStore, dbcPath,"QuestFactionReward.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sRandomPropertiesPointsStore, dbcPath,"RandPropPoints.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sScalingStatDistributionStore, dbcPath,"ScalingStatDistribution.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sScalingStatValuesStore, dbcPath,"ScalingStatValues.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSkillLineStore, dbcPath,"SkillLine.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSkillLineAbilityStore, dbcPath,"SkillLineAbility.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSoundEntriesStore, dbcPath,"SoundEntries.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellStore, dbcPath,"Spell.dbc", &CustomSpellEntryfmt, &CustomSpellEntryIndex);
|
||||
for (uint32 i = 1; i < sSpellStore.GetNumRows(); ++i)
|
||||
{
|
||||
SpellEntry const * spell = sSpellStore.LookupEntry(i);
|
||||
if (spell && spell->Category)
|
||||
sSpellCategoryStore[spell->Category].insert(i);
|
||||
}
|
||||
|
||||
for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
|
||||
{
|
||||
SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j);
|
||||
|
||||
if (!skillLine)
|
||||
continue;
|
||||
|
||||
SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId);
|
||||
|
||||
if (spellInfo && IsPassiveSpell(spellInfo->Id))
|
||||
{
|
||||
for (uint32 i = 1; i < sCreatureFamilyStore.GetNumRows(); ++i)
|
||||
{
|
||||
CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(i);
|
||||
if (!cFamily)
|
||||
continue;
|
||||
|
||||
if (skillLine->skillId != cFamily->skillLine[0] && skillLine->skillId != cFamily->skillLine[1])
|
||||
continue;
|
||||
if (spellInfo->spellLevel)
|
||||
continue;
|
||||
|
||||
if (skillLine->learnOnGetSkill != ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL)
|
||||
continue;
|
||||
|
||||
sPetFamilySpellsStore[i].insert(spellInfo->Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellCastTimesStore, dbcPath,"SpellCastTimes.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellDifficultyStore, dbcPath,"SpellDifficulty.dbc", &CustomSpellDifficultyfmt, &CustomSpellDifficultyIndex);
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellDurationStore, dbcPath,"SpellDuration.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellFocusObjectStore, dbcPath,"SpellFocusObject.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellItemEnchantmentStore,dbcPath,"SpellItemEnchantment.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellItemEnchantmentConditionStore,dbcPath,"SpellItemEnchantmentCondition.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRadiusStore, dbcPath,"SpellRadius.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRangeStore, dbcPath,"SpellRange.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRuneCostStore, dbcPath,"SpellRuneCost.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellShapeshiftStore, dbcPath,"SpellShapeshiftForm.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sStableSlotPricesStore, dbcPath,"StableSlotPrices.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSummonPropertiesStore, dbcPath,"SummonProperties.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTalentStore, dbcPath,"Talent.dbc");
|
||||
|
||||
// Create Spelldifficulty searcher
|
||||
for (uint32 i = 0; i < sSpellDifficultyStore.GetNumRows(); ++i)
|
||||
{
|
||||
SpellDifficultyEntry const *spellDiff = sSpellDifficultyStore.LookupEntry(i);
|
||||
if (!spellDiff)
|
||||
continue;
|
||||
|
||||
SpellDifficultyEntry newEntry;
|
||||
for (int x = 0; x < MAX_DIFFICULTY; ++x)
|
||||
{
|
||||
if (spellDiff->SpellID[x] <= 0 || !sSpellStore.LookupEntry(spellDiff->SpellID[x]))
|
||||
{
|
||||
if (spellDiff->SpellID[x] > 0)//don't show error if spell is <= 0, not all modes have spells and there are unknown negative values
|
||||
sLog.outErrorDb("spelldifficulty_dbc: spell %i at field id:%u at spellid%i does not exist in SpellStore (spell.dbc), loaded as 0", spellDiff->SpellID[x], spellDiff->ID, x);
|
||||
newEntry.SpellID[x] = 0;//spell was <= 0 or invalid, set to 0
|
||||
} else newEntry.SpellID[x] = spellDiff->SpellID[x];
|
||||
}
|
||||
if (newEntry.SpellID[0] <= 0 || newEntry.SpellID[1] <= 0)//id0-1 must be always set!
|
||||
continue;
|
||||
|
||||
for (int x = 0; x < MAX_DIFFICULTY; ++x)
|
||||
spellmgr.SetSpellDifficultyId(uint32(newEntry.SpellID[x]), spellDiff->ID);
|
||||
}
|
||||
|
||||
// create talent spells set
|
||||
for (unsigned int i = 0; i < sTalentStore.GetNumRows(); ++i)
|
||||
{
|
||||
TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
|
||||
if (!talentInfo) continue;
|
||||
for (int j = 0; j < MAX_TALENT_RANK; j++)
|
||||
if (talentInfo->RankID[j])
|
||||
sTalentSpellPosMap[talentInfo->RankID[j]] = TalentSpellPos(i,j);
|
||||
}
|
||||
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTalentTabStore, dbcPath,"TalentTab.dbc");
|
||||
|
||||
// prepare fast data access to bit pos of talent ranks for use at inspecting
|
||||
{
|
||||
// now have all max ranks (and then bit amount used for store talent ranks in inspect)
|
||||
for (uint32 talentTabId = 1; talentTabId < sTalentTabStore.GetNumRows(); ++talentTabId)
|
||||
{
|
||||
TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry(talentTabId);
|
||||
if (!talentTabInfo)
|
||||
continue;
|
||||
|
||||
// prevent memory corruption; otherwise cls will become 12 below
|
||||
if ((talentTabInfo->ClassMask & CLASSMASK_ALL_PLAYABLE) == 0)
|
||||
continue;
|
||||
|
||||
// store class talent tab pages
|
||||
uint32 cls = 1;
|
||||
for (uint32 m=1; !(m & talentTabInfo->ClassMask) && cls < MAX_CLASSES; m <<= 1, ++cls) {}
|
||||
|
||||
sTalentTabPages[cls][talentTabInfo->tabpage]=talentTabId;
|
||||
}
|
||||
}
|
||||
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiNodesStore, dbcPath,"TaxiNodes.dbc");
|
||||
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiPathStore, dbcPath,"TaxiPath.dbc");
|
||||
for (uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i)
|
||||
if (TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i))
|
||||
sTaxiPathSetBySource[entry->from][entry->to] = TaxiPathBySourceAndDestination(entry->ID,entry->price);
|
||||
uint32 pathCount = sTaxiPathStore.GetNumRows();
|
||||
|
||||
//## TaxiPathNode.dbc ## Loaded only for initialization different structures
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiPathNodeStore, dbcPath,"TaxiPathNode.dbc");
|
||||
// Calculate path nodes count
|
||||
std::vector<uint32> pathLength;
|
||||
pathLength.resize(pathCount); // 0 and some other indexes not used
|
||||
for (uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i)
|
||||
if (TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i))
|
||||
{
|
||||
if (pathLength[entry->path] < entry->index + 1)
|
||||
pathLength[entry->path] = entry->index + 1;
|
||||
}
|
||||
// Set path length
|
||||
sTaxiPathNodesByPath.resize(pathCount); // 0 and some other indexes not used
|
||||
for (uint32 i = 1; i < sTaxiPathNodesByPath.size(); ++i)
|
||||
sTaxiPathNodesByPath[i].resize(pathLength[i]);
|
||||
// fill data
|
||||
for (uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i)
|
||||
if (TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i))
|
||||
sTaxiPathNodesByPath[entry->path][entry->index] = TaxiPathNode(entry->mapid,entry->x,entry->y,entry->z,entry->actionFlag,entry->delay);
|
||||
sTaxiPathNodeStore.Clear();
|
||||
|
||||
// Initialize global taxinodes mask
|
||||
// include existed nodes that have at least single not spell base (scripted) path
|
||||
{
|
||||
std::set<uint32> spellPaths;
|
||||
for (uint32 i = 1; i < sSpellStore.GetNumRows (); ++i)
|
||||
if (SpellEntry const* sInfo = sSpellStore.LookupEntry (i))
|
||||
for (int j=0; j < 3; ++j)
|
||||
if (sInfo->Effect[j] == 123 /*SPELL_EFFECT_SEND_TAXI*/)
|
||||
spellPaths.insert(sInfo->EffectMiscValue[j]);
|
||||
|
||||
memset(sTaxiNodesMask,0,sizeof(sTaxiNodesMask));
|
||||
memset(sOldContinentsNodesMask,0,sizeof(sTaxiNodesMask));
|
||||
for (uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i)
|
||||
{
|
||||
TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(i);
|
||||
if (!node)
|
||||
continue;
|
||||
|
||||
TaxiPathSetBySource::const_iterator src_i = sTaxiPathSetBySource.find(i);
|
||||
if (src_i != sTaxiPathSetBySource.end() && !src_i->second.empty())
|
||||
{
|
||||
bool ok = false;
|
||||
for (TaxiPathSetForSource::const_iterator dest_i = src_i->second.begin(); dest_i != src_i->second.end(); ++dest_i)
|
||||
{
|
||||
// not spell path
|
||||
if (spellPaths.find(dest_i->second.ID) == spellPaths.end())
|
||||
{
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
continue;
|
||||
}
|
||||
|
||||
// valid taxi network node
|
||||
uint8 field = (uint8)((i - 1) / 32);
|
||||
uint32 submask = 1<<((i-1)%32);
|
||||
sTaxiNodesMask[field] |= submask;
|
||||
|
||||
// old continent node (+ nodes virtually at old continents, check explicitly to avoid loading map files for zone info)
|
||||
if (node->map_id < 2 || i == 82 || i == 83 || i == 93 || i == 94)
|
||||
sOldContinentsNodesMask[field] |= submask;
|
||||
|
||||
// fix DK node at Ebon Hold
|
||||
if (i == 315) {
|
||||
((TaxiNodesEntry*)node)->MountCreatureID[1] = 32981;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTotemCategoryStore, dbcPath,"TotemCategory.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sVehicleStore, dbcPath,"Vehicle.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sVehicleSeatStore, dbcPath,"VehicleSeat.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWMOAreaTableStore, dbcPath,"WMOAreaTable.dbc");
|
||||
for(uint32 i = 0; i < sWMOAreaTableStore.GetNumRows(); ++i)
|
||||
{
|
||||
if(WMOAreaTableEntry const* entry = sWMOAreaTableStore.LookupEntry(i))
|
||||
{
|
||||
sWMOAreaInfoByTripple.insert(WMOAreaInfoByTripple::value_type(WMOAreaTableTripple(entry->rootId, entry->adtId, entry->groupId), entry));
|
||||
}
|
||||
}
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldMapAreaStore, dbcPath,"WorldMapArea.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldMapOverlayStore, dbcPath,"WorldMapOverlay.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldSafeLocsStore, dbcPath,"WorldSafeLocs.dbc");
|
||||
|
||||
// error checks
|
||||
if (bad_dbc_files.size() >= DBCFilesCount)
|
||||
{
|
||||
sLog.outError("\nIncorrect DataDir value in Trinityd.conf or ALL required *.dbc files (%d) not found by path: %sdbc",DBCFilesCount,dataPath.c_str());
|
||||
exit(1);
|
||||
}
|
||||
else if (!bad_dbc_files.empty())
|
||||
{
|
||||
std::string str;
|
||||
for (std::list<std::string>::iterator i = bad_dbc_files.begin(); i != bad_dbc_files.end(); ++i)
|
||||
str += *i + "\n";
|
||||
|
||||
sLog.outError("\nSome required *.dbc files (%u from %d) not found or not compatible:\n%s",(uint32)bad_dbc_files.size(),DBCFilesCount,str.c_str());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Check loaded DBC files proper version
|
||||
if (!sAreaStore.LookupEntry(3617) || // last area (areaflag) added in 3.3.3a
|
||||
!sCharTitlesStore.LookupEntry(177) || // last char title added in 3.3.3a
|
||||
!sGemPropertiesStore.LookupEntry(1629) || // last added spell in 3.3.3a
|
||||
!sItemStore.LookupEntry(54860) || // last gem property added in 3.3.3a
|
||||
!sItemExtendedCostStore.LookupEntry(2997) || // last item extended cost added in 3.3.3a
|
||||
!sMapStore.LookupEntry(724) || // last map added in 3.3.3a
|
||||
!sSpellStore.LookupEntry(76567) ) // last client known item added in 3.3.3a
|
||||
{
|
||||
sLog.outError("\nYou have _outdated_ DBC files. Please extract correct versions from current using client.");
|
||||
exit(1);
|
||||
}
|
||||
sLog.outString();
|
||||
sLog.outString(">> Initialized %d data stores", DBCFilesCount);
|
||||
}
|
||||
|
||||
SimpleFactionsList const* GetFactionTeamList(uint32 faction, bool &isTeamMember)
|
||||
{
|
||||
for (FactionTeamMap::const_iterator itr = sFactionTeamMap.begin(); itr != sFactionTeamMap.end(); ++itr)
|
||||
{
|
||||
if (itr->first == faction)
|
||||
{
|
||||
isTeamMember = false;
|
||||
return &itr->second;
|
||||
}
|
||||
for (SimpleFactionsList::const_iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2)
|
||||
{
|
||||
if ((*itr2) == faction)
|
||||
{
|
||||
isTeamMember = true;
|
||||
return &itr->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char* GetPetName(uint32 petfamily, uint32 dbclang)
|
||||
{
|
||||
if (!petfamily)
|
||||
return NULL;
|
||||
CreatureFamilyEntry const *pet_family = sCreatureFamilyStore.LookupEntry(petfamily);
|
||||
if (!pet_family)
|
||||
return NULL;
|
||||
return pet_family->Name[dbclang]?pet_family->Name[dbclang]:NULL;
|
||||
}
|
||||
|
||||
TalentSpellPos const* GetTalentSpellPos(uint32 spellId)
|
||||
{
|
||||
TalentSpellPosMap::const_iterator itr = sTalentSpellPosMap.find(spellId);
|
||||
if (itr == sTalentSpellPosMap.end())
|
||||
return NULL;
|
||||
|
||||
return &itr->second;
|
||||
}
|
||||
|
||||
uint32 GetTalentSpellCost(uint32 spellId)
|
||||
{
|
||||
if (TalentSpellPos const* pos = GetTalentSpellPos(spellId))
|
||||
return pos->rank+1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 GetAreaFlagByAreaID(uint32 area_id)
|
||||
{
|
||||
AreaFlagByAreaID::iterator i = sAreaFlagByAreaID.find(area_id);
|
||||
if (i == sAreaFlagByAreaID.end())
|
||||
return -1;
|
||||
|
||||
return i->second;
|
||||
}
|
||||
|
||||
WMOAreaTableEntry const* GetWMOAreaTableEntryByTripple(int32 rootid, int32 adtid, int32 groupid)
|
||||
{
|
||||
WMOAreaInfoByTripple::iterator i = sWMOAreaInfoByTripple.find(WMOAreaTableTripple(rootid, adtid, groupid));
|
||||
if(i == sWMOAreaInfoByTripple.end())
|
||||
return NULL;
|
||||
return i->second;
|
||||
}
|
||||
|
||||
AreaTableEntry const* GetAreaEntryByAreaID(uint32 area_id)
|
||||
{
|
||||
int32 areaflag = GetAreaFlagByAreaID(area_id);
|
||||
if (areaflag < 0)
|
||||
return NULL;
|
||||
|
||||
return sAreaStore.LookupEntry(areaflag);
|
||||
}
|
||||
|
||||
AreaTableEntry const* GetAreaEntryByAreaFlagAndMap(uint32 area_flag,uint32 map_id)
|
||||
{
|
||||
if (area_flag)
|
||||
return sAreaStore.LookupEntry(area_flag);
|
||||
|
||||
if (MapEntry const* mapEntry = sMapStore.LookupEntry(map_id))
|
||||
return GetAreaEntryByAreaID(mapEntry->linked_zone);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32 GetAreaFlagByMapId(uint32 mapid)
|
||||
{
|
||||
AreaFlagByMapID::iterator i = sAreaFlagByMapID.find(mapid);
|
||||
if (i == sAreaFlagByMapID.end())
|
||||
return 0;
|
||||
else
|
||||
return i->second;
|
||||
}
|
||||
|
||||
uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId)
|
||||
{
|
||||
if (mapid != 530 && mapid != 571) // speed for most cases
|
||||
return mapid;
|
||||
|
||||
if (WorldMapAreaEntry const* wma = sWorldMapAreaStore.LookupEntry(zoneId))
|
||||
return wma->virtual_map_id >= 0 ? wma->virtual_map_id : wma->map_id;
|
||||
|
||||
return mapid;
|
||||
}
|
||||
|
||||
ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId)
|
||||
{
|
||||
mapid = GetVirtualMapForMapAndZone(mapid,zoneId);
|
||||
if (mapid < 2)
|
||||
return CONTENT_1_60;
|
||||
|
||||
MapEntry const* mapEntry = sMapStore.LookupEntry(mapid);
|
||||
if (!mapEntry)
|
||||
return CONTENT_1_60;
|
||||
|
||||
switch(mapEntry->Expansion())
|
||||
{
|
||||
default: return CONTENT_1_60;
|
||||
case 1: return CONTENT_61_70;
|
||||
case 2: return CONTENT_71_80;
|
||||
}
|
||||
}
|
||||
|
||||
ChatChannelsEntry const* GetChannelEntryFor(uint32 channel_id)
|
||||
{
|
||||
// not sorted, numbering index from 0
|
||||
for (uint32 i = 0; i < sChatChannelsStore.GetNumRows(); ++i)
|
||||
{
|
||||
ChatChannelsEntry const* ch = sChatChannelsStore.LookupEntry(i);
|
||||
if (ch && ch->ChannelID == channel_id)
|
||||
return ch;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId)
|
||||
{
|
||||
if (requiredTotemCategoryId == 0)
|
||||
return true;
|
||||
if (itemTotemCategoryId == 0)
|
||||
return false;
|
||||
|
||||
TotemCategoryEntry const* itemEntry = sTotemCategoryStore.LookupEntry(itemTotemCategoryId);
|
||||
if (!itemEntry)
|
||||
return false;
|
||||
TotemCategoryEntry const* reqEntry = sTotemCategoryStore.LookupEntry(requiredTotemCategoryId);
|
||||
if (!reqEntry)
|
||||
return false;
|
||||
|
||||
if (itemEntry->categoryType != reqEntry->categoryType)
|
||||
return false;
|
||||
|
||||
return (itemEntry->categoryMask & reqEntry->categoryMask) == reqEntry->categoryMask;
|
||||
}
|
||||
|
||||
void Zone2MapCoordinates(float& x,float& y,uint32 zone)
|
||||
{
|
||||
WorldMapAreaEntry const* maEntry = sWorldMapAreaStore.LookupEntry(zone);
|
||||
|
||||
// if not listed then map coordinates (instance)
|
||||
if (!maEntry)
|
||||
return;
|
||||
|
||||
std::swap(x,y); // at client map coords swapped
|
||||
x = x*((maEntry->x2-maEntry->x1)/100)+maEntry->x1;
|
||||
y = y*((maEntry->y2-maEntry->y1)/100)+maEntry->y1; // client y coord from top to down
|
||||
}
|
||||
|
||||
void Map2ZoneCoordinates(float& x,float& y,uint32 zone)
|
||||
{
|
||||
WorldMapAreaEntry const* maEntry = sWorldMapAreaStore.LookupEntry(zone);
|
||||
|
||||
// if not listed then map coordinates (instance)
|
||||
if (!maEntry)
|
||||
return;
|
||||
|
||||
x = (x-maEntry->x1)/((maEntry->x2-maEntry->x1)/100);
|
||||
y = (y-maEntry->y1)/((maEntry->y2-maEntry->y1)/100); // client y coord from top to down
|
||||
std::swap(x,y); // client have map coords swapped
|
||||
}
|
||||
|
||||
MapDifficulty const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty)
|
||||
{
|
||||
MapDifficultyMap::const_iterator itr = sMapDifficultyMap.find(MAKE_PAIR32(mapId,difficulty));
|
||||
return itr != sMapDifficultyMap.end() ? &itr->second : NULL;
|
||||
}
|
||||
|
||||
PvPDifficultyEntry const* GetBattlegroundBracketByLevel(uint32 mapid, uint32 level)
|
||||
{
|
||||
// prevent out-of-range levels for dbc data
|
||||
if (level > DEFAULT_MAX_LEVEL)
|
||||
level = DEFAULT_MAX_LEVEL;
|
||||
|
||||
for (uint32 i = 0; i < sPvPDifficultyStore.GetNumRows(); ++i)
|
||||
if (PvPDifficultyEntry const* entry = sPvPDifficultyStore.LookupEntry(i))
|
||||
if (entry->mapId == mapid && entry->minLevel <= level && entry->maxLevel >= level)
|
||||
return entry;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PvPDifficultyEntry const* GetBattlegroundBracketById(uint32 mapid, BattleGroundBracketId id)
|
||||
{
|
||||
for (uint32 i = 0; i < sPvPDifficultyStore.GetNumRows(); ++i)
|
||||
if (PvPDifficultyEntry const* entry = sPvPDifficultyStore.LookupEntry(i))
|
||||
if (entry->mapId == mapid && entry->GetBracketId() == id)
|
||||
return entry;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32 const* GetTalentTabPages(uint8 cls)
|
||||
{
|
||||
return sTalentTabPages[cls];
|
||||
}
|
||||
|
||||
// script support functions
|
||||
DBCStorage <SoundEntriesEntry> const* GetSoundEntriesStore() { return &sSoundEntriesStore; }
|
||||
DBCStorage <SpellEntry> const* GetSpellStore() { return &sSpellStore; }
|
||||
DBCStorage <SpellRangeEntry> const* GetSpellRangeStore() { return &sSpellRangeStore; }
|
||||
DBCStorage <FactionEntry> const* GetFactionStore() { return &sFactionStore; }
|
||||
DBCStorage <ItemEntry> const* GetItemDisplayStore() { return &sItemStore; }
|
||||
DBCStorage <CreatureDisplayInfoEntry> const* GetCreatureDisplayStore() { return &sCreatureDisplayInfoStore; }
|
||||
DBCStorage <EmotesEntry> const* GetEmotesStore() { return &sEmotesStore; }
|
||||
DBCStorage <EmotesTextEntry> const* GetEmotesTextStore() { return &sEmotesTextStore; }
|
||||
DBCStorage <AchievementEntry> const* GetAchievementStore() { return &sAchievementStore; }
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_DBCSTORES_H
|
||||
#define TRINITY_DBCSTORES_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "Database/DBCStore.h"
|
||||
#include "DBCStructure.h"
|
||||
|
||||
#include <list>
|
||||
|
||||
typedef std::list<uint32> SimpleFactionsList;
|
||||
|
||||
SimpleFactionsList const* GetFactionTeamList(uint32 faction, bool &isTeamMember);
|
||||
char* GetPetName(uint32 petfamily, uint32 dbclang);
|
||||
uint32 GetTalentSpellCost(uint32 spellId);
|
||||
TalentSpellPos const* GetTalentSpellPos(uint32 spellId);
|
||||
|
||||
int32 GetAreaFlagByAreaID(uint32 area_id); // -1 if not found
|
||||
AreaTableEntry const* GetAreaEntryByAreaID(uint32 area_id);
|
||||
AreaTableEntry const* GetAreaEntryByAreaFlagAndMap(uint32 area_flag,uint32 map_id);
|
||||
uint32 GetAreaFlagByMapId(uint32 mapid);
|
||||
|
||||
WMOAreaTableEntry const* GetWMOAreaTableEntryByTripple(int32 rootid, int32 adtid, int32 groupid);
|
||||
|
||||
uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId);
|
||||
|
||||
enum ContentLevels
|
||||
{
|
||||
CONTENT_1_60 = 0,
|
||||
CONTENT_61_70,
|
||||
CONTENT_71_80
|
||||
};
|
||||
ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId);
|
||||
|
||||
ChatChannelsEntry const* GetChannelEntryFor(uint32 channel_id);
|
||||
|
||||
bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId);
|
||||
|
||||
void Zone2MapCoordinates(float &x, float &y, uint32 zone);
|
||||
void Map2ZoneCoordinates(float &x, float &y, uint32 zone);
|
||||
|
||||
typedef std::map<uint32/*pair32(map,diff)*/,MapDifficulty> MapDifficultyMap;
|
||||
MapDifficulty const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty);
|
||||
|
||||
uint32 const* /*[3]*/ GetTalentTabPages(uint8 cls);
|
||||
|
||||
PvPDifficultyEntry const* GetBattlegroundBracketByLevel(uint32 mapid, uint32 level);
|
||||
PvPDifficultyEntry const* GetBattlegroundBracketById(uint32 mapid, BattleGroundBracketId id);
|
||||
|
||||
extern DBCStorage <AchievementEntry> sAchievementStore;
|
||||
extern DBCStorage <AchievementCriteriaEntry> sAchievementCriteriaStore;
|
||||
extern DBCStorage <AreaTableEntry> sAreaStore;// recommend access using functions
|
||||
extern DBCStorage <AreaGroupEntry> sAreaGroupStore;
|
||||
extern DBCStorage <AreaPOIEntry> sAreaPOIStore;
|
||||
extern DBCStorage <AreaTriggerEntry> sAreaTriggerStore;
|
||||
extern DBCStorage <AuctionHouseEntry> sAuctionHouseStore;
|
||||
extern DBCStorage <BankBagSlotPricesEntry> sBankBagSlotPricesStore;
|
||||
extern DBCStorage <BarberShopStyleEntry> sBarberShopStyleStore;
|
||||
extern DBCStorage <BattlemasterListEntry> sBattlemasterListStore;
|
||||
//extern DBCStorage <ChatChannelsEntry> sChatChannelsStore; -- accessed using function, no usable index
|
||||
extern DBCStorage <CharStartOutfitEntry> sCharStartOutfitStore;
|
||||
extern DBCStorage <CharTitlesEntry> sCharTitlesStore;
|
||||
extern DBCStorage <ChrClassesEntry> sChrClassesStore;
|
||||
extern DBCStorage <ChrRacesEntry> sChrRacesStore;
|
||||
extern DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore;
|
||||
extern DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore;
|
||||
extern DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore;
|
||||
extern DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore;
|
||||
extern DBCStorage <CreatureTypeEntry> sCreatureTypeStore;
|
||||
extern DBCStorage <CurrencyTypesEntry> sCurrencyTypesStore;
|
||||
extern DBCStorage <DurabilityCostsEntry> sDurabilityCostsStore;
|
||||
extern DBCStorage <DurabilityQualityEntry> sDurabilityQualityStore;
|
||||
extern DBCStorage <EmotesEntry> sEmotesStore;
|
||||
extern DBCStorage <EmotesTextEntry> sEmotesTextStore;
|
||||
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 <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 <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 <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 <SoundEntriesEntry> sSoundEntriesStore;
|
||||
extern DBCStorage <SpellCastTimesEntry> sSpellCastTimesStore;
|
||||
extern DBCStorage <SpellDifficultyEntry> sSpellDifficultyStore;
|
||||
extern DBCStorage <SpellDurationEntry> sSpellDurationStore;
|
||||
extern DBCStorage <SpellFocusObjectEntry> sSpellFocusObjectStore;
|
||||
extern DBCStorage <SpellItemEnchantmentEntry> sSpellItemEnchantmentStore;
|
||||
extern DBCStorage <SpellItemEnchantmentConditionEntry> sSpellItemEnchantmentConditionStore;
|
||||
extern SpellCategoryStore sSpellCategoryStore;
|
||||
extern PetFamilySpellsStore sPetFamilySpellsStore;
|
||||
extern DBCStorage <SpellRadiusEntry> sSpellRadiusStore;
|
||||
extern DBCStorage <SpellRangeEntry> sSpellRangeStore;
|
||||
extern DBCStorage <SpellRuneCostEntry> sSpellRuneCostStore;
|
||||
extern DBCStorage <SpellShapeshiftEntry> sSpellShapeshiftStore;
|
||||
extern DBCStorage <SpellEntry> sSpellStore;
|
||||
extern DBCStorage <StableSlotPricesEntry> sStableSlotPricesStore;
|
||||
extern DBCStorage <SummonPropertiesEntry> sSummonPropertiesStore;
|
||||
extern DBCStorage <TalentEntry> sTalentStore;
|
||||
extern DBCStorage <TalentTabEntry> sTalentTabStore;
|
||||
extern DBCStorage <TaxiNodesEntry> sTaxiNodesStore;
|
||||
extern DBCStorage <TaxiPathEntry> sTaxiPathStore;
|
||||
extern TaxiMask sTaxiNodesMask;
|
||||
extern TaxiMask sOldContinentsNodesMask;
|
||||
extern TaxiPathSetBySource sTaxiPathSetBySource;
|
||||
extern TaxiPathNodesByPath sTaxiPathNodesByPath;
|
||||
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);
|
||||
|
||||
// script support functions
|
||||
DBCStorage <SoundEntriesEntry> const* GetSoundEntriesStore();
|
||||
DBCStorage <SpellEntry> const* GetSpellStore();
|
||||
DBCStorage <SpellRangeEntry> const* GetSpellRangeStore();
|
||||
DBCStorage <FactionEntry> const* GetFactionStore();
|
||||
DBCStorage <ItemEntry> const* GetItemDisplayStore();
|
||||
DBCStorage <CreatureDisplayInfoEntry> const* GetCreatureDisplayStore();
|
||||
DBCStorage <EmotesEntry> const* GetEmotesStore();
|
||||
DBCStorage <EmotesTextEntry> const* GetEmotesTextStore();
|
||||
DBCStorage <AchievementEntry> const* GetAchievementStore();
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_DBCSFRM_H
|
||||
#define TRINITY_DBCSFRM_H
|
||||
|
||||
const char Achievementfmt[]="niixssssssssssssssssxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxxxxxxxxii";
|
||||
const char AchievementCriteriafmt[]="niiiiiiiixxxxxxxxxxxxxxxxxiiiix";
|
||||
const char AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxixxxxxxx";
|
||||
const char AreaGroupEntryfmt[]="niiiiiii";
|
||||
const char AreaPOIEntryfmt[]="niiiiiiiiiiifffixixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxix";
|
||||
const char AreaTriggerEntryfmt[]="niffffffff";
|
||||
const char AuctionHouseEntryfmt[]="niiixxxxxxxxxxxxxxxxx";
|
||||
const char BankBagSlotPricesEntryfmt[]="ni";
|
||||
const char BarberShopStyleEntryfmt[]="nixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiii";
|
||||
const char BattlemasterListEntryfmt[]="niiiiiiiiixssssssssssssssssxiixx";
|
||||
const char CharStartOutfitEntryfmt[]="diiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
const char CharTitlesEntryfmt[]="nxssssssssssssssssxxxxxxxxxxxxxxxxxxi";
|
||||
const char ChatChannelsEntryfmt[]="iixssssssssssssssssxxxxxxxxxxxxxxxxxx";
|
||||
// ChatChannelsEntryfmt, index not used (more compact store)
|
||||
const char ChrClassesEntryfmt[]="nxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii";
|
||||
const char ChrRacesEntryfmt[]="nxixiixixxxxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi";
|
||||
const char CinematicSequencesEntryfmt[]="nxxxxxxxxx";
|
||||
const char CreatureDisplayInfofmt[]="nxxxfxxxxxxxxxxx";
|
||||
const char CreatureFamilyfmt[]="nfifiiiiixssssssssssssssssxx";
|
||||
const char CreatureSpellDatafmt[]="niiiixxxx";
|
||||
const char CreatureTypefmt[]="nxxxxxxxxxxxxxxxxxx";
|
||||
const char CurrencyTypesfmt[]="xnxi";
|
||||
const char DurabilityCostsfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiii";
|
||||
const char DurabilityQualityfmt[]="nf";
|
||||
const char EmotesEntryfmt[]="nxxiiix";
|
||||
const char EmotesTextEntryfmt[]="nxixxxxxxxxxxxxxxxx";
|
||||
const char FactionEntryfmt[]="niiiiiiiiiiiiiiiiiixxxxssssssssssssssssxxxxxxxxxxxxxxxxxx";
|
||||
const char FactionTemplateEntryfmt[]="niiiiiiiiiiiii";
|
||||
const char GameObjectDisplayInfofmt[]="nxxxxxxxxxxxffffffx";
|
||||
const char GemPropertiesEntryfmt[]="nixxi";
|
||||
const char GlyphPropertiesfmt[]="niii";
|
||||
const char GlyphSlotfmt[]="nii";
|
||||
const char GtBarberShopCostBasefmt[]="f";
|
||||
const char GtCombatRatingsfmt[]="f";
|
||||
const char GtChanceToMeleeCritBasefmt[]="f";
|
||||
const char GtChanceToMeleeCritfmt[]="f";
|
||||
const char GtChanceToSpellCritBasefmt[]="f";
|
||||
const char GtChanceToSpellCritfmt[]="f";
|
||||
const char GtOCTRegenHPfmt[]="f";
|
||||
//const char GtOCTRegenMPfmt[]="f";
|
||||
const char GtRegenHPPerSptfmt[]="f";
|
||||
const char GtRegenMPPerSptfmt[]="f";
|
||||
const char Holidaysfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
const char Itemfmt[]="niiiiiii";
|
||||
const char ItemBagFamilyfmt[]="nxxxxxxxxxxxxxxxxx";
|
||||
//const char ItemDisplayTemplateEntryfmt[]="nxxxxxxxxxxixxxxxxxxxxx";
|
||||
//const char ItemCondExtCostsEntryfmt[]="xiii";
|
||||
const char ItemExtendedCostEntryfmt[]="niiiiiiiiiiiiiix";
|
||||
const char ItemLimitCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxix";
|
||||
const char ItemRandomPropertiesfmt[]="nxiiiiissssssssssssssssx";
|
||||
const char ItemRandomSuffixfmt[]="nssssssssssssssssxxiiiiiiiiii";
|
||||
const char ItemSetEntryfmt[]="dssssssssssssssssxxxxxxxxxxxxxxxxxxiiiiiiiiiiiiiiiiii";
|
||||
const char LFGDungeonEntryfmt[]="nxxxxxxxxxxxxxxxxxiiiiiiixixxixixxxxxxxxxxxxxxxxx";
|
||||
const char LockEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx";
|
||||
const char MailTemplateEntryfmt[]="nxxxxxxxxxxxxxxxxxssssssssssssssssx";
|
||||
const char MapEntryfmt[]="nxixxssssssssssssssssxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixiffxiix";
|
||||
const char MapDifficultyEntryfmt[]="diixxxxxxxxxxxxxxxxxiix";
|
||||
const char MovieEntryfmt[]="nxx";
|
||||
const char QuestSortEntryfmt[]="nxxxxxxxxxxxxxxxxx";
|
||||
const char QuestXPfmt[]="niiiiiiiiii";
|
||||
const char QuestFactionRewardfmt[]="niiiiiiiiii";
|
||||
const char PvPDifficultyfmt[]="diiiii";
|
||||
const char RandomPropertiesPointsfmt[]="niiiiiiiiiiiiiii";
|
||||
const char ScalingStatDistributionfmt[]="niiiiiiiiiiiiiiiiiiiii";
|
||||
const char ScalingStatValuesfmt[]="iniiiiiiiiiiiiiiiiixiiii";
|
||||
const char SkillLinefmt[]="nixssssssssssssssssxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxi";
|
||||
const char SkillLineAbilityfmt[]="niiiixxiiiiixx";
|
||||
const char SoundEntriesfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
const char SpellCastTimefmt[]="nixx";
|
||||
const char SpellDifficultyfmt[]="niiii";
|
||||
const std::string CustomSpellDifficultyfmt="ppppp";
|
||||
const std::string CustomSpellDifficultyIndex="id";
|
||||
const char SpellDurationfmt[]="niii";
|
||||
const char SpellEntryfmt[]="niiiiiiiiiiiixixiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiixxxxxxx";
|
||||
const std::string CustomSpellEntryfmt="pappppppppaaaaaapaaaaaaaaaaapaaapapppppppaaaaapaapaaaaaaaaaaaaaaaaaappppppppppppppppppppppppppppppppppppaaaaaapppppppppaaapppppppppaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaappppppppapppaaaaappaaaaaaa";
|
||||
const std::string CustomSpellEntryIndex = "Id";
|
||||
const char SpellFocusObjectfmt[]="nxxxxxxxxxxxxxxxxx";
|
||||
const char SpellItemEnchantmentfmt[]="nxiiiiiixxxiiissssssssssssssssxiiiiiii";
|
||||
const char SpellItemEnchantmentConditionfmt[]="nbbbbbxxxxxbbbbbbbbbbiiiiiXXXXX";
|
||||
const char SpellRadiusfmt[]="nfxf";
|
||||
const char SpellRangefmt[]="nffffixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
const char SpellRuneCostfmt[]="niiii";
|
||||
const char SpellShapeshiftfmt[]="nxxxxxxxxxxxxxxxxxxiixixxxxiiiiiiii";
|
||||
const char StableSlotPricesfmt[] = "ni";
|
||||
const char SummonPropertiesfmt[] = "niiiii";
|
||||
const char TalentEntryfmt[]="niiiiiiiixxxxixxixxxxxx";
|
||||
const char TalentTabEntryfmt[]="nxxxxxxxxxxxxxxxxxxxiiix";
|
||||
const char TaxiNodesEntryfmt[]="nifffssssssssssssssssxii";
|
||||
const char TaxiPathEntryfmt[]="niii";
|
||||
const char TaxiPathNodeEntryfmt[]="diiifffiixx";
|
||||
const char TotemCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxii";
|
||||
const char VehicleEntryfmt[]="niffffiiiiiiiifffffffffffffffssssfifiixx";
|
||||
const char VehicleSeatEntryfmt[]="niiffffffffffiiiiiifffffffiiifffiiiiiiiffiiiiixxxxxxxxxxxx";
|
||||
const char WMOAreaTableEntryfmt[]="niiixxxxxiixxxxxxxxxxxxxxxxx";
|
||||
const char WorldMapAreaEntryfmt[]="xinxffffixx";
|
||||
const char WorldMapOverlayEntryfmt[]="nxiiiixxxxxxxxxxx";
|
||||
const char WorldSafeLocsEntryfmt[]="nifffxxxxxxxxxxxxxxxxx";
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "DestinationHolder.h"
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_DESTINATION_HOLDER_H
|
||||
#define TRINITY_DESTINATION_HOLDER_H
|
||||
|
||||
#include "Platform/Define.h"
|
||||
#include "Timer.h"
|
||||
|
||||
class WorldObject;
|
||||
class Map;
|
||||
|
||||
#define TRAVELLER_UPDATE_INTERVAL 300
|
||||
|
||||
template<typename TRAVELLER>
|
||||
class DestinationHolder
|
||||
{
|
||||
TimeTrackerSmall i_tracker;
|
||||
uint32 i_totalTravelTime;
|
||||
uint32 i_timeElapsed;
|
||||
bool i_destSet;
|
||||
float i_fromX, i_fromY, i_fromZ;
|
||||
float i_destX, i_destY, i_destZ;
|
||||
|
||||
public:
|
||||
DestinationHolder() : i_tracker(TRAVELLER_UPDATE_INTERVAL), i_totalTravelTime(0), i_timeElapsed(0),
|
||||
i_destSet(false), i_fromX(0), i_fromY(0), i_fromZ(0), i_destX(0), i_destY(0), i_destZ(0) {}
|
||||
|
||||
uint32 SetDestination(TRAVELLER &traveller, float dest_x, float dest_y, float dest_z, bool sendMove = true);
|
||||
void GetDestination(float &x, float &y, float &z) const { x = i_destX; y = i_destY; z = i_destZ; }
|
||||
bool UpdateExpired(void) const { return i_tracker.Passed(); }
|
||||
void ResetUpdate(uint32 t = TRAVELLER_UPDATE_INTERVAL) { i_tracker.Reset(t); }
|
||||
uint32 GetTotalTravelTime(void) const { return i_totalTravelTime; }
|
||||
void IncreaseTravelTime(uint32 increment) { i_totalTravelTime += increment; }
|
||||
void ResetTravelTime() { i_totalTravelTime = 0; }
|
||||
bool HasDestination(void) const { return i_destSet; }
|
||||
float GetDestinationDiff(float x, float y, float z) const;
|
||||
bool HasArrived(void) const { return (i_totalTravelTime == 0 || i_timeElapsed >= i_totalTravelTime); }
|
||||
bool UpdateTraveller(TRAVELLER &traveller, uint32 diff, bool micro_movement=false);
|
||||
uint32 StartTravel(TRAVELLER &traveller, bool sendMove = true);
|
||||
void GetLocationNow(const Map * map, float &x, float &y, float &z, bool is3D = false) const;
|
||||
void GetLocationNowNoMicroMovement(float &x, float &y, float &z) const; // For use without micro movement
|
||||
float GetDistance3dFromDestSq(const WorldObject &obj) const;
|
||||
|
||||
private:
|
||||
void _findOffSetPoint(float x1, float y1, float x2, float y2, float offset, float &x, float &y);
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_DESTINATIONHOLDERIMP_H
|
||||
#define TRINITY_DESTINATIONHOLDERIMP_H
|
||||
|
||||
#include "MapManager.h"
|
||||
#include "DestinationHolder.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
template<typename TRAVELLER>
|
||||
void
|
||||
DestinationHolder<TRAVELLER>::_findOffSetPoint(float x1, float y1, float x2, float y2, float offset, float &x, float &y)
|
||||
{
|
||||
/* given the point (x1, y1) and (x2, y2).. need to find the point (x,y) on the same line
|
||||
* such that the distance from (x, y) to (x2, y2) is offset.
|
||||
* Let the distance of p1 to p2 = d.. then the ratio of offset/d = (x2-x)/(x2-x1)
|
||||
* hence x = x2 - (offset/d)*(x2-x1)
|
||||
* like wise offset/d = (y2-y)/(y2-y1);
|
||||
*/
|
||||
if (offset == 0)
|
||||
{
|
||||
x = x2;
|
||||
y = y2;
|
||||
}
|
||||
else
|
||||
{
|
||||
double x_diff = double(x2 - x1);
|
||||
double y_diff = double(y2 - y1);
|
||||
double distance_d = (double)((x_diff*x_diff) + (y_diff * y_diff));
|
||||
if (distance_d == 0)
|
||||
{
|
||||
x = x2;
|
||||
y = y2;
|
||||
}
|
||||
else
|
||||
{
|
||||
distance_d = ::sqrt(distance_d); // starting distance
|
||||
double distance_ratio = (double)(distance_d - offset)/(double)distance_d;
|
||||
// line above has revised formula which is more correct, I think
|
||||
x = (float)(x1 + (distance_ratio*x_diff));
|
||||
y = (float)(y1 + (distance_ratio*y_diff));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TRAVELLER>
|
||||
uint32
|
||||
DestinationHolder<TRAVELLER>::SetDestination(TRAVELLER &traveller, float dest_x, float dest_y, float dest_z, bool sendMove)
|
||||
{
|
||||
i_destSet = true;
|
||||
i_destX = dest_x;
|
||||
i_destY = dest_y;
|
||||
i_destZ = dest_z;
|
||||
|
||||
return StartTravel(traveller, sendMove);
|
||||
}
|
||||
|
||||
template<typename TRAVELLER>
|
||||
uint32
|
||||
DestinationHolder<TRAVELLER>::StartTravel(TRAVELLER &traveller, bool sendMove)
|
||||
{
|
||||
if (!i_destSet) return 0;
|
||||
|
||||
i_fromX = traveller.GetPositionX();
|
||||
i_fromY = traveller.GetPositionY();
|
||||
i_fromZ = traveller.GetPositionZ();
|
||||
|
||||
i_totalTravelTime = traveller.GetTotalTrevelTimeTo(i_destX,i_destY,i_destZ);
|
||||
i_timeElapsed = 0;
|
||||
if (sendMove)
|
||||
traveller.MoveTo(i_destX, i_destY, i_destZ, i_totalTravelTime);
|
||||
return i_totalTravelTime;
|
||||
}
|
||||
|
||||
template<typename TRAVELLER>
|
||||
bool
|
||||
DestinationHolder<TRAVELLER>::UpdateTraveller(TRAVELLER &traveller, uint32 diff, bool micro_movement)
|
||||
{
|
||||
i_timeElapsed += diff;
|
||||
|
||||
// Update every TRAVELLER_UPDATE_INTERVAL
|
||||
i_tracker.Update(diff);
|
||||
if (!i_tracker.Passed())
|
||||
return false;
|
||||
else
|
||||
ResetUpdate();
|
||||
|
||||
if (!i_destSet) return true;
|
||||
|
||||
float x, y, z;
|
||||
if (!micro_movement)
|
||||
GetLocationNowNoMicroMovement(x, y, z);
|
||||
else
|
||||
{
|
||||
if (!traveller.GetTraveller().hasUnitState(UNIT_STAT_MOVING | UNIT_STAT_IN_FLIGHT))
|
||||
return true;
|
||||
|
||||
if (traveller.GetTraveller().hasUnitState(UNIT_STAT_IN_FLIGHT))
|
||||
GetLocationNow(traveller.GetTraveller().GetBaseMap() ,x, y, z, true); // Should reposition Object with right Coord, so I can bypass some Grid Relocation
|
||||
else
|
||||
GetLocationNow(traveller.GetTraveller().GetBaseMap(), x, y, z, false);
|
||||
|
||||
// Change movement computation to micro movement based on last tick coords, this makes system work
|
||||
// even on multiple floors zones without hugh vmaps usage ;)
|
||||
|
||||
// Take care of underrun of uint32
|
||||
if (i_totalTravelTime >= i_timeElapsed)
|
||||
i_totalTravelTime -= i_timeElapsed; // Consider only the remaining part
|
||||
else
|
||||
i_totalTravelTime = 0;
|
||||
|
||||
i_timeElapsed = 0;
|
||||
i_fromX = x; // and change origine
|
||||
i_fromY = y; // then I take into account only micro movement
|
||||
i_fromZ = z;
|
||||
}
|
||||
|
||||
if (traveller.GetTraveller().GetPositionX() != x || traveller.GetTraveller().GetPositionY() != y || traveller.GetTraveller().GetPositionZ() != z)
|
||||
{
|
||||
float ori = traveller.GetTraveller().GetAngle(x, y);
|
||||
traveller.Relocation(x, y, z, ori);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename TRAVELLER>
|
||||
void
|
||||
DestinationHolder<TRAVELLER>::GetLocationNow(const Map * map, float &x, float &y, float &z, bool is3D) const
|
||||
{
|
||||
if (HasArrived())
|
||||
{
|
||||
x = i_destX;
|
||||
y = i_destY;
|
||||
z = i_destZ;
|
||||
}
|
||||
else if (HasDestination())
|
||||
{
|
||||
double percent_passed = (double)i_timeElapsed / (double)i_totalTravelTime;
|
||||
const float distanceX = ((i_destX - i_fromX) * percent_passed);
|
||||
const float distanceY = ((i_destY - i_fromY) * percent_passed);
|
||||
const float distanceZ = ((i_destZ - i_fromZ) * percent_passed);
|
||||
x = i_fromX + distanceX;
|
||||
y = i_fromY + distanceY;
|
||||
float z2 = i_fromZ + distanceZ;
|
||||
// All that is not finished but previous code neither... Traveller need be able to swim.
|
||||
if (is3D)
|
||||
z = z2;
|
||||
else
|
||||
{
|
||||
//That part is good for mob Walking on the floor. But the floor is not always what we thought.
|
||||
z = map->GetHeight(x,y,i_fromZ,false); // Disable cave check
|
||||
const float groundDist = sqrt(distanceX*distanceX + distanceY*distanceY);
|
||||
const float zDist = fabs(i_fromZ - z) + 0.000001f;
|
||||
const float slope = groundDist / zDist;
|
||||
if (slope < 1.0f) // This prevents the ground returned by GetHeight to be used when in cave
|
||||
z = z2; // a climb or jump of more than 45 is denied
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TRAVELLER>
|
||||
float
|
||||
DestinationHolder<TRAVELLER>::GetDistance3dFromDestSq(const WorldObject &obj) const
|
||||
{
|
||||
float x,y,z;
|
||||
obj.GetPosition(x,y,z);
|
||||
return (i_destX-x)*(i_destX-x)+(i_destY-y)*(i_destY-y)+(i_destZ-z)*(i_destZ-z);
|
||||
}
|
||||
|
||||
template<typename TRAVELLER>
|
||||
float
|
||||
DestinationHolder<TRAVELLER>::GetDestinationDiff(float x, float y, float z) const
|
||||
{
|
||||
return sqrt(((x-i_destX)*(x-i_destX)) + ((y-i_destY)*(y-i_destY)) + ((z-i_destZ)*(z-i_destZ)));
|
||||
}
|
||||
|
||||
template<typename TRAVELLER>
|
||||
void
|
||||
DestinationHolder<TRAVELLER>::GetLocationNowNoMicroMovement(float &x, float &y, float &z) const
|
||||
{
|
||||
if (HasArrived())
|
||||
{
|
||||
x = i_destX;
|
||||
y = i_destY;
|
||||
z = i_destZ;
|
||||
}
|
||||
else
|
||||
{
|
||||
double percent_passed = (double)i_timeElapsed / (double)i_totalTravelTime;
|
||||
x = i_fromX + ((i_destX - i_fromX) * percent_passed);
|
||||
y = i_fromY + ((i_destY - i_fromY) * percent_passed);
|
||||
z = i_fromZ + ((i_destZ - i_fromZ) * percent_passed);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Common.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "Log.h"
|
||||
#include "Opcodes.h"
|
||||
#include "UpdateData.h"
|
||||
#include "Player.h"
|
||||
|
||||
void WorldSession::HandleDuelAcceptedOpcode(WorldPacket& recvPacket)
|
||||
{
|
||||
uint64 guid;
|
||||
Player *pl;
|
||||
Player *plTarget;
|
||||
|
||||
if (!GetPlayer()->duel) // ignore accept from duel-sender
|
||||
return;
|
||||
|
||||
recvPacket >> guid;
|
||||
|
||||
pl = GetPlayer();
|
||||
plTarget = pl->duel->opponent;
|
||||
|
||||
if (pl == pl->duel->initiator || !plTarget || pl == plTarget || pl->duel->startTime != 0 || plTarget->duel->startTime != 0)
|
||||
return;
|
||||
|
||||
//sLog.outDebug("WORLD: received CMSG_DUEL_ACCEPTED");
|
||||
DEBUG_LOG("Player 1 is: %u (%s)", pl->GetGUIDLow(),pl->GetName());
|
||||
DEBUG_LOG("Player 2 is: %u (%s)", plTarget->GetGUIDLow(),plTarget->GetName());
|
||||
|
||||
time_t now = time(NULL);
|
||||
pl->duel->startTimer = now;
|
||||
plTarget->duel->startTimer = now;
|
||||
|
||||
pl->SendDuelCountdown(3000);
|
||||
plTarget->SendDuelCountdown(3000);
|
||||
}
|
||||
|
||||
void WorldSession::HandleDuelCancelledOpcode(WorldPacket& recvPacket)
|
||||
{
|
||||
//sLog.outDebug("WORLD: received CMSG_DUEL_CANCELLED");
|
||||
|
||||
// no duel requested
|
||||
if (!GetPlayer()->duel)
|
||||
return;
|
||||
|
||||
// player surrendered in a duel using /forfeit
|
||||
if (GetPlayer()->duel->startTime != 0)
|
||||
{
|
||||
GetPlayer()->CombatStopWithPets(true);
|
||||
if (GetPlayer()->duel->opponent)
|
||||
GetPlayer()->duel->opponent->CombatStopWithPets(true);
|
||||
|
||||
GetPlayer()->CastSpell(GetPlayer(), 7267, true); // beg
|
||||
GetPlayer()->DuelComplete(DUEL_WON);
|
||||
return;
|
||||
}
|
||||
|
||||
// player either discarded the duel using the "discard button"
|
||||
// or used "/forfeit" before countdown reached 0
|
||||
uint64 guid;
|
||||
recvPacket >> guid;
|
||||
|
||||
GetPlayer()->DuelComplete(DUEL_INTERUPTED);
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Common.h"
|
||||
#include "UpdateMask.h"
|
||||
#include "Opcodes.h"
|
||||
#include "World.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "CellImpl.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
|
||||
DynamicObject::DynamicObject() : WorldObject()
|
||||
{
|
||||
m_objectType |= TYPEMASK_DYNAMICOBJECT;
|
||||
m_objectTypeId = TYPEID_DYNAMICOBJECT;
|
||||
|
||||
m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_POSITION);
|
||||
|
||||
m_valuesCount = DYNAMICOBJECT_END;
|
||||
|
||||
m_aura = 0;
|
||||
m_duration = 0;
|
||||
}
|
||||
|
||||
void DynamicObject::AddToWorld()
|
||||
{
|
||||
///- Register the dynamicObject for guid lookup
|
||||
if (!IsInWorld())
|
||||
{
|
||||
ObjectAccessor::Instance().AddObject(this);
|
||||
WorldObject::AddToWorld();
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicObject::RemoveFromWorld()
|
||||
{
|
||||
///- Remove the dynamicObject from the accessor
|
||||
if (IsInWorld())
|
||||
{
|
||||
if (m_isWorldObject)
|
||||
{
|
||||
if (Unit *caster = GetCaster())
|
||||
{
|
||||
if (caster->GetTypeId() == TYPEID_PLAYER)
|
||||
caster->ToPlayer()->SetViewpoint(this, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
sLog.outCrash("DynamicObject::RemoveFromWorld cannot find viewpoint owner");
|
||||
}
|
||||
}
|
||||
WorldObject::RemoveFromWorld();
|
||||
ObjectAccessor::Instance().RemoveObject(this);
|
||||
}
|
||||
}
|
||||
|
||||
bool DynamicObject::Create(uint32 guidlow, Unit *caster, uint32 spellId, const Position &pos, float radius, bool active)
|
||||
{
|
||||
SetMap(caster->GetMap());
|
||||
Relocate(pos);
|
||||
if (!IsPositionValid())
|
||||
{
|
||||
sLog.outError("DynamicObject (spell %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)",spellId,GetPositionX(),GetPositionY());
|
||||
return false;
|
||||
}
|
||||
|
||||
WorldObject::_Create(guidlow, HIGHGUID_DYNAMICOBJECT, caster->GetPhaseMask());
|
||||
|
||||
SetEntry(spellId);
|
||||
SetFloatValue(OBJECT_FIELD_SCALE_X, 1);
|
||||
SetUInt64Value(DYNAMICOBJECT_CASTER, caster->GetGUID());
|
||||
|
||||
// The lower word of DYNAMICOBJECT_BYTES must be 0x0001. This value means that the visual radius will be overriden
|
||||
// by client for most of the "ground patch" visual effect spells and a few "skyfall" ones like Hurricane.
|
||||
// If any other value is used, the client will _always_ use the radius provided in DYNAMICOBJECT_RADIUS, but
|
||||
// precompensation is necessary (eg radius *= 2) for many spells. Anyway, blizz sends 0x0001 for all the spells
|
||||
// I saw sniffed...
|
||||
SetUInt32Value(DYNAMICOBJECT_BYTES, 0x00000001);
|
||||
SetUInt32Value(DYNAMICOBJECT_SPELLID, spellId);
|
||||
SetFloatValue(DYNAMICOBJECT_RADIUS, radius);
|
||||
SetUInt32Value(DYNAMICOBJECT_CASTTIME, getMSTime());
|
||||
|
||||
m_isWorldObject = active;
|
||||
return true;
|
||||
}
|
||||
|
||||
Unit* DynamicObject::GetCaster() const
|
||||
{
|
||||
// can be not found in some cases
|
||||
return ObjectAccessor::GetUnit(*this, GetCasterGUID());
|
||||
}
|
||||
|
||||
void DynamicObject::Update(uint32 p_time)
|
||||
{
|
||||
// caster can be not in world at time dynamic object update, but dynamic object not yet deleted in Unit destructor
|
||||
Unit* caster = GetCaster();
|
||||
if (!caster)
|
||||
{
|
||||
Delete();
|
||||
return;
|
||||
}
|
||||
|
||||
bool expired = false;
|
||||
|
||||
if (m_aura)
|
||||
{
|
||||
if (!m_aura->IsRemoved())
|
||||
m_aura->UpdateOwner(p_time, this);
|
||||
|
||||
// m_aura may be set to null in Unit::RemoveGameObject call
|
||||
if (m_aura && (m_aura->IsRemoved() || m_aura->IsExpired()))
|
||||
expired = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GetDuration() > int32(p_time))
|
||||
m_duration -= p_time;
|
||||
else
|
||||
expired = true;
|
||||
}
|
||||
|
||||
if (expired)
|
||||
{
|
||||
caster->RemoveDynObjectWithGUID(GetGUID());
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicObject::Delete()
|
||||
{
|
||||
if (m_aura)
|
||||
{
|
||||
// dynObj may be removed in Aura::Remove - we cannot delete there
|
||||
// so recheck aura here
|
||||
if (!m_aura->IsRemoved())
|
||||
m_aura->_Remove(AURA_REMOVE_BY_DEFAULT);
|
||||
delete m_aura;
|
||||
m_aura = NULL;
|
||||
}
|
||||
SendObjectDeSpawnAnim(GetGUID());
|
||||
RemoveFromWorld();
|
||||
AddObjectToRemoveList();
|
||||
}
|
||||
|
||||
int32 DynamicObject::GetDuration() const
|
||||
{
|
||||
if (!m_aura)
|
||||
return m_duration;
|
||||
else
|
||||
return m_aura->GetDuration();
|
||||
}
|
||||
|
||||
void DynamicObject::SetDuration(int32 newDuration)
|
||||
{
|
||||
if (!m_aura)
|
||||
m_duration = newDuration;
|
||||
else
|
||||
m_aura->SetDuration(newDuration);
|
||||
}
|
||||
|
||||
void DynamicObject::Delay(int32 delaytime)
|
||||
{
|
||||
SetDuration(GetDuration() - delaytime);
|
||||
}
|
||||
|
||||
bool DynamicObject::isVisibleForInState(Player const* u, bool inVisibleList) const
|
||||
{
|
||||
return IsInWorld() && u->IsInWorld()
|
||||
&& (IsWithinDistInMap(u->m_seer,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false));
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user